如何确保仅在 cassandra 中不存在数据时写入

Posted

技术标签:

【中文标题】如何确保仅在 cassandra 中不存在数据时写入【英文标题】:How to make sure write only if data does not exist in cassandra 【发布时间】:2016-07-27 17:51:57 【问题描述】:

我的服务器应用程序中有两种方法:

boolean isMessageExist(messageId) 执行以下查询:

SELECT messageId from message where messageId =1;

insertMessage(int messageId,String data) 执行以下查询:

INSERT INTO message (messageId,data) VALUES (1, xyz);

在我的代码中,我正在执行以下操作以满足“仅在消息不存在时插入”的要求。

if(!isMessageExist(1))
insertMessage(1,"xyz")

但如果对相同 messageId 的请求几乎同时出现,则上述代码不起作用。

即在时间 T0 ... Read1(1)、Write1(1) 和 Read2(1)、Write2(1) 同时发生,因为这两个请求是同时从客户端发送的。有没有办法在服务器端按顺序发出这些请求。我的意思是 Read2(1) 应该总是得到结果 Write1(1) ?

如果 IF NOT EXISTS 由于性能开销,我不想使用 CAS 操作。 有没有其他方法可以达到我的要求?请提出建议。

【问题讨论】:

【参考方案1】:

使用 Cassandra 的轻量级事务 (LWT) IF NOT EXISTS 应该比您当前正在做的更便宜,并且满足您对唯一性的要求。

INSERT INTO message( messageId, data ) VALUES ( 1, xyz ) IF NOT EXISTS

您可以测试和验证性能,但两次往返(读取、写入)几乎肯定比一次 INSERT ... IF NOT EXISTS 更昂贵。

或者,如果您可以重新设计您的应用程序,使其使用 UPSERTS - 新值只是覆盖旧数据,那会更好,并使用更原生的 Cassandra 样式。

【讨论】:

感谢您的回复。但我认为根据docs.datastax.com/en/cassandra/2.2/cassandra/dml/…,LWT 会更贵。它说“paxos 协议的这四个阶段需要在提出轻量级事务的节点和事务中涉及的任何集群副本之间进行四次往返。性能会受到影响。因此,为必须考虑并发性的情况保留轻量级事务。” .但我会验证的。 注意它不仅仅是 4>2。 LTW 需要“在提出轻量级事务的节点和事务中涉及的任何集群副本之间进行四次往返”,而您当前在客户端驱动程序和服务器之间进行两次往返。因此,性能测试都应该为您提供做出决定所需的事实。

以上是关于如何确保仅在 cassandra 中不存在数据时写入的主要内容,如果未能解决你的问题,请参考以下文章

表中不存在的行

Cassandra如何保证数据最终一致性

仅在列存在时才提供数据框列表

Cassandra 数据如何更新

如何确保 MS Access 中的有界表单和子表单仅在单击按钮后提交到数据库?

如何设置cassandra用户名和密码