卡桑德拉一致性问题?

时间:2014-08-19 23:40:59

标签: cassandra datastax-enterprise consistency

我们在三个不同的数据中心(DC1,DC2和DC3)中有cassandra集群,每个数据中心有10台机器。我们在cassandra中有几张表,其中我们的记录少于100条。

我们所看到的 - 当我们选择计数(*)时,DC3中的某些表与DC1或DC2之间的表不同步。

作为一个例子,我们在dc3数据中心连接到一台cassandra机器时选择了count(*),而在dc1数据中心中只有一台cassandra机器,结果不同。

root@machineA:/home/david/apache-cassandra/bin# python cqlsh dc3114.dc3.host.com
Connected to TestCluster at dc3114.dc3.host.com:9160.
[cqlsh 2.3.0 | Cassandra 1.2.9 | CQL spec 3.0.0 | Thrift protocol 19.36.0]
Use HELP for help.
cqlsh> use testingkeyspace ;
cqlsh:testingkeyspace> select count(*) from test_metadata ;

count
-------
    12

cqlsh:testingkeyspace> exit
root@machineA:/home/david/apache-cassandra/bin# python cqlsh dc18b0c.dc1.host.com
Connected to TestCluster at dc18b0c.dc1.host.com:9160.
[cqlsh 2.3.0 | Cassandra 1.2.9 | CQL spec 3.0.0 | Thrift protocol 19.36.0]
Use HELP for help.
cqlsh> use testingkeyspace ;
cqlsh:testingkeyspace> select count(*) from test_metadata ;

count
-------
    16

这个同步问题可能是什么原因?它是否会发生?任何人都可以对此有所了解吗?

由于我们的java驱动程序代码和datastax c ++驱动程序代码正在使用这些表与CONSISTENCY LEVEL ONE。

2 个答案:

答案 0 :(得分:0)

你的复制策略是什么?对于跨数据中心,您应该查看NetowrokTopologyStrategy,其中包含为每个数据中心指定的复制因子。然后在您的查询期间,您可以指定仲裁/本地仲裁等。但是,请考虑一下这一点:

  • 您有一个包含多个数据中心的分布式群集。如果你想要一个each_quorum,想想你要求cassandra做什么 - 对于读取或写入,你要求它在返回成功之前分别持续存储到两个数据中心。考虑延迟和网络连接下降。对于读取,客户端请求的节点成为协调器。它将写入发送到数据中心本地副本,并发送到远程数据中心的一个节点。那里的收件人与当地的法定人数进行协调。完成后,它返回结果,当初始协调器收到足够的响应时,它返回。一切都很好。慢,但很好。现在对于写入,会发生类似的事情,但如果协调器不知道节点已关闭,它仍会发送到节点。当节点重新启动时写入完成,但客户端可以获得写入超时(注意,不是失败 - 写入最终会成功)。多个数据中心之间可能会发生这种情况。

  • 您希望进行计数(*)查询。这通常是一个糟糕的主意。它需要命中表的每个分区。 Cassandra喜欢点击单个分区或至少少量分区的查询(通过IN过滤器)。

  • 考虑select count(*)在分布式系统中的作用。结果甚至意味着什么?结果可能会在一瞬间过时。在处理查询结果时,某些其他数据中心可能还有其他插入。

如果您希望对批量或所有分区进行聚合,请考虑将cassandra与spark配对,而不是尝试跨数据中心进行select(*)。回到前面的观点,不要假设(或依赖)交叉数据中心的即时一致性。拥抱最终的一致性,并围绕它设计您的应用程序。

希望有所帮助。

答案 1 :(得分:0)

相关点,您可以使用cqlsh中的不同一致性级别进行查询。跑吧:

一致性EACH_QUORUM;

一致性;

只要您的cqlsh会话或直到您将其替换为另一个CONSISTENCY语句,该设置将保持不变。

无论您的协调节点如何,EACH_QUORUM或ALL都应该保证您的响应相同。虽然表现会受到打击。一般来说,请查看数字(*)上的数字点。如果这是一个常见的查询,则另一个选项是将计数保存在单独的表中。