首页 文章

即使使用Quorum配置,Cassandra中的数据也不一致

提问于
浏览
4

当我们有Quorum进行读写时,我遇到了使用Hector和Cassandra的一致性问题 .

我使用MultigetSubSliceQuery从超级列限制大小100查询行,然后读取它,然后删除它 . 并开始另一个 .

我发现我之前的查询应该删除的行仍然显示在下一个查询中 .

而且从普通的列族中,我将一列的值从status ='FALSE'更新为status ='TRUE',下次我查询它时,状态仍为'FALSE' .

更多详情:

  • 并非每次都发生过(1 / 10,000)

  • 两次查询之间的时间约为500毫秒(但是我们发现一对查询,其间已经过了2秒,仍然表明存在一致性问题)

  • 我们使用ntp作为我们的集群时间同步解决方案 .

  • 我们有6个节点,复制因子是3

我知道Cassandra应该是“最终一致的”,并且在写入Cassandra之前可能不会发生这种情况 . 但是两秒钟?!如果是这样,那么拥有Quorum或其他一致性级别配置是否毫无意义?

首先,它是Cassandra的正确行为,如果不是,我们需要分析哪些数据才能进一步投资?

4 回答

  • -1

    在使用系统日志检查源代码后,我发现了不一致的根本原因 . 导致问题的因素有三个:

    • different nodes 创建并更新相同的记录

    • 本地系统 time is not synchronized 足够准确(虽然我们使用NTP)

    • 一致性等级为 QUORUM

    这是问题,请将以下内容作为事件序列

    seqID   NodeA         NodeB          NodeC
     1.      New(.050)     New(.050)      New(.050)
     2.      Delete(.030)  Delete(.030)
    

    第一个 Create 请求来自 Node C ,带有本地时间戳 00:00:00.050 ,假设请求首先记录在 Node ANode B ,然后再与 Node C 同步 .

    然后 Delete 请求来自 Node A ,带有本地时间戳 00:00:00.030 ,并记录在 node ANode B 中 .

    read 请求到来时,Cassandra会做版本冲突合并,但合并 only depend on time stamp ,所以虽然 Delete 发生在 Create 之后,但合并的最终结果是“ New ”,其中由于本地时间同步问题而具有最新时间戳 .

  • 1

    我也遇到过类似的问题 . 发生此问题是因为cassandra驱动程序默认使用服务器时间戳来检查哪个查询是最新的 . 但是在最新版本的cassandra驱动程序中,它们已对其进行了更改,现在默认情况下它们使用的是客户端时间戳 .

    我已经描述了问题的细节here

  • 3

    由于分布式删除的工作方式,已删除的行可能会显示为"range ghosts":请参阅http://wiki.apache.org/cassandra/FAQ#range_ghosts

    如果您正在CL_QUORUM上读取和写入各个列,那么无论时间间隔如何,您都应始终获得完全一致性(如果仍然遵守严格排序,即您确定读取始终在写入之后) . 如果你没有看到这个,那么在某个地方,某些东西是错误的 .

    首先,我建议a)验证客户端是否正确地与NTP同步,和/或以某种方式在客户端之间交叉检查时重现问题,以及b)尝试用CL_ALL重现问题 .

    另一个想法 - 您的客户端是与NTP同步还是只与Cassandra服务器节点同步?请记住,Cassandra使用客户端时间戳来确定哪个值是最新的 .

  • 0

    我正在使用我的一个客户端/节点遇到此问题 . 我正在测试的其他2个客户端(以及其他2个节点)运行顺畅 . 我有一个测试,在所有读取和所有写入中使用QUORUM,它很快就会失败 . 实际上有些进程看不到其他进程,而其他进程可能总是看到数据,即使我在QUORUM中删除它 .

    在我的情况下,我打开日志并打算使用tail -F命令测试该专长:

    tail -F /var/lib/cassandra/log/system.log
    

    看看我是否收到了一些错误 . 令我惊讶的是尾部进程本身返回了一个错误:

    tail: inotify cannot be used, reverting to polling: Too many open files
    

    从另一个线程,这意味着某些进程将无法打开文件 . 换句话说,Cassandra节点可能没有按预期响应,因为它无法正确访问磁盘上的数据 .

    我不太确定这是否与发布问题的用户的问题有关,但是尾部-F肯定是确定是否达到文件限制的好方法 .

    (仅供参考,我有5台相对较重的服务器在同一台机器上运行,所以我不是事实太令人惊讶了 . 我将不得不考虑增加ulimit . 如果我以这种方式修复它,我会再次在此报告 . )

    有关文件限制和ulimit命令行选项的更多信息:https://askubuntu.com/questions/181215/too-many-open-files-how-to-find-the-culprit

    ---------更新1

    为了以防万一,我首先使用Oracle的Java 1.7.0-11进行测试(如下所述,我首先使用了3000的限制而没有成功!)运行我的Cassandra测试时,同样的错误会弹出同样的错误(甚至在ulimit为3,000的情况下,尾部会出现-F错误......)

    ---------更新2

    好的!那很有效 . 我将ulimit更改为32,768,问题就消失了 . 请注意,我必须在 /etc/security/limits.conf 中放大每用户限制并运行 sudo sysctl -p 才能将最大值提高到如此高的数字 . 不知何故,默认的上限3000是不够的,即使旧的限制只有1024 .

相关问题