首页 > 解决方案 > Cassandra 行顺序与集群键的一致性

问题描述

在 Datastax 博客中阅读了有关使用 Cassandra 作为队列的陷阱的文章。很快,如果我们有这样的表

CREATE TABLE queues (
    name text,
    enqueued_at timeuuid,
    payload blob,
    PRIMARY KEY (name, enqueued_at)
);

并且我们删除已处理的行,随后的选择查询将在读取未处理的行之前扫描太多的墓碑。

SELECT enqueued_at, payload FROM queues WHERE name = 'queue-1'

作为一个潜在的解决方法,作者建议保存最后处理的行的 timeuuid 并在这样的查询中使用它来排除墓碑扫描

SELECT enqueued_at, payload 
FROM queues 
WHERE name = 'queue-1' AND enqueued_at > 9d1cb818-9d7a-11b6-96ba-60c5470cbf0e

但我无法理解一件事:依靠这种方法是否安全?当然,timeuuid 是按照集群键的时间顺序排序的,但是 Cassandra 是否给我们一些保证,在我们记忆的 timeuuid 之前不会添加任何记录,以防同时写入?例如,如果我们使用now()函数插入新记录:

INSERT INTO queues VALUES ('queue-1', now(), /*some payload*/)

文档说,now()在协调节点上生成新的 timeuuid。那么,是否有可能的情况:

  1. Coordinator1用timeuuid1生成record1并开始写
  2. Coordinator2 生成timeuuid2 > timeuuid1的 record2并开始写入
  3. record2的写入完成
  4. Coordinator3 从 partition 中读取新记录并 memoize timeuuid2
  5. 记录1的写入完成
  6. Coordinator3从timeuuid2开始读取新记录,跳过record1

?

标签: concurrencycassandratimeuuid

解决方案


推荐阅读