Каков рекомендуемый способ удаления большого количества элементов из DynamoDB?


Я пишу простой сервис регистрации в DynamoDB.

У меня есть таблица журналов, которая управляется хэшем user_id и диапазоном timestamp (Unix epoch int).

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

каков рекомендуемый способ выполнения такого рода операций (имея в виду, что могут быть миллионы элементов для удаления)?

мои варианты, насколько я могу смотрите здесь:

A: выполните операцию сканирования, вызывая delete для каждого возвращенного элемента, пока не останется ни одного элемента

B: выполните операцию BatchGet, снова вызывая delete для каждого элемента, пока не останется ни одного

оба они выглядят ужасно для меня, как они займут много времени.

то, что я в идеале хочу сделать, это вызвать LogTable.DeleteItem (user_id) - без предоставления диапазона, и пусть он удалит все для меня.

5 62

5 ответов:

что я в идеале хочу сделать, это вызвать LogTable.Фельетонистам(ид_пользователя) - Не поставляя диапазон, и пусть он удалит все для меня.

действительно понятный запрос; я могу представить, что такие расширенные операции могут быть добавлены со временем командой AWS (у них есть история начала с ограниченного набора функций сначала и оценки расширений на основе отзывов клиентов), но вот что вы должны сделать, чтобы избежать стоимости полного сканирования в конце минимум:

  1. использовать запрос, а не Scan чтобы получить все элементы для user_id - это работает независимо от комбинированного хеша / диапазона первичного ключа в использовании, потому что HashKeyValue и RangeKeyCondition являются отдельными параметрами в этом API, и первый только нацелен на значение атрибута хэш-компонента составного первичного ключа..

    • обратите внимание, что вы"ll придется иметь дело с подкачкой API запроса здесь, как обычно, см. ExclusiveStartKey :

      первичный ключ элемента, из которого следует продолжить предыдущий запрос. Один более ранний запрос может предоставить это значение в качестве LastEvaluatedKey, если это операция запроса была прервана до завершения запроса; либо из-за размера результирующего набора или параметра Limit. Этот LastEvaluatedKey может быть передан обратно в новом запросе запрос на продолжение операция от этот момент.

  2. цикл по всем возвращенным элементам и либо облегчить DeleteItem как обычно

    • обновление: скорее всего BatchWriteItem больше подходит для такого случая использования (см. ниже для деталей).

обновление

как указала ивант на BatchWriteItem операция позволяет поставить или удалить несколько элементов в нескольких таблицах в одном вызове API [акцент мой]:

чтобы загрузить один элемент, вы можете использовать API PutItem и удалить его элемент, вы можете использовать API Фельетонистам. Однако, когда вы хотите загрузить или удалить большие объемы данных, такие как загрузка больших объемов данные из Amazon Elastic MapReduce (EMR) или перенос данных из другого источника база данных в Amazon DynamoDB, это API предлагает эффективный альтернатива.

обратите внимание, что это все еще имеет некоторые соответствующие ограничения, в частности:

  • максимальное количество операций в одном запросе - вы можете указать в общей сложности до 25 операций put или delete; однако общий размер запроса не может превышать 1 МБ (полезная нагрузка HTTP).

  • не атомарная операция - отдельные операции, указанные в BatchWriteItem являются атомарный; однако BatchWriteItem в целом является операцией "наилучших усилий", а не атомной операцией. То есть в запросе BatchWriteItem некоторые операции могут быть успешными, а другие-неудачными. [...]

тем не менее, это, очевидно, возможно значительное увеличение случаев использования, как под рукой.

согласно документации DynamoDB вы можете просто удалить полную таблицу.

см. ниже:

"удаление всей таблицы значительно эффективнее, чем удаление элементов по одному, что существенно удваивает пропускную способность записи, поскольку вы выполняете столько операций удаления, сколько операций put"

Если вы хотите удалить только подмножество ваших данных, то вы можете сделать отдельные таблицы для каждого месяца, года или аналогичного. Таким образом, вы могли бы удалите "last month" и сохраните остальные данные нетронутыми.

вот как вы удаляете таблицу в Java с помощью AWS SDK:

DeleteTableRequest deleteTableRequest = new DeleteTableRequest()
  .withTableName(tableName);
DeleteTableResult result = client.deleteTable(deleteTableRequest);

Если вы хотите удалить элементы через некоторое время, например, через месяц, просто используйте опцию Time To Live. Это будет не количество единиц записи.

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

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

в DynamoDB обычно удаление просроченных элементов в течение 48 часов выдыхание. Точная продолжительность, в течение которой элемент действительно удаляется после истечения срока действия зависит от характера рабочей нагрузки и размер стола. Элементы, срок действия которых истек и которые не были удалены, будут по-прежнему отображаются в чтениях, запросах и сканированиях. Эти предметы все еще могут быть обновленные и успешные обновления для изменения или удаления срока действия атрибут будет заслуженный.

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/howitworks-ttl.html

ответ на этот вопрос зависит от количества элементов и их размеров и вашего бюджета. Зависит от того, что у нас есть следующие 3 случая:

1 - число элементов и размер элементов в таблице не очень много. затем, как сказал Штеффен Опель, вы можете использовать запрос, а не сканирование, чтобы получить все элементы для user_id, а затем перебрать все возвращенные элементы и либо облегчить DeleteItem или BatchWriteItem. Но имейте в виду, что вы можете сжечь много пропускной способности здесь. Например, рассмотрим ситуация, когда необходимо удалить 1000 элементов из таблицы DynamoDB. Предположим, что каждый элемент имеет размер 1 КБ, в результате чего около 1 МБ данных. Эта задача массового удаления потребует в общей сложности 2000 единиц емкости записи для запроса и удаления. Чтобы выполнить эту загрузку данных в течение 10 секунд (что даже не считается быстрым в некоторых приложениях), вам нужно будет установить подготовленную пропускную способность записи таблицы в 200 единиц емкости записи. Как вы можете видеть его реально использовать этот способ, если его меньше количество деталей или деталей малого размера.

2-мы имеем много детали или очень большие детали в таблице и мы можем хранить они согласно времени в различные таблицы. Тогда как Джонатан сказал, что вы можете просто удалить таблицу. это намного лучше, но я не думаю, что это соответствует вашему делу. Поскольку вы хотите удалить все данные пользователей независимо от времени создания журналов, поэтому в этом случае вы не можете удалить конкретную таблицу. если вы хотите иметь отдельную таблицу для каждого пользователя, тогда я угадайте, если количество пользователей велико, то его так дорого, и это не практично для вашего случая.

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

У нас нет возможности усечь таблицы Динамо. мы должны отбросить таблицу и создать снова . Заряды DynamoDB основаны на ReadCapacityUnits & WriteCapacityUnits . Если мы удалим все элементы с помощью функции BatchWriteItem, он будет использовать WriteCapacityUnits.So лучше удалить определенные записи или удалить таблицу и начать все сначала .