使用 minTimeuuid 和 maxTimeuuid 查询分页

Query pagination using minTimeuuid and maxTimeuuid

我有一个带有 Timeuuid 主键的 cassandra table,我想在各种处理节点上分块处理整个 table。

所以,我想我可以使用 minTimeuuid/maxTimeuuid:

分块处理

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

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

文档说:

The min/maxTimeuuid example selects all rows where the timeuuid column, t, is strictly later than 2013-01-01 00:05+0000 but strictly earlier than 2013-02-02 10:00+0000. The t >= maxTimeuuid('2013-01-01 00:05+0000') does not select a timeuuid generated exactly at 2013-01-01 00:05+0000 and is essentially equivalent to t > maxTimeuuid('2013-01-01 00:05+0000').

所以据我所知,如果我要 select 从 '2013-02-02 10:00+0000' 开始的范围作为下一个块,我会错过恰好位于那个时间因为 none 涵盖了那个确切的日期。

好的,我知道由于 Timeuuid 的生成方式,这不太可能,但我仍然对 table 可能会丢失一些结果感到不安。之后可能会检查重复项,但这在集群上是一项相当昂贵的操作。



编辑:

好的,显然我不能对 Timeuuid 进行范围查询。正如所问,这是我的 table:

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 并将它们的块发送到各个节点。我知道这将适用于我目前的数量,我只是担心以后它会增长。

感谢您的帮助!

你可以这样做:

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)
);

其中 timebucketpk_uuidsome_numbersome_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 selects 解释:

我没有测试过,不过我的理解是这样的:

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

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

where x < y, you will select time in range (x_000, y_999) - _abc 是 clockid + nodeid.

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

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

您将 select 时间范围 (x_000, y+1_000)。你不会 select y+1_000 或 y+1_389,但你会 select y_999.

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

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

这里的时间范围是(y_999, z+1_000)。因此你不会 select y_999.

但是,请注意,这只是我的理解,如果可行,请在您测试后告诉我。此外,根据您的驱动程序,这可能会有所不同,如 C# 驱动程序实现所示:http://nickberardi.com/sometimes-a-nanosecond-makes-all-the-difference/