首页 文章

Cassandra 一致性问题?

提问于
浏览
0

我们在三个不同的数据中心(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

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

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

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

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

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

    希望有所帮助 .

  • 0

    相关点,您可以从cqlsh查询不同的一致性级别 . 赶紧跑:

    一致性EACH_QUORUM;

    要么

    一致性;

    等等

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

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

相关问题