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

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

Я пишу простую службу ведения журнала в DynamoDB.

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

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

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

Мои параметры, насколько я могу судить, следующие:

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

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

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

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

4b9b3361

Ответ 1

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

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

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

    • Обратите внимание, что вам, как обычно, придется обращаться к поисковому API-интерфейсу запроса, см. параметр ExclusiveStartKey:

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

  • Перебирать все возвращенные элементы и либо облегчать DeleteItem, как обычно

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

Update

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

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

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

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

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

Тем не менее, это, очевидно, дает потенциально значительный выигрыш для использования, например, под рукой.

Ответ 2

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

См. ниже:

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

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

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

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

Ответ 3

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

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

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

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

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

Ответ 4

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

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

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

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

Ответ 5

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

Ответ 6

Мой подход к удалению всех строк из таблицы в DynamoDb состоит в том, чтобы просто извлечь все строки из таблицы, используя DynamoDbs ScanAsync, а затем передать список результатов в DynamoDbs AddDeleteItems. Ниже код в С# работает нормально для меня.

        public async Task DeleteAllReadModelEntitiesInTable()
    {
        List<ReadModelEntity> readModels;

        var conditions = new List<ScanCondition>();
        readModels = await _context.ScanAsync<ReadModelEntity>(conditions).GetRemainingAsync();

        var batchWork = _context.CreateBatchWrite<ReadModelEntity>();
        batchWork.AddDeleteItems(readModels);
        await batchWork.ExecuteAsync();
    }