【问题标题】:How to make write operation idempotent?如何使写操作具有幂等性?
【发布时间】:2011-02-05 13:46:15
【问题描述】:

我正在阅读 twitter (http://engineering.twitter.com/2010/04/introducing-gizzard-framework-for.html) 上最近发布的 Gizzard 分片框架的文章。它提到所有的写操作必须是幂等的,以确保高可靠性。

根据wikipedia,“幂等操作是可以多次应用而不改变结果的操作。”但是,恕我直言,在 Gizzard 的情况下,幂等写操作应该是顺序无关紧要的操作。

现在,我的问题是:如何使写操作具有幂等性?

我唯一能想到的就是在每次写入时附加一个版本号。例如,在博客系统中,每个博客必须有一个 $blog_id$content。在应用程序级别,我们总是像这样 write($blog_id, $content, $version) 来编写博客内容。 $version 在应用程序级别被确定为唯一的。因此,如果一个应用程序首先尝试将一个博客设置为“Hello world”,然后再将其设置为“Goodbye”,那么 write 是幂等的。我们有这样两个写操作:

write($blog_id, "Hello world", 1);
write($blog_id, "Goodbye", 2);

这两个操作应该改变数据库中的两条不同的记录。所以,无论这两个操作执行多少次,以什么顺序执行,结果都是一样的。

这只是我的理解。如果我错了,请纠正我。

【问题讨论】:

    标签: scalability idempotent


    【解决方案1】:

    你完全正确。幂等操作本身只能提供一种冲突解决模式——“最后写入获胜”。如果您的写入无法及时重新排序,这是一个可能的解决方案。如果可以,您应该提供其他信息以自动解决冲突。你的想法并不新鲜。在一般情况下,它被称为vector clocks

    我们在其中一个系统中使用基于版本的冲突解决方案,该系统收集系统中对象的更改历史记录。客户端将完整的对象状态和版本信息发送到历史模块(异步)。历史模块然后可以以正确的方式重新排序对象状态,并仅将增量保存在持久存储中。唯一的限制是客户端在更改对象时应该使用某种并发控制(如果您跟踪对象状态版本,optimistic locking 是非常好的方法)。

    【讨论】:

      【解决方案2】:

      你的想法是对的。设置特定值是幂等的,因为如果您多次执行该操作,您将获得相同的结果。经典的非幂等写入是追加,因为重复会导致追加多个副本。

      另外,请参阅previous stackoverflow question

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-26
        • 1970-01-01
        • 2020-05-08
        • 2018-03-05
        • 1970-01-01
        • 2010-11-07
        • 1970-01-01
        相关资源
        最近更新 更多