4

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

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

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

并且同样从一个普通的Column Family,我将一列的值从status='FALSE'更新为status='TRUE',下次查询时,status还是'FALSE'。

更多详情:

  1. 并非每次都发生(1/10,000)
  2. 两个查询之间的时间大约是 500 毫秒(但我们发现一对查询之间已经过去了 2 秒,仍然表明存在一致性问题)
  3. 我们使用 ntp 作为我们的集群时间同步解决方案。
  4. 我们有 6 个节点,复制因子为 3

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

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

4

4 回答 4

3

用系统日志查看源代码后,找到了不一致的根本原因。导致问题的三个因素:

  • 从不同节点创建和更新相同的记录
  • 本地系统时间同步不够准确(虽然我们使用 NTP)
  • 一致性级别是QUORUM

这就是问题所在,以following为事件序列

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

首先创建请求来自节点 C,本地时间戳为00:00:00.050,假设请求首先记录在节点 A节点 B中,然后再与节点 C同步。

然后删除请求来自节点 A,本地时间戳为00:00:00.030,并记录在节点 A节点 B中。

读取请求来时,Cassandra 会进行版本冲突合并,但合并只依赖于时间戳,所以虽然Delete发生在Create之后,但由于本地时间同步问题,合并最终结果是“ New ”,它具有最新的时间戳。

于 2013-03-06T06:54:01.423 回答
1

我也面临类似的问题。出现此问题是因为 cassandra 驱动程序默认使用服务器时间戳来检查哪个查询是最新的。然而,在最新版本的 cassandra 驱动程序中,他们对其进行了更改,现在默认情况下他们使用客户端时间戳。

我在这里描述了问题的细节

于 2015-12-03T16:05:03.097 回答
0

由于分布式删除的工作方式,已删除的行可能显示为“范围幽灵”:请参阅http://wiki.apache.org/cassandra/FAQ#range_ghosts

如果您在 CL_QUORUM 读取写入单个列,那么无论时间间隔如何,您都应该始终获得完全一致性(假设仍然遵守严格的顺序,即您确定读取始终在写入之后)。如果您没有看到这一点,那么某处某处是错误的。

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

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

于 2012-06-25T21:35:00.437 回答
-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 节点可能没有按预期响应,因为它无法正确访问磁盘上的数据。

我不太确定这是否与发布问题的用户有关,但 tail -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 进行了测试(如下所述,我第一次使用了 3,000 的限制但没有成功!)在运行我的 Cassandra 测试时会在大约同一时间弹出相同的错误(甚至在 ulimit 为 3,000 的情况下,仍会出现 tail -F 错误...)

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

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

于 2013-01-26T11:49:46.387 回答