使用 minTimeuuid 和 maxTimeuuid 查询分页
Query pagination using minTimeuuid and maxTimeuuid
我有一个带有 Timeuuid 主键的 cassandra table,我想在各种处理节点上分块处理整个 table。
所以,我想我可以使用 minTimeuuid/maxTimeuuid:
分块处理
- 为了开始他们的工作,每个节点都会得到一个他们应该从 Cassandra 获取的时间范围,查询并处理它。
- 数据密度比较均匀,应该没有问题。
如果我要这样做,让我感到震惊的是:
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)
);
其中 timebucket 是 pk_uuid 模 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 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/
我有一个带有 Timeuuid 主键的 cassandra table,我想在各种处理节点上分块处理整个 table。
所以,我想我可以使用 minTimeuuid/maxTimeuuid:
分块处理- 为了开始他们的工作,每个节点都会得到一个他们应该从 Cassandra 获取的时间范围,查询并处理它。
- 数据密度比较均匀,应该没有问题。
如果我要这样做,让我感到震惊的是:
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)
);
其中 timebucket 是 pk_uuid 模 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 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/