Cassandra CQL3条件插入/更新

时间:2015-02-28 07:54:17

标签: cassandra conditional updates cql3 nosql

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

我在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不允许&lt;和&gt;轻量级事务IF子句中的运算符。

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

2 个答案:

答案 0 :(得分:4)

你在运行什么版本的cassandra?通过CASSANDRA-6839

在2.1.1中添加了对LWT不平等条件的支持
cqlsh:test> UPDATE events SET first_occurrence = 123456 WHERE event_name='some_event' IF first_occurrence > 1;

[applied]
-----------
  True

答案 1 :(得分:2)

Cassandra在写之前没有读过,只有2个例外 - counters和“lightweight transactions”。因此,您将无法在Cassandra中直接可靠地实现您的方案。即使您读取了值,然后根据这些值进行更新,您也可能会覆盖其他人的更改,因为Cassandra中没有锁定和隔离,并且最终的一致性使其更糟糕。

所以如果你需要实现这样的东西,你需要在Cassandra之外做。创建一个同步层,它将为Cassandra写入提供一个中心点,并使该层负责逻辑。只要确保没有写入这个图层。