【问题标题】:DynamoDB atomic counter for account balance用于账户余额的 DynamoDB 原子计数器
【发布时间】:2016-05-17 21:24:10
【问题描述】:

在 DynamoDB 中,原子计数器是避免竞争条件的数字

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithItems.html#WorkingWithItems.AtomicCounters

什么使数字具有原子性,我可以在非单位值中添加/减去浮点数吗?

目前我正在做:“SET balance = balance + :change”

(长版)我正在尝试将 DynamoDB 用于用户余额,因此准确性至关重要。余额可以同时从多个来源更新。不需要预取余额,我们永远不会拒绝交易,我只关心当所有操作完成后,我们会留下正确的余额。只要最终结果正确,这些操作也可以按任何顺序应用。

据我了解,这应该没问题,但我没有看到任何原子增量示例会更改“1”以外的值

之所以犹豫,是因为像Amazon DynamoDB Conditional Writes and Atomic Counters 这样的问题建议在类似情况下使用条件写入,这听起来是个糟糕的主意。如果我获取余额、更改并进行有条件的写入,如果值在此期间发生更改,则写入可能会失败。然而,平衡是业务关键的定义,忽略文档时我总是很紧张

-附加信息-

所有写入都来自 Lambda 函数,我预计写入的成功率几乎是 100%。但是,我还保留了所有更改的历史记录,如果余额处于“未知”状态(例如网络超时),可以锁定表并从历史记录中重新计算正确的余额。

我认为这是最好的“正常”操作。 99.999% 的情况下,所有更新都将通过一次写入进行。失败的代价可能非常高昂,因为我们需要扫描客户的整个历史来重新创建平衡,但就权衡而言,这似乎是一个相当安全的选择。

【问题讨论】:

    标签: amazon-dynamodb


    【解决方案1】:

    原子计数器的文档非常清楚,我认为它对您的用例不安全。

    您要解决的问题很常见,AWS 建议在这种情况下使用乐观锁定。 请参阅以下 AWS 文档, http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptimisticLocking.html

    【讨论】:

    • 所有这些文件都确保根据号码的正确客户端版本进行更改。我从不检索“余额”,因此不存在过时版本的风险。
    • 如果更新操作不能确保一致性,那么无论我使用哪种方法,我都无法保证正确的数字。对于条件写入,我们将存储的数字与我们预期的初始条件相匹配,但是如果不能保证更新是一致的,那么 IFF 测试可能会通过(初始化值匹配),外部进程会更改值,然后我们用我们的值覆盖更改
    • 换句话说,如果在执行“更新”操作时任何数字是“原子计数器”,那么要么用例有效,要么原子计数器无法满足预期。如果原子计数器是一种特殊的数字类型,或者只有以“1”递增时才起作用的函数,那么我的操作不算是原子的,我被骗了:)
    • 我没有关注您对客户端版本的评论。乐观锁定的工作方式是,它期望您检索余额,随后的写入确保数据库值自上次检索以来没有更改。我不确定为什么它不适用于您的用例。
    • 我从来没有真正得到当前的余额。我没有在 db 值上发送“SET”,而是发送了一个偏移量。这意味着我其实并不关心存储的值是什么,只要正确记录了偏移量,如果5个操作同时偏移该值,则最终值是正确的。
    【解决方案2】:

    从 AWS 工作人员的回复看来,这个概念是可行的

    应用程序编写者通常会结合使用这两种方法, 您可以在其中使用原子计数器进行实时计数,以及 审计表,以便以后完善会计。

    https://forums.aws.amazon.com/thread.jspa?messageID=470243&#470243

    还有确认更新是原子的,任何更新操作都是一致的

    您发送到 DynamoDB 的所有非批处理请求都会自动处理 - 请求之间不涉及任何类型的交错。写请求也是一致的,所以任何写请求都会更新 收到请求时项目的最新版本。

    https://forums.aws.amazon.com/thread.jspa?messageID=621994&#621994

    事实上,对给定项目的每次写入都是强一致的

    在 DynamoDB 中,针对给定项目的所有操作都是序列化的。

    https://forums.aws.amazon.com/thread.jspa?messageID=324353&#324353

    【讨论】:

    • "对给定项目的操作已序列化"...但是您的代码不知道选择了哪种序列化顺序。考虑到UPDATE(+1), DELETE, CREATE(10) = 10 可能会变成DELETE, CREATE(10), UPDATE(+1) = 11
    • 是的,一旦你有绝对动作,它就会中断。只要操作是相对的,就可以了
    • 实际上它也被全局表中的相对操作“破坏”了。协调是基于图像的,这意味着在跨区域冲突的情况下,整个项目的一个版本获胜。
    猜你喜欢
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-31
    • 2016-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多