【问题标题】:Cassandra CQL3 conditional insert/updateCassandra CQL3 条件插入/更新
【发布时间】:2015-02-28 07:54:16
【问题描述】:

我有一个无序事件列表,我的任务是为它们存储第一次和最后一次出现的事件。

我在 Cassandra 中有以下列族:

CREATE TABLE events (
   event_name TEXT,
   first_occurrence BIGINT,
   last_occurrence BIGINT,
   PRIMARY KEY (event_name)
);

因此,如果我有一个名为“some_event”的事件并发生为 123456,我想要做的是在 MySQL 术语中看起来像这样的事情:

INSERT INTO events (event_name, first_occurence, last_occurence)
VALUES ('some_event', 123456, 123456)
ON DUPLICATE KEY UPDATE 
     first_occurrence = LEAST(first_occurrence, 12345), 
     last_occurrence = GREATEST(last_occurrence, 123456)

我打算在 Cassandra 中使用轻量级事务来完成它,如下所示:

INSERT INTO events(event_name, first_occurrence, last_occurrence) VALUES ('some_event', 12345, 12345) IF NOT EXISTS;
UPDATE events SET first_occurrence = 123456 WHERE event_name='some_event' IF first_occurrence > 123456;
UPDATE events SET last_occurrence = 123456 WHERE event_name='some_event' IF last_occurrence < 123456;

但事实证明,CQL3 不允许在轻量级事务的 IF 子句中使用 运算符。

所以我的问题是,进行这种条件更新的模式是什么?

【问题讨论】:

    标签: cassandra conditional updates cql3 nosql


    【解决方案1】:

    您运行的是哪个版本的 cassandra? 2.1.1 通过CASSANDRA-6839 添加了对 LWT 不相等条件的支持:

    cqlsh:test> UPDATE events SET first_occurrence = 123456 WHERE event_name='some_event' IF first_occurrence > 1;
    
    [applied]
    -----------
      True
    

    【讨论】:

    • 谢谢,这正是我的目的。我目前正在运行 DataStax community 2.0.9。这意味着我需要切换到“开发”分支
    【解决方案2】:

    Cassandra 不会先读后写,只有 2 个例外 - counters 和“lightweight transactions”。因此,您将无法直接在 Cassandra 中可靠地实现您的场景。即使您读出这些值然后根据这些值进行更新,您也可能会覆盖其他人的更改,因为 Cassandra 中没有锁定和隔离,最终的一致性会使情况变得更糟。

    因此,如果您需要实现类似的功能,则需要在 Cassandra 之外进行。创建一个为 Cassandra 写入提供中心点的同步层,并使该层负责逻辑。只需确保没有写入围绕这一层进行。

    【讨论】:

    • 嗯,我看不出 IF 列 = 值和 IF 列
    • 你没有抓住重点。这不是关于等于和不等于之间的区别,而是关于您在插入或更新时不知道数据库中的值的事实。因此,INSERT 是 Cassandra 中 UPDATE 的同义词。在 4 个 ACID 属性(原子性、一致性、隔离性、持久性)中,Cassandra 仅提供 2 个 - A 和 D。您的示例至少需要一个属性 - 隔离,也可能是一致性。这就是为什么我说你必须在 Cassandra 之外构建一些东西来提供这些属性。
    • 我认为我们在这里争论的是不同的事情。轻量级交易确实有效吗? Cassandra 以某种方式在轻量级事务上执行 read-before-write 事情,这样的查询:UPDATE events SET first_occurrence = 123456 WHERE event_name='some_event' IF first_occurrence = 2345678; 所以我看不出技术上的差异会影响 equals 和 not equals 比较。
    • 啊,不小心删除了我的评论而不是添加它。 LWT 为比较和设置 (CAS) 操作提供可线性化的一致性。传统上,CAS 操作要求预期值等于当前值以应用更改。 CASSANDRA-6839 (2.1.1+) 允许您使用 >、
    猜你喜欢
    • 2013-08-09
    • 2013-06-30
    • 2013-05-15
    • 2015-10-28
    • 1970-01-01
    • 2013-02-07
    • 2017-08-18
    • 2016-09-19
    • 2018-08-11
    相关资源
    最近更新 更多