以原子方式更新Cassandra中的共享状态

Din*_*esh 2 cassandra nosql

问题:

我打算将cassandra用作我的应用程序的nosql数据存储.我有一个使用案例是更新用户的"余额".假设每个用户的余额存储为密钥UID_balance.现在,如果我的应用程序想要更新多个用户的余额,我将如何处理原子性?

我想,在某些时候,应用程序基本上会执行以下操作:

1. for each user u
2.    current_balance = read_users_balance(u);
3.    new_balance     = current_balance + delta_for_user(u);
4.    write_users_balance(u, new_balance);
5. end
Run Code Online (Sandbox Code Playgroud)

现在,这里有几个问题:

  1. 与cassandra的连接可能会中断,导致代码仅更新少数用户的余额.
  2. 在步骤2和步骤4之间,可能有另一个进程可以更新用户的余额,我将更新陈旧的余额,使用户的余额处于"损坏"状态.

RDBMS'解决了这些问题,因为它们提供ACID属性,而Cassandra则没有.我最近看到Cassandra(2012年10月)已经开始提供Atomic Batches.我不确定这是否是解决这个问题的正确方法.

可能解决方案

这是我和朋友一起集思广益的事情.我们实际上并不更新用户的余额,而是创建一条记录,将更新增量附加到不同的记录.例如:

UID1_balance = {100}
UID1_deltas  = {10,20,-40}
Run Code Online (Sandbox Code Playgroud)

为了获得当前的余额,我们只需将增量应用于余额.我们可以有一个脱机过程,将增量应用于用户的余额并修剪增量列表.

这个解决方案起作用并减少腐败状态的可能性,但我认为这是一种矫枉过正.有没有更好的方法来解决这个问题?

Dea*_*ler 6

我建议阅读"建立在流沙上"的论文,这会让你考虑到帐户,他们甚至会参考像这样的银行帐户示例.注意:Chase和well fargo不会在交易中转账,因此他在那篇文章中解释了我们如何在微观层面上做同样的事情,就像宏观层面一样;).

这也有助于PlayOrm for cassandra的编写,因为现在PlayOrm维基上也有一个模式页面.