2010-04-08 63 views
7

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

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

现在,我的问题是:如何使写操作idempotent?

我能想象的唯一事情就是每个写入都附加一个版本号。例如,在博客系统中,每个博客必须有一个$ blog_id$ content。在应用程序级别,我们总是编写像这样的这样的博客内容($ blog_id,$ content,$ version)$版本被确定为在应用程序级别唯一。因此,如果一个应用程序首先尝试将一个博客设置为“Hello world”,并且第二个希望它是“再见”,那么编写是幂等的。我们有这样的两个写操作:

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

这两个操作都应该在DB改变了两个不同的记录。所以,无论执行这两个操作的次数和顺序如何,结果都是一样的。

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

回答

3

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

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

2

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

此外,请参阅此previous stackoverflow question