#amazon-web-services #amazon-dynamodb
#amazon-web-services #amazon-dynamodb
Вопрос:
У меня возникли проблемы с тем, чтобы понять дихотомию DDB, обеспечивающую запись условий, но также являющуюся в конечном итоге последовательной. Эти две истины, по-видимому, противоречат друг другу.
В классическом сценарии пользователь Bob обновляет ключ A и устанавливает значение «FOO». Пользователь Alice считывает данные с узла, который еще не получил обновление, и поэтому он получает исходное значение «BAR» для того же ключа.
Если Боб и Алиса выполняют запись на разные узлы кластера без проверки условий, может возникнуть конфликт, когда Алиса и Боб одновременно выполняют запись в один и тот же ключ, и DDB не знает, какое обновление должно быть последним. Этот конфликт должен быть разрешен клиентом при следующем чтении.
Но как насчет того, когда используются условия записи?
Пользователь Bob отправляет свое обновление для A как «FOO», если существующее значение для A равно «BAR». Пользователь Alice отправляет свое обновление для A как «BAZ», если существующее значение для A равно «BAR».
Локально каждый узел может проверить, имеет ли его узел исходное значение «BAR», и выполнить обновление. Но единственный способ узнать истинное состояние A во всем кластере — это сначала выполнить строго согласованное чтение по всему кластеру. Это строго согласованное чтение должно блокировать либо Алису, либо Боба, иначе они оба могут одновременно выполнять строго согласованное чтение.
Итак, вот где я запутался в характере записи условий DDBs. Мне кажется, что либо:
- Операции записи условий оцениваются только локально. Конфликты слияния все еще могут возникать.
- Операции записи условий оцениваются между кластерами.
Если это # 2, единственный способ, которым я вижу, что это работает, — это если:
- Для ключа создается блокировка.
- Выполняется строго согласованное чтение.
Допустим, это # 2. Теперь, где это оставляет обновление Боба? Обновление было внесено в узел 2 и отправлено на узел 1, и у нас есть кворум большинства. Но чтобы сделать эти обновления доступными для Alice, когда они выполняют свою собственную условную запись, эти обновления необходимо удалить из WAL. Итак, при условной записи обновления всегда сбрасываются? Всегда ли записи сбрасываются вообще?
Здесь были и другие подобные вопросы, но ответы были повторением или ссылкой на документацию AWS по этому поводу. Документация AWS на самом деле не объясняет этого (или я пропустил это).
Ответ №1:
Условные записи DynamoDB — это «транзакционные» записи, но то, как они выполняются, не является общедоступной информацией и, возможно, является частной интеллектуальной собственностью.
Разработчики DynamoDB — единственные, у кого есть эта информация.
Ваша проблема в том, что вы смотрите на это с точки зрения узла — я просмотрел все упоминания об узле где угодно в документации DynamoDB, и это просто упоминания Node.js или узлы DAX не являются узлами базы данных.
Хотя могут быть устаревшие чтения — да, это указывало бы на некоторую форму узла — при выполнении условной записи нет узлов базы данных для таких.
Пользователь Bob отправляет свое обновление для A как «FOO», если существующее значение для A равно «BAR». Пользователь Alice отправляет свое обновление для A как «BAZ», если существующее значение для A равно «BAR».
Чей бы запрос ни поступил туда первым, он проходит первым.
Следующий запрос просто завершится неудачей, что означает, что теперь вам нужно сделать новый запрос на чтение, чтобы получить последнее значение, а затем продолжить 2-ю последующую запись.
Руководство разработчика Amazon DynamoDB показывает это очень четко.
Обратите внимание, что нет узлов, реплик и т. Д. — Существует только 1 ссылка на таблицу DynamoDB:
Записи условий, вероятно, оцениваются между кластерами, и, вероятно, выполняется строго согласованное чтение, но Amazon не обнародовал эту информацию.
Комментарии:
1. Невероятно полезно — спасибо. Просто говорю: «Разработчики DynamoDB — единственные, у кого есть эта информация». один избавляет меня от необходимости просматривать каждый технический документ, чтобы прийти к тому же выводу. Когда вы говорите, что «условные записи являются транзакционными», означает ли это, что DDB также считает это «транзакционной записью», или вы имеете в виду «транзакционную» в обычном смысле?
2. Не беспокойтесь — я имею в виду транзакционные, поскольку в обычном смысле это условно 🙂
Ответ №2:
Эрмия Эскандарий права в том, что точные детали реализации DynamoDB не являются общедоступными, а также могут быть изменены в будущем при сохранении документированных гарантий API. Тем не менее, различные документы и особенно видеопрезентации, которые разработчики Amazon делали в прошлом, относительно ясно показали, как это работает под капотом — по крайней мере, в общих чертах, и я попытаюсь объяснить свое понимание здесь: Обратите внимание, что это может быть не на 100% точным, и у меня нет никакихвнутренние знания о DynamoDB.
- DynamoDB хранит три копии каждого элемента.
- Один из узлов, содержащих копию определенного элемента, назначается лидером для этого элемента (нет ни одного «лидера» — это может быть другой лидер для каждого элемента). Насколько я знаю, у нас нет подробностей о том, какой протокол используется для выбора этого лидера (конечно, если узлы выходят из строя, выбор лидера меняется).
- Запись в элемент запускается на лидере, который сериализует записи в тот же элемент. Обратите внимание, что условные обновления DynamoDB могут считывать и обновлять только один и тот же элемент, поэтому один и тот же узел (ведущий) может считывать и записывать элемент только с локальной блокировкой. После того, как руководитель оценивает кодировку и принимает решение о записи, он также отправляет обновление двум другим узлам, возвращая пользователю успех только после того, как два из трех узлов успешно записали данные (для обеспечения долговечности).
- Как вы, наверное, знаете, у операций чтения в DyanamoDB есть два варианта «согласованный» и «в конечном итоге согласованный«: в конечном итоге согласованное чтение произвольно считывается из одной из трех реплик и может еще не увидеть результат успешной записи (если запись записала две копии, но еще не третью).). Последовательное чтение считывается с лидера, поэтому гарантируется чтение ранее записанных данных.
Наконец, вы спросили о более новой и более дорогой «транзакционной» поддержке DynamoDB. Это совершенно другая функция. «Транзакции» DynamoDB связаны с чтением и записью нескольких элементов в одном запросе. Как я объяснял выше, более старая функция условных обновлений позволяет выполнять операцию чтения-изменения-записи только для одного элемента за раз и, следовательно, имеет более простую реализацию — где один узел (ведущий) может сериализовать параллельные записи и принимать решения без сложного распределенного алгоритма (однако,для выбора лидера необходим сложный распределенный алгоритм).