问题:
我计划将 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
现在,这里有几个问题:
- 与 cassandra 的连接可能会中断,导致代码仅更新少数用户的余额。
- 在第 2 步和第 4 步之间,可能有另一个过程可以更新用户的余额,我将更新一个过时的余额,使用户的余额处于“损坏”状态。
RDBMS 解决了这些问题,因为它们提供了 ACID 属性,而 Cassandra 没有。我看到 Cassandra 最近(2012 年 10 月)开始提供 Atomic Batches。我不确定这是否是解决此问题的正确方法。
可能的解决方案:
这是我和一个朋友的头脑风暴。我们实际上并没有更新用户的余额,而是创建一个记录,将更新增量附加到不同的记录。例如:
UID1_balance = {100}
UID1_deltas = {10,20,-40}
为了获得当前余额,我们只需将增量应用于余额。我们可以有一个离线过程,将增量应用到用户的余额并修剪增量列表。
该解决方案有效并减少了损坏状态的可能性,但我认为这是一种矫枉过正的做法。有没有更好的方法来解决这个问题?