Quel est le moyen recommandé de supprimer un grand nombre d'éléments de DynamoDB?

J'écris un service de journalisation simple dans DynamoDB.

J'ai une table de journaux qui est saisie par un hachage user_id et une plage d'horodatage (Unix Epoch int).

Lorsqu'un utilisateur du service termine son compte, je dois supprimer tous les éléments de la table, quelle que soit la valeur de la plage.

Quelle est la façon recommandée de faire ce genre d'opération (en gardant à l'esprit qu'il pourrait y avoir des millions d'éléments à supprimer)?

Mes options, autant que je peux voir sont:

Un: Effectuez une opération D'analyse, en appelant delete sur chaque élément renvoyé, jusqu'à ce qu'il ne reste aucun élément

B: effectuez une opération BatchGet, en appelant à nouveau delete sur chaque élément jusqu'à ce qu'il n'en reste aucun

Ces deux semblent terribles pour moi car ils vont prendre beaucoup de temps.

Ce que je veux idéalement faire est d'appeler LogTable.DeleteItem (user_id) - sans fournir la plage, et l'avoir tout Supprimer pour moi.

62
demandé sur Cœur 2012-02-06 04:00:22

5 réponses

Ce que je veux idéalement faire est d'appeler LogTable.DeleteItem(id_utilisateur) - Sans fournir la gamme, et l'avoir tout Supprimer pour moi.

Une demande compréhensible en effet; je peux imaginer que des opérations avancées comme celles-ci pourraient être ajoutées au fil du temps par L'équipe AWS (elles ont un historique de départ avec un ensemble de fonctionnalités limité en premier et évaluent les extensions en fonction des commentaires des clients), mais voici ce que vous devez faire pour éviter le coût d'une analyse les moins:

  1. Utilisez Queryplutôt que Scan pour récupérer tous les éléments de user_id - cela fonctionne indépendamment de la clé primaire hash/range combinée utilisée, car HashKeyValueet RangeKeyConditionsont des paramètres distincts dans cette API et le premier ne cible que la valeur D'attribut du composant de hachage de la clé primaire composite..

    • Veuillez noter que vous devrez traiter la pagination de l'API de requête ici comme d'habitude, voir le paramètre ExclusiveStartKey :

      Clé primaire de l'élément à partir duquel poursuivre une requête précédente. Un la requête précédente peut fournir cette valeur en tant que LastEvaluatedKey si cela l'opération de requête a été interrompue avant de terminer la requête; soit parce que la taille ou le paramètre de Limite. Le LastEvaluatedKey peut être renvoyé dans une nouvelle requête requête pour continuer l'opération à partir de ce point.

  2. Boucle sur tout les articles retournés et faciliter DeleteItem, comme d'habitude

    • Update : très probablement BatchWriteItem est plus approprié pour un cas d'utilisation comme celui-ci (voir ci-dessous pour plus de détails).

Mettre à jour

Comme mis en évidence par ivant , L'opérationBatchWriteItem vous permet de placer ou de supprimer plusieurs éléments sur plusieurs tables dans un seul appel D'API [emphasis mine]:

Pour télécharger un élément, vous pouvez utiliser L'API PutItem et en supprimer un élément, vous pouvez utiliser L'API DeleteItem. Toutefois, lorsque vous souhaitez télécharger ou supprimez de grandes quantités de données, telles que le téléchargement données D'Amazon Elastic MapReduce (EMR) ou migrer des données d'un autre base de données dans Amazon DynamoDB, cette API offre un alternative.

Veuillez noter que cela a encore quelques limitations, notamment:

  • Maximum opérations dans une seule requête - vous pouvez spécifier un total de jusqu'à 25 opérations put ou delete; cependant, la taille totale de la requête ne peut pas dépasser 1 Mo (la charge utile HTTP).

  • Pas une opération atomique - les opérations individuelles spécifiées dans un BatchWriteItem sont atomiques; cependant BatchWriteItem dans son ensemble est une opération "best-effort" et non une opération atomique. Autrement dit, dans une requête BatchWriteItem, certaines opérations peuvent réussir et d'autres peuvent échouer. [...]

Néanmoins, cela offre évidemment un gain potentiellement significatif pour des cas d'utilisation comme celui ci.

40
répondu Steffen Opel 2017-05-23 12:02:12

Selon la documentation DynamoDB, vous pouvez simplement supprimer la table complète.

Voir ci-dessous:

"la suppression d'une table entière est nettement plus efficace que la suppression d'éléments un par un, ce qui double essentiellement le débit d'écriture car vous effectuez autant d'opérations de suppression que d'opérations de mise"

Si vous souhaitez supprimer uniquement un sous-ensemble de vos données, vous pouvez créer des tables séparées pour chaque mois, année ou similaire. De cette façon, vous pouvez supprimer "le mois dernier" et garder le reste de vos données intactes.

Voici comment vous supprimez une table en Java à L'aide du SDK AWS:

DeleteTableRequest deleteTableRequest = new DeleteTableRequest()
  .withTableName(tableName);
DeleteTableResult result = client.deleteTable(deleteTableRequest);
36
répondu jonathan 2013-04-15 09:51:06

Si vous voulez supprimer des éléments après un certain temps, par exemple après un mois, utilisez simplement L'option Time To Live. Il va pas compter les unités d'écriture.

Dans votre cas, j'ajouterais ttl lorsque les journaux expirent et les laissent après la suppression d'un utilisateur. TTL s'assurerait que les journaux sont supprimés éventuellement.

Lorsque L'option Time To Live est activée sur une table, une tâche Attribut TTL des éléments pour voir s'ils ont expiré.

DynamoDB supprime généralement les éléments expirés dans 48 heures de expiration. La durée exacte dans laquelle un élément est vraiment supprimé après expiration est spécifique à la nature de la charge de travail et le taille de la table. Les éléments qui ont expiré et qui n'ont pas été supprimés toujours apparaître dans les lectures, les requêtes et les analyses. Ces éléments peuvent encore être mises à jour et mises à jour réussies pour modifier ou supprimer l'expiration l'attribut sera honorer.

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

5
répondu Lukas 2018-06-13 20:59:57

La réponse à cette question dépend du nombre d'éléments et de leur taille et de votre budget. Cela dépend de ce que nous avons 3 cas suivants:

1 - le nombre d'articles et la taille des articles dans le tableau ne sont pas beaucoup. ensuite, comme l'a dit Steffen Opel, vous pouvez utiliser Query plutôt que Scan pour récupérer tous les éléments pour user_id, puis parcourir tous les éléments retournés et faciliter DeleteItem ou BatchWriteItem. Mais gardez à l'esprit que vous pouvez brûler beaucoup de capacité de débit ici. Par exemple, considérez une situation où vous devez supprimer 1000 éléments d'une table DynamoDB. Supposons que chaque élément a une taille de 1 KO, ce qui donne environ 1 Mo de données. Cette tâche de suppression en bloc nécessitera un total de 2000 unités de capacité d'écriture pour query et delete. Pour effectuer cette charge de données dans les 10 secondes (ce qui n'est même pas considéré comme rapide dans certaines applications), vous devez définir le débit d'écriture provisionné de la table sur 200 unités de capacité d'écriture. Comme vous pouvez le voir il est faisable d'utiliser de cette façon si c'est pour moins de nombre de articles ou articles de petite taille.

2-Nous avons beaucoup d'articles ou de très gros articles dans la table et nous pouvons les stocker en fonction du temps dans différentes tables. Alors que jonathan a dit que vous pouvez simplement supprimer la table. c'est beaucoup mieux, mais je ne pense pas que cela corresponde à votre cas. Comme vous voulez supprimer toutes les données des utilisateurs, peu importe le moment de la création des journaux, dans ce cas, vous ne pouvez pas supprimer une table particulière. si vous voulez avoir une table séparée pour chaque utilisateur, alors je suppose que si le nombre des utilisateurs sont élevés alors c'est si cher et ce n'est pas pratique pour votre cas.

3-Si vous avez beaucoup de données et que vous ne pouvez pas diviser vos données chaudes et froides en différentes tables et que vous devez faire des suppressions à grande échelle fréquemment, DynamoDB n'est malheureusement pas une bonne option pour vous. Il peut devenir plus cher ou très lent(dépend de votre budget). Dans ces cas, je recommande de trouver une autre base de données pour vos données.

2
répondu Iman Sedighi 2016-05-26 07:16:47

Nous n'avons pas l'option de tronquer les tables dynamo. nous devons laisser tomber la table et créer à nouveau . DynamoDB Charges est basé sur ReadCapacityUnits & WriteCapacityUnits . Si nous supprimons tous les éléments en utilisant la fonction BatchWriteItem, il utilisera WriteCapacityUnits.So mieux vaut supprimer des enregistrements spécifiques ou supprimer la table et recommencer .

0
répondu kpshrheb 2018-08-02 10:13:56