Как сделать операцию записи идемпотентной?

Я читаю статью о недавно выпущенной Gizzard sharding framework от twitter (http://engineering.twitter.com/2010/04/introducing-gizzard-framework-for.html). В нем упоминается, что все операции записи должны быть идемпотентными для обеспечения высокой надежности.

по данным Википедия, "идемпотентные операции-это операции, которые могут применяться несколько раз без изменения результата."Но, ИМХО, в случае с желудком, idempotent write операции должны быть такими, последовательность которых не имеет значения.

теперь мой вопрос: Как сделать операции записи идемпотентными?

единственное, что я могу себе представить, это иметь номер версии, прикрепленный к каждой записи. Например, в системе блогов каждый блог должен иметь $blog_id и $ content. На уровне приложений, мы всегда пишем содержание блога, как это write ($blog_id, $content, $version). Этот $version определяется как уникальный на уровне приложения. Итак, если приложение сначала пытается установить один блог на "Hello world", а второй хочет, чтобы это было" Goodbye", то написать идемпотентна. У нас есть такие две операции:

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

эти две операции должны изменить две разные записи в БД. Итак, независимо от того, сколько раз и в какой последовательности выполняются эти две операции, результаты одинаковы.

этот это просто мое понимание. Пожалуйста, поправьте меня, если я ошибаюсь.

2 ответов


вы абсолютно правы. Идемпотентные операции сами по себе могут обеспечить только один шаблон разрешения конфликтов - "последняя запись выигрывает". Это возможное решение, если ваши записи не могут быть переупорядочены во времени. Если они могут, вы должны предоставить дополнительную информацию для автоматического разрешения конфликтов. И ваша идея не нова. В общем случае он называется векторные часы.

мы используем разрешение конфликтов на основе версий в одной из наших систем, которые собирают история изменений объектов в нашей системе. Клиенты отправляют полную информацию о состоянии объекта и версии в модуль хронологии (асинхронно). Затем модуль истории может правильно изменить порядок состояний объекта и сохранить только дельту в постоянном хранилище. Единственное ограничение заключается в том, что клиент должен использовать какой-то контроль параллелизма при внесении изменений в объект (оптимистическая блокировка очень хороший метод, если вы отслеживаете версию состояния объекта).


У вас есть правильная идея. Установка определенного значения является идемпотентной, потому что если вы выполняете эту операцию более одного раза, у вас будет тот же результат. Классическая не идемпотентная запись является добавлением, потому что повторение приведет к добавлению нескольких копий.

а также в предыдущий вопрос stackoverflow.