【问题标题】:Query pagination using minTimeuuid and maxTimeuuid使用 minTimeuuid 和 maxTimeuuid 查询分页
【发布时间】:2015-08-14 16:46:30
【问题描述】:

我有一个带有 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 所在的所有行 列 t 严格晚于 2013-01-01 00:05+0000 但严格 早于 2013-02-02 10:00+0000。 t >= maxTimeuuid('2013-01-01 00:05+0000') 不选择恰好在 2013-01-01 00:05+0000 基本上相当于 t > maxTimeuuid('2013-01-01 00:05+0000').

因此,据我了解,如果我要为下一个块选择从 '2013-02-02 10:00+0000' 开始的范围,我会错过当时的数据,因为它们都没有涵盖确切的日期。

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

感谢您的帮助!

【问题讨论】:

  • 你能发布你的表定义吗?此外,您不能对分区键进行范围查询,因此您需要有一个分区键,然后是一个集群键来查询您的范围。

标签: cassandra cassandra-2.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)
);

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 选择说明:

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

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

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

其中 x

但是 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/

【讨论】:

  • 我明白你的意思,这样拆分工作是个好主意。我不清楚的唯一部分是范围查询如何工作,因为边界不包含在内。据我了解,如果窗口上限是 "2013-02-02 10:00+0000" 并且下一个下限是相同的( "2013-02-02 10:00+0000" )会有一个理论上行可能滑入的小裂缝。
  • @CodeHerder 我已经更新了我的答案。但是这是理论,所以请测试一下,如果它有效,请告诉我。
猜你喜欢
  • 2013-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
相关资源
最近更新 更多