我有一个无序事件列表,我的任务是存储它们的第一次和最后一次出现。
我在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子句中的运算符。
所以我的问题是,进行此类条件更新的模式是什么?
答案 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写入提供一个中心点,并使该层负责逻辑。只要确保没有写入这个图层。