Гарантируется ли DynamoDB сходимость к последним данным, когда обновления происходят быстро?

Понятно, что Dynamo не является потокобезопасным при параллельном выполнении обновлений/удалений (если только не используется оптимистическая блокировка обновлений или условная запись).

Что мне интересно, существует ли риск возникновения проблем с согласованностью при запуске обновлений одно за другим без какой-либо паузы последовательно, что-то вроде этого (Javascript):

await dynamo
  .put({ // PUT creates a record if it doesn't exist
    TableName: "table-name",
    Item: {
      id,
      value: "some value"
    }
  })
  .promise();
await dynamo
  .delete({
    TableName: "table-name",
    Key: {
      id
    }
  })
  .promise();

// wait for X seconds for eventual consistency here
const result = await dynamo
  .get({
    TableName: "table-name",
    Key: {
      id
    }
  })
  .promise();
if (result.Item) {
  throw new Error('Oh no, record should have been deleted!');
}

Я запускал этот код 1000 раз, и результаты показывают, что в этом случае можно полагаться на то, что Dynamo будет вести себя так, как ожидалось (выигрывает последнее обновление/удаление), но я хотел бы быть уверенным (ссылка на документы?).

Обновление: другими словами, я хотел бы знать, гарантирует ли Dynamo соблюдение порядка, в котором я отправляю обновления, когда обновления происходят быстро.


person Zhenya    schedule 15.12.2020    source источник
comment
docs.aws.amazon.com/amazondynamodb/latest/developerguide/   -  person Iłya Bursov    schedule 16.12.2020
comment
Это полезно и, кажется, указывает на то, что мои ожидания верны, цитата: Если вы повторите свой запрос на чтение через короткое время, ответ должен вернуть последние данные. Однако в нем конкретно не упоминаются обновления, происходящие быстро одно за другим. Я думаю - возможно, Dynamo нужно ПРОЧИТАТЬ внутренне, прежде чем выполнять УДАЛЕНИЕ? И если он ЧИТАЕТ в тот момент, когда база данных еще не стала согласованной, он может подумать, что УДАЛИТЬ нечего?   -  person Zhenya    schedule 16.12.2020
comment
Определение википедии для согласованности в конечном счете также не вселяет в меня оптимизма: согласованность в конечном счете — это модель согласованности, используемая в распределенных вычислениях для достижения высокой доступности, которая неформально гарантирует, что, если не будут сделаны новые обновления для данного элемента данных, в конечном итоге все обращения к этому элементу вернет последнее обновленное значение. Обратите внимание на часть определения без новых обновлений.   -  person Zhenya    schedule 16.12.2020


Ответы (2)


Если вы хотите иметь гарантию, что вы будете читать последнюю версию данных, вы должны использовать строго согласованное чтение. Таким образом, при запросе вы гарантированно прочитаете последнее значение.

Если вы используете согласованность в конечном счете, вы можете не прочитать последнее значение (вероятность чтения устарела примерно в 33 %). Эмпирически период времени, в течение которого операции чтения будут устаревшими, составляет порядка миллисекунд, а результат устаревшего чтения стремится к нулю по мере увеличения времени с момента последней записи, но конкретного соглашения об уровне обслуживания не существует, в течение которого это может продолжаться. принять для в конечном итоге последовательных чтений для достижения консенсуса. Эмпирически все, что длится более нескольких секунд, будет в порядке, но опять же, если вам нужны надежные гарантии, вам придется использовать строго согласованные чтения.

person Mike Dinescu    schedule 16.12.2020
comment
Это на самом деле не отвечает на мой вопрос. Возможно, мой вопрос был не ясен. Я перефразировал свой вопрос по-другому в разделе обновлений - person Zhenya; 17.12.2020

Получил ответ от службы поддержки AWS:

Короче говоря, да. Независимо от того, как быстро происходят обновления, последнее обновление выигрывает. У вас не будет ситуации, когда служба DynamoDB считает данные согласованными, но это не так, что приводит к долгосрочному устаревшему состоянию. Все команды типа записи в DynamoDB (PutItem, UpdateItem, DeleteItem), которые возвращают код успеха HTTP 200, обрабатываются последовательно.

Если я правильно понимаю ваш пример на StackOverflow, вы помещаете элемент и потом сразу удаляю. Этот элемент ВСЕГДА будет удаляться при запуске в таком порядке. Никогда не будет ситуации, когда PutItem произойдет слишком близко перед DeleteItem, а затем вы получите элемент, не удаленный, как вы ожидали. Возможная и строгая согласованность имеет значение только при чтении данных [1].


Как вы, возможно, знаете, существует два разных способа чтения элемента из таблиц DynamoDB: в конечном счете согласованное (по умолчанию) и строго согласованное.

[+] В конечном счете согласованное чтение обойдется вдвое дешевле (например, 0,5 RCU). для элемента размером 4 КБ), но может возвращать устаревшие данные, если этот элемент был обновлен в течение нескольких секунд до чтения. [+] Чтение со строгой последовательностью осуществляется за полную стоимость (например, 1 RCU за элемент размером 4 КБ), может привести к немного большей задержке в сети и приведет к следующим результатам:

  1. HTTP 200 — возвращает элемент, если он существует, или null, если он не существует. Это верно независимо от того, как недавно выполнялась ПОСЛЕДНЯЯ операция добавления/обновления/удаления перед чтением.
  2. HTTP 500 — с нашей стороны произошла внутренняя сетевая ошибка, и вам нужно повторить попытку чтения (это бывает редко). То, что вы НЕ увидите, — это устаревшие данные или элемент, который был недавно удален.
person Zhenya    schedule 17.12.2020