Как я могу сделать атомное обновление с etcd

Я пытаюсь понять, что такое "атомарное" обновление в терминах 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 между результатом).

Меня не особо волнует время. Если я сделаю обновление мистера Хэнки, и последующие средства извлечения значения продолжат получать Hidee Ho в течение (короткого) периода времени, это нормально.

Я запутался, потому что в протоколе есть функция Atomic CompareAndSwap. Насколько я могу судить, это не столько атомный, сколько "обновление только в том случае, если значение соответствует моему". В моем случае мне все равно, какое значение было раньше. Я просто хочу знать, что это изменилось и что никто из читателей не увидит ничего, кроме значений "до" или "после".

1 ответ

Решение

Вы правы в том, что простой PUT является атомарным в том, что клиент будет видеть только предыдущее значение или новое значение.

Функция CompareAndSwap позволяет вам выполнять оптимистическую блокировку, чтобы вы могли записывать новые значения, которые зависят от предыдущего значения, например, счетчик. Если бы вы реализовали счетчик без использования CompareAndSwap, у вас было бы что-то вроде write("count", 1 + read("count")) в этом случае чтение и запись разделены, если 2 вызывающих абонента сделали это одновременно, то возможно, что они оба увидят одинаковое начальное значение, и вы потеряете одно из приращений. используя CAS, вызывающий абонент может сказать, установить его на 12, только если предыдущее значение равно 11, а теперь, если это происходит одновременно, одна из записей завершится неудачно, а затем он может перечитать и повторно применить свою дельту, чтобы вы не потеряли любые приращения.

Другие вопросы по тегам