使用minTimeuuid和maxTimeuuid查询分页

时间:2015-08-12 17:39:40

标签: cassandra cassandra-2.0

我有一个带有Timeuuid主键的cassandra表,我想在各种处理节点上以块的形式处理整个表。

所以,我认为我可以使用minTimeuuid / maxTimeuuid进行处理:

  • 要开始他们的工作,每个节点都会获得他们应该从Cassandra获得的时间范围,查询并处理它。
  • 数据密度相当一致,因此不存在任何问题。

如果我这样做,那么让我感到震惊的是:

   SELECT * FROM myTable
   WHERE t > maxTimeuuid('2013-01-01 00:05+0000')
   AND t < minTimeuuid('2013-02-02 10:00+0000')

文档说:

  

min / maxTimeuuid示例选择timeuuid所在的所有行   column,t,严格要晚于2013-01-01 00:05 + 0000   早于2013-02-02 10:00 + 0000。 t&gt; = maxTimeuuid(&#39; 2013-01-01   00:05 + 0000&#39;)没有选择精确生成的时间线   2013-01-01 00:05 + 0000并且基本等同于t>   maxTimeuuid(&#39; 2013-01-01 00:05 + 0000&#39;)。

根据我的理解,如果我选择从2013-02-02 10:00 + 0000&#39;对于下一个块,我会错过当时的数据,因为它们都没有涵盖那个确切的日期。

好的,我明白,由于生成Timeuuid的方式不太可能,但我仍然对丢弃某些结果的可能性感到不安。之后可以检查重复项,但这对集群来说是一项相当昂贵的操作。



修改

好的,显然我不能在Timeuuid上进行范围查询。如我所知,这是我的表:

CREATE TABLE cgr.reports (
    pk_1 text,
    pk_2 text,
    pk_3 bigint,
    pk_4 bigint,
    some_data text,
    PRIMARY KEY ((pk_1, pk_2, pk_3, pk_4))
);

PK并不需要成为这4个人的聚合因素,因为我在某个时候意识到没有计划对这些人进行查询。那时我以为我可以在Timeuuid上进行范围查询,所以我想我可以这样做:

CREATE TABLE cgr.reports (
    pk_uuid Timeuuid,
    data_1 text,
    data_2 text,
    data_3 bigint,
    data_4 bigint,
    some_data text,
    PRIMARY KEY ((pk_uuid))
);

我真正想做的是在各个节点之间拆分处理。我想要做的一种方法是查询所有行id并将它们的块发送到各个节点。我知道我会用现有的音量开始工作,我只是担心它会在以后增长。

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

你可以这样做:

CREATE TABLE cgr.reports (
    timebucket int,
    pk_uuid Timeuuid,
    data_1 text,
    data_2 text,
    data_3 bigint,
    data_4 bigint,
    some_data text,
    PRIMARY KEY (timebucket, pk_uuid)
);

timebucket pk_uuid modulo some_number some_number 应该足够高,可以将数据平均分配到您的节点,并且足够低,可以为您的工作人员聚合一些数据量,而不是经常查询许多小块。每个工作人员都会分配提醒部门并仅处理这些值。

然而,完美的方式是这样的:

CREATE TABLE cgr.reports (
    pk_uuid Timeuuid,
    data_1 text,
    data_2 text,
    data_3 bigint,
    data_4 bigint,
    some_data text,
    PRIMARY KEY (data_1, pk_uuid)
);

data_1具有高基数并且为您的员工所知。这会将数据平均分配到您的群集,并且pk_uuid上允许时间范围查询。每个工作人员都分配了data_1值并仅处理这些值。

修改 Timeuuid选择解释:

我没有测试过,但我的理解如下:

Timeuuid基本上是Time + UUID。因此,如果你只能询问Cassandra:

t > minTimeuuid(x) AND t < maxTimeuuid(y)

其中x < y,您将选择范围内的时间(x_000,y_999) - _abc是clockid + nodeid。

但是在y_999之后呢?它是(y + 1 tick)_000 - 它是minTimeuuid(y + 1)。因此执行查询:

t > minTimeuuid(x) AND t < minTimeuuid(y+1)

您将选择范围内的时间(x_000,y + 1_000)。您不会选择y + 1_000或y + 1_389,但您将选择y_999。

下一个查询,与此相邻将是:

t > maxTimeuuid(y) AND t < minTimeuuid(z+1)

这里的时间范围是(y_999,z + 1_000)。因此,您不会选择y_999。

然而,请注意,这只是我的理解,如果有效,请在测试后告诉我。更重要的是,根据您的驱动程序,这可能会有所不同,因为显示了C#驱动程序实现:http://nickberardi.com/sometimes-a-nanosecond-makes-all-the-difference/