4

我试图了解 etcd 上的“原子”更新是什么。

当我想到“原子”时,我认为有“之前”和“之后”(没有期间,如果更新失败,它仍然是“之前”)。

这是一个例子:

curl -s -XPUT http://localhost:2379/v2/keys/message -d value='Hidee Ho'

因此,此时,任何人都可以访问该消息并获取当前值:

curl -s http://localhost:2379/v2/keys/message
{"action":"get","node":{"key":"/message","value":"Hidee Ho","modifiedIndex":4748,"createdIndex":4748}}

稍后,我可以修改这个值,如下所示:

curl -s -XPUT http://localhost:2379/v2/keys/message -d value='Mr Hanky'

并且可以像以前一样获取结果。在我更改值“Hidee Ho”之前返回,更改后值“Mr Hanky”返回。所以,我的问题是我能保证其中一个结果吗?也就是说,我想确认将返回一个或另一个(而不是结果之间的nil值)。

我不是特别在意时间。如果我进行 Hanky 先生更新,并且随后的价值获取者在(短)一段时间内继续获得 Hidee Ho,那没关系。

我很困惑,因为协议中有一个 Atomic CompareAndSwap函数。据我所知,它不是原子的,而是“只有当值是我所说的值时才进行更新”。就我而言,我不太在乎过去的价值。我只想知道它已经改变了,除了“之前”或“之后”值之外,没有读者会看到任何东西。

4

1 回答 1

8

您是正确的,因为普通 PUT 是原子的,因为客户端只会看到以前的值或新值。

CompareAndSwap 功能允许您进行乐观锁定,以便您可以写入取决于先前值的新值,例如计数器。如果你要在不使用 CompareAndSwap 的情况下实现一个计数器,你会有类似的东西write("count", 1 + read("count")),在这种情况下,读取和写入是分开的,如果 2 个调用者同时这样做,那么他们可能都会看到相同的起始值,并且您会丢失其中一个增量。使用 CAS,调用者可以说只有在前一个值为 11 时才将其设置为 12,现在如果这种情况同时发生,其中一个写入将失败,然后它可以重新读取并重新应用其增量,这样你就不会松动任何增量。

于 2015-06-17T01:12:09.000 回答