Подтвердить что ты не робот

Измените схему таблицы DynamoDB: какой лучший/рекомендуемый способ?

Что такое рекомендованный Amazon способ изменения схемы большой таблицы в производственном DynamoDB?

Представьте гипотетический гипотетический случай, когда у нас есть таблица Person, с первичным хэш-ключом SSN. Эта таблица может содержать 10 миллионов элементов.

Теперь стало известно, что из-за критического объема краж личных данных правительство этой гипотетической страны ввело другую личную идентификацию: уникальный персональный идентификатор или UPI.

Нам нужно добавить столбец UPI и изменить схему таблицы Person, так что теперь основной хеш-ключ является UPI. Мы хотим в течение некоторого времени поддерживать как текущую систему, использующую SSN, так и новую систему, которая использует UPI, поэтому нам нужно, чтобы оба этих столбца сосуществовали в таблице Person.

Что такое рекомендованный Amazon способ изменения этой схемы?

4b9b3361

Ответ 1

Существует несколько подходов, но сначала вы должны понимать, что вы не можете изменить схему существующей таблицы. Чтобы получить другую схему, вам нужно создать новую таблицу. Возможно, вы сможете повторно использовать существующую таблицу, но результат будет таким же, как если бы вы создали другую таблицу.

  • Ленивая миграция в ту же таблицу без Streams. Каждый раз, когда вы изменяете запись в таблице Person, создайте новый элемент в таблице Person, используя UPI, а не SSN, как значение для хеш-ключа, и удалите старый элемент, введенный в SSN. Это предполагает, что UPI извлекает из другого диапазона значений, чем SSN. Если SSN выглядит как XXX-XX-XXXX, то до тех пор, пока UPI имеет различное количество цифр, чем SSN, у вас никогда не будет перекрытия.
  • Ленивая миграция в ту же таблицу с использованием потоков. Когда потоки становятся общедоступными, вы сможете включить Stream для вашей таблицы Person. Создайте поток с типом представления потока NEW_AND_OLD_IMAGES и всякий раз, когда вы обнаруживаете изменение элемента, который добавляет UPI к существующему человеку в таблице Person, создайте функцию Lambda, которая удаляет человека, введенного в SSN, и добавляет человека с тем же атрибуты, введенные в UPI. Этот подход имеет условия гонки, которые можно смягчить, добавив атрибут атомной контр-версии к элементу и обусловливая вызов DeleteItem атрибутом версии.
  • Переназначение (сценарий) миграции в другую таблицу с использованием потоков. Запустите script, который сканирует вашу таблицу и добавляет уникальный UPI для каждого элемента Person в таблице Person. Создайте поток на таблице Person с видом потока NEW_AND_OLD_IMAGES и подпишите лямбда-функцию для этого потока, который записывает все новые лица в новую таблицу Person_UPI, когда функция лямбда обнаруживает, что лицо с UPI было изменено или когда у человека было UPI добавил. Мутации на базовой таблице обычно занимают сотни миллисекунд, чтобы они отображались в потоке в виде записей потока, поэтому вы можете выполнить горячий переход на новую таблицу Person_UPI в приложении. Отклоните запросы на несколько секунд, укажите ваше приложение в таблицу Person_UPI за это время и повторно включите запросы.

Ответ 2

Потоки DynamoDB позволяют нам переносить таблицы без простоя. Я сделал это очень эффективно, и шаги, которые я выполнил, следующие:

  • Создайте новую таблицу (позвольте нам назвать этот NewTable), с требуемой структурой клавиш, LSI, GSI.
  • Включить потоки DynamoDB в исходной таблице
  • Свяжите Лямбду с потоком, который подталкивает запись в NewTable. (Эта Лямбда должна обрезать флаг миграции на шаге 5)
  • [Дополнительно] Создайте GSI в исходной таблице, чтобы ускорить сканирование элементов. Убедитесь, что этот GSI имеет только атрибуты: Первичный ключ и Миграция (см. Шаг 5).
  • Сканирование GSI, созданного на предыдущем шаге (или всей таблице), и использование следующего фильтра:

    FilterExpression = "attribute_not_exists (Migrated)"

Обновите каждый элемент в таблице с помощью флажка переноса (т.е. "Миграция": { "S": "0" }, который отправляет его в потоки DynamoDB (с использованием API UpdateItem, чтобы гарантировать отсутствие потери данных).

ПРИМЕЧАНИЕ. Возможно, вы захотите увеличить количество единиц мощности записи в таблице во время обновлений.

  1. Лямбда возьмет все предметы, обрезает флаг Migrated и введет его в NewTable.
  2. Как только все элементы были перенесены, переведите код в новую таблицу
  3. Удалить исходную таблицу, а функция Lambda после того, как вы счастливы, все хорошо.

Следуя этим шагам, вы должны убедиться, что у вас нет потери данных и нет простоев.

Я зарегистрировал это в своем блоге с кодом, чтобы помочь: https://www.abhayachauhan.com/2018/01/dynamodb-changing-table-schema/

Ответ 3

Я использую вариант третьего подхода Александра. Опять же, вы создаете новую таблицу, которая будет обновляться по мере обновления старой таблицы. Разница заключается в том, что вы используете код в существующей службе для записи в обе таблицы во время перехода вместо использования лямбда-функции. У вас может быть пользовательский код сохранения, который вы не хотите воспроизводить во временной лямбда-функции, и, вероятно, вам все равно придется писать код службы для этой новой таблицы. В зависимости от вашей архитектуры вы даже можете переключиться на новую таблицу без простоя.

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