在基于时间的小块中查询 cassandra 的最有效方法

Most efficient way to query cassandra in small time-based chunks

我的基于 Cassandra 的应用程序需要读取自上次读取后更改的行。 为此,我们计划有一个包含两列的 table changed_rows -

  1. ID - 更改行的 ID 和
  2. Updated_Time - 更改时的时间戳。

读取这样一个 table 的最佳方法是什么,以便它读取按时间排序的一小组行。 示例:如果 table 是:

ID   Updated_Time
foo    1000
bar    1200
abc    2000
pqr    2500
zyx    2900
 ...
xyz   901000
 ...

我将 ID 显示为简单的 3 个字母键,实际上它们是 UUID。 此外,为简单起见,上面显示的时间显示为整数,但它是实际的 Cassandra 时间戳(或 Java 日期)。 Updated_Time列是单调递增的。

如果我查询此数据:

SELECT * FROM changed_rows WHERE Updated_Time < toTimestamp(now())

我收到以下错误:

Cannot execute this query as it might involve data filtering and 
thus may have unpredictable performance... Use Allow Filtering

但我认为 Allow Filtering 在这种情况下会破坏性能。 Cassandra 索引页面警告避免为高基数列创建索引,上面的 Updated_Time 肯定看起来像高基数。

我事先不知道 ID 列,因为查询的目的是了解给定时间间隔之间更新的 ID。

那么在这种情况下查询 Cassandra 的最佳方式是什么?
我能否以某种方式将我的 table 更有效地更改为 运行 时间块查询?

注意:这听起来应该与 Cassandra-CDC feature 有点相似,但我们不能使用相同的方法,因为我们的解决方案应该适用于所有 Cassandra 版本

假设您知道要查询的时间间隔,则需要创建另一个 table,如下所示:

CREATE TABLE modified_records (
    timeslot timestamp,
    updatedtime timestamp,
    recordid timeuuid,
    PRIMARY KEY (timeslot, updatedtime)
);

现在您可以将 "updated record log" 分成时间片,例如 1 小时,然后像这样填充 table:

INSERT INTO modified_records (timeslot, updatedtime, recordid) VALUES ( '2017-02-27 09:00:00', '2017-02-27 09:36:00', 123);
INSERT INTO modified_records (timeslot, updatedtime, recordid) VALUES ( '2017-02-27 09:00:00', '2017-02-27 09:56:00', 456);
INSERT INTO modified_records (timeslot, updatedtime, recordid) VALUES ( '2017-02-27 10:00:00', '2017-02-27 10:00:13', 789);

您使用 updatedtime 时间戳的一部分作为分区键,例如,在这种情况下,您四舍五入到整数小时。然后通过指定时间段查询,例如:

SELECT * FROM modified_records WHERE timeslot = '2017-02-27 09:00:00';
SELECT * FROM modified_records WHERE timeslot = '2017-02-27 10:00:00';

根据您的记录更新频率,您可以选择更小或更大的时间片,例如每 6 小时、1 天或每 15 分钟。这种结构非常灵活。您只需要知道您要查询的时间段。如果您需要跨越多个时隙,则需要执行多个查询。