读取失败,一致性

时间:2018-01-17 06:21:49

标签: cassandra cassandra-3.0

我有3个节点;数据中心1(节点1和节点2)中的数据2和数据中心2中的1(节点3)。复制策略:网络拓扑,dc1:2,dc2:1。

最初,我将dc1中的一个节点关闭(节点2),并使用一致性2(通过c ++程序)写入100 000个条目。写完后,我关闭数据中心2(节点3)中的节点并打开节点2.

现在,如果我尝试读取我写过的10万个条目(再次通过c ++程序),一致性设置为1,我就无法读取所有这10万个条目,即我能够只读一些条目。当我一次又一次地运行程序时,我的程序会获取越来越多的条目。

我原以为由于2个节点中的一个节点包含所有10万个条目,因此,当设置的一致性为1时,读取程序应该获取第一次执行中的所有条目。

这与阅读修复有关吗?我认为因为读取修复发生在后台,这就是为什么节点无法响应所有查询?但我无处可寻找有关此行为的任何内容。

2 个答案:

答案 0 :(得分:1)

读取时

Per documentation,一致性级别 $add_item = new Report; $add_item->item= $request->input("item"); $add_item->user_id= Auth::user()->id; $add_item->postqs_id=$id; $add_item->save();

  

返回来自最近的副本的响应,由snitch确定。默认情况下,读取修复在后台运行以使其他副本保持一致。如果您能够容忍相对较高的过时数据读取概率,则提供所有级别的最高可用性。联系读取的副本可能并不总是最近的写入。

您是否检查过您的代码是否联系了始终在线的节点&接受写道?

DSE Architecture guide,尤其是Database Internals部分概述了Cassandra的工作原理。

答案 1 :(得分:1)

让我们来看看这个场景。

在写入100K行(DC1)期间,Node1和(DC2)Node3接受了所有写操作。正如发生的那样,Node1也可能默认3小时为Node2(DC1)提示,然后停止这样做。

一旦Node2重新上线,除非进行了修复 - 通过重播提示需要一些时间。如果节点停机超过3小时,则必须进行修复。

在读取期间,它可以根据驱动程序使用的loadbalancy策略在技术上到达群集中的任何节点。除非指定执行“DCAwareRoundRobinPolicy”,否则读取请求甚至可能到达任何DC(在这种情况下为DC1或DC2)。由于请求的一致性是“一”,实际上任何ALIVE节点都可以响应 - NODE1&在这种情况下,NODE2(DC1)。因此,NODE2甚至可能没有所有数据,它仍然可以使用NULL值进行响应,这就是为什么有时会收到空数据并在其他时间更正数据。

一致性“ONE”读取修复甚至不会发生,因为没有其他节点可以与之进行比较。这是documentation就可以了。即使在一致性“local_quorum”或“quorum”的情况下,在表级别设置 read_repair_chance ,默认为0.1。这意味着只有10%的读取会触发read_repair。这是为了通过不每次触发来节省性能。想一想,如果读取修复可以使表格在节点之间完全一致,那么为什么“nodetool repair”甚至存在呢?

为了避免这种情况,每当节点重新联机时,最佳做法是执行“nodetool修复”或运行一致性“local_quorum”的查询以获得一致的数据。

还要记住,一致性“ONE”与RDBMS(WITH UR)世界中未提交的读取(脏读)相当。期待看到意想不到的数据。