当我们使用Quorum进行读写操作时,我遇到了使用Hector和Cassandra的一致性问题。
我使用MultigetSubSliceQuery从超级列限制大小100中查询行,然后读取它,然后删除它。并开始另一个。
我发现我之前查询应该删除的行仍会显示在下一个查询中。
同样来自普通的Column Family,我将一行的值从status ='FALSE'更新为status ='TRUE',下次我查询它时,状态仍为'FALSE'。
更多细节:
据我所知,Cassandra应该是“最终一致的”,并且在写入Cassandra之前可能不会发生这种情况。但是两秒钟?!如果是这样,那么具有Quorum或其他一致性级别配置是不是没有意义呢?
首先,这是Cassandra的正确行为,如果没有,我们需要分析哪些数据才能进一步投资?
答案 0 :(得分:3)
使用系统日志检查源代码后,我发现了不一致的根本原因。 有三个因素导致了这个问题:
这是问题,请将以下内容作为事件序列
seqID NodeA NodeB NodeC
1. New(.050) New(.050) New(.050)
2. Delete(.030) Delete(.030)
首先创建请求来自节点C ,本地时间戳 00:00:00.050 ,假设请求首先记录在节点中和节点B ,然后与节点C 同步。
然后删除请求来自节点A ,本地时间戳 00:00:00.030 ,并记录在节点A < / strong>和节点B 。
当阅读请求到来时,Cassandra会进行版本冲突合并,但合并仅取决于时间戳,所以尽管删除之后发生了创建,但合并最终结果为“新”,由于本地时间同步问题而具有最新时间戳。
答案 1 :(得分:1)
我也面临类似的问题。发生此问题是因为cassandra驱动程序默认使用服务器时间戳来检查哪个查询是最新的。但是在最新版本的cassandra驱动程序中,它们已对其进行了更改,现在默认情况下它们使用的是客户端时间戳。
我已经描述了问题here
的详细信息答案 2 :(得分:0)
由于分布式删除的工作方式,已删除的行可能会显示为“范围重影”:请参阅http://wiki.apache.org/cassandra/FAQ#range_ghosts
如果您正在读取和在CL_QUORUM处写入各个列,那么无论时间间隔如何,您都应始终获得完全一致性(如果仍然遵守严格的排序,即您确定已读取总是写完之后)。如果你没有看到这个,那么在某个地方,某些东西是错误的。
首先,我建议a)验证客户端是否正确地同步到NTP,和/或以某种方式在客户端之间交叉检查时重现问题,以及b)尝试用CL_ALL重现问题。
另一个想法 - 您的客户端是与NTP同步还是只与Cassandra服务器节点同步?请记住,Cassandra使用 client 时间戳来确定哪个值是最新的。
答案 3 :(得分:-1)
我正在使用我的一个客户端/节点遇到此问题。我正在测试的其他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测试时,同样的错误会在同一时间弹出(加上即使是3000的ulimit,尾部-F错误仍会出现......)
---------更新2
好!那很有效。我将ulimit更改为32,768,问题就消失了。请注意,我必须在/etc/security/limits.conf
中放大每个用户限制并运行sudo sysctl -p
,然后才能将最大值提高到如此高的数字。不知何故,默认的上限3000是不够的,即使旧的限制仅 1024。