获取切片返回不一致的结果

时间:2013-01-09 15:52:41

标签: cassandra thrift slice

我正在使用宽列索引以时间轴方式命令记录,la:

"TimelineIndex" //CF name
  [CFName] //row key
    [TimeUUID]:[CFRowKey] //column name/value
    [TimeUUID]:[CFRowKey] //column name/value
    [TimeUUID]:[CFRowKey] //column name/value
    [TimeUUID]:[CFRowKey] //column name/value

假设我在TimelineIndex CF中有10条记录,每天有一列,范围从'01 / 01/2013 12:00:00'到'10 / 01/2013 12:00:00'(作为TimeUUIDs),然后运行以下get_slice()命令:

var predicate = new SlicePredicate(){ Slice_range = new SliceRange() {
{
  Start = TimeGenerator.GetTimeUUID(new DateTime("06/01/2013 12:00:00"),
  Finish = TimeGenerator.GetTimeUUID(new DateTime("11/01/2013 12:00:00"),
  Count = 5,
  Reversed = false
}};
var results = client.get_slice([CFName], parent, predicate, consitencylevel.one);

此查询返回的列并不总是一致的。大多数时候返回名为'06 / 01/2013 12:00:00'的列,但是每隔一段时间(大约有10次执行中的1)该列被排除在结果之外,我最终只返回了4列

我不能为我的生活弄清楚为什么我会在这里得到不一致的结果。有人可以说明这个原因吗?

在有人说之前,我知道不建议直接使用Thrift - 这纯粹是一个概念证明练习!

2 个答案:

答案 0 :(得分:4)

冒着明显的危险,请记住TimeUUID(版本1 UUID)有两个目的:

  • 他们有一个基于时间的组件
  • 他们是UUID

因此,您可以插入多个基于时间的数据值并按时间顺序返回,而不必担心因列名冲突而丢失数据。

还要记住,列名必须全局排序才能使Cassandra正确找到您的数据,UUID也不例外。因此,如果您为Cassandra提供两个具有相同时间组件的TimeUUID,它将根据非时间组件对它们进行排序。

所以,正在发生的是上述两点之间的微妙交互:当你在06/01/2013 12:00:00创建新的随机时间TimeUUID时,有时会在你插入的那个之前进行排序,有时则不会。如果没有,则不包括第一列。

要解决此问题,您需要有意为查询UUID构建非时间组件,以便尽可能低地排序。例如,pycassa库就是这样做的。

答案 1 :(得分:0)

您的问题似乎与您的一致性水平有关。您有2个副本,但您正在阅读一致性级别为ONE。如果您也使用ONE编写,则会遇到您描述的问题。如果您将读取级别更改为QUORUM(或LOCAL_QUORUM),我的猜测是您的数据永远不会消失。偶尔消失的数据几乎总是一致性问题。

为什么会这样?

使用RF = 2的3个节点的设置,假设你用CL = ONE写了A列。现在你有一个节点(比方说N1)和A列,另一个理论上得到副本的节点(比方说N2)还没有它。所以你最终会得到这个:

N1: has A
N2: does not have A
N3: will look to N1 or N2 for A

现在,让我们看看如果使用CL = ONE,您会向每个节点询问A:

N1: you get A
N2: you get nothing because it doesn't check with any other nodes
N3: you may get A or nothing, depending on whether the request gets handled by N1 or N2

如果您阅读CL = QUORUM:

N1: you get A, and N2 gets updated due to repair on read
N2: you get A, because it checks against N1 and repairs
N3: you get A, because both N1 and N2 will reliably return it

您可以使用QUORUM读取轻松检查这是否是您的问题。如果是这样,问题就不会再出现了。