it-swarm-eu.dev

Was ist die empfohlene Methode, um eine große Anzahl von Elementen aus DynamoDB zu löschen?

Ich schreibe einen einfachen Protokollierungsdienst in DynamoDB.

Ich habe eine Protokolltabelle, die von einem user_id-Hash und einem Zeitstempelbereich (Unix Epoch int) eingegeben wird.

Wenn ein Benutzer des Dienstes sein Konto kündigt, muss ich alle Elemente in der Tabelle unabhängig vom Bereichswert löschen.

Was ist der empfohlene Weg, um diese Art von Vorgang durchzuführen (unter Berücksichtigung von Millionen von zu löschenden Objekten)?

Meine Möglichkeiten, soweit ich sehen kann, sind:

A: Führen Sie einen Scanvorgang aus, und rufen Sie bei jedem zurückgegebenen Artikel den Befehl delete auf, bis keine Objekte mehr vorhanden sind

B: Führen Sie einen BatchGet-Vorgang aus, und rufen Sie erneut delete für jedes Element auf, bis keine mehr vorhanden sind

Beide sehen fürchterlich aus, da sie lange dauern werden.

Im Idealfall möchte ich LogTable.DeleteItem (user_id) aufrufen - ohne den Bereich anzugeben, und habe es für mich alles zu löschen.

70
Tyler

Ich möchte im Idealfall LogTable.DeleteItem (user_id) aufrufen, ohne den Bereich anzugeben, und alles für mich löschen lassen.

Eine verständliche Bitte; Ich kann mir vorstellen, dass das AWS-Team mit der Zeit fortgeschrittene Operationen wie diese hinzufügt (sie haben in der Vergangenheit mit einem eingeschränkten Funktionsumfang begonnen und Erweiterungen basierend auf Kundenfeedback bewertet), aber Sie sollten Folgendes tun, um die Kosten für zu vermeiden mindestens ein vollständiger Scan:

  1. Verwenden Sie Abfrage anstelle von Scan , um alle Elemente für user_id abzurufen. Dies funktioniert unabhängig vom verwendeten kombinierten Hash/Range-Primärschlüssel, da HashKeyValue und RangeKeyCondition sind separate Parameter in dieser API und die erstere zielt nur auf den Attributwert der Hash-Komponente des Verbunds ab Primärschlüssel..

    • Beachten Sie, dass Sie sich hier wie gewohnt mit dem Paging der Abfrage-API befassen müssen (siehe Parameter ExclusiveStartKey :

      Primärschlüssel des Elements, von dem aus eine frühere Abfrage fortgesetzt werden soll. Eine frühere Abfrage kann diesen Wert als LastEvaluatedKey bereitstellen, wenn dieser Abfragevorgang vor Abschluss der Abfrage unterbrochen wurde. entweder aufgrund der Größe der Ergebnismenge oder des Parameters Limit. Der LastEvaluatedKey kann in einer neuen Abfrageanforderung zurückgegeben werden, um den Vorgang ab diesem Zeitpunkt fortzusetzen.

  2. Durchlaufen Sie alle zurückgegebenen Artikel und aktivieren Sie DeleteItem wie gewohnt

    • pdate: Höchstwahrscheinlich BatchWriteItem ist für einen Anwendungsfall wie diesen besser geeignet (Einzelheiten siehe unten).

Aktualisieren

Wie durch ivant hervorgehoben, können Sie mit der Operation BatchWriteItemoder löschen mehrere Elemente über mehrere Tabellen in eine einzige einfügen API-Aufruf [Hervorhebung von mir] :

Um ein Element hochzuladen, können Sie die PutItem-API verwenden, und um ein Element zu löschen, können Sie die DeleteItem-API verwenden. Wenn Sie jedoch große Datenmengen hochladen oder löschen möchten, z. B. große Datenmengen von Amazon Elastic MapReduce (EMR) hochladen oder Daten aus einer anderen Datenbank in Amazon DynamoDB migrieren möchten, bietet diese API eine effiziente Alternative.

Bitte beachten Sie, dass dies immer noch einige relevante Einschränkungen aufweist, insbesondere:

  • Maximale Operationen in einer einzelnen Anforderung - Sie können insgesamt bis zu 25 Put- oder Delete-Operationen angeben. Die Gesamtanforderungsgröße darf jedoch 1 MB (die HTTP-Nutzlast) nicht überschreiten.

  • Keine atomare Operation - Einzelne in einem BatchWriteItem angegebene Operationen sind atomar. BatchWriteItem als Ganzes ist jedoch eine "Best-Effort" -Operation und keine atomare Operation. Das heißt, dass in einer BatchWriteItem-Anforderung einige Vorgänge möglicherweise erfolgreich sind und andere fehlschlagen. [...]

Dennoch bietet dies offensichtlich einen potenziell signifikanten Gewinn für Anwendungsfälle wie den vorliegenden.

45
Steffen Opel

Entsprechend der DynamoDB-Dokumentation können Sie einfach die vollständige Tabelle löschen.

Siehe unten:

"Das Löschen einer gesamten Tabelle ist wesentlich effizienter als das Entfernen von Elementen nacheinander, wodurch der Schreibdurchsatz verdoppelt wird, da Sie so viele Löschvorgänge wie Put-Vorgänge ausführen."

Wenn Sie nur einen Teil Ihrer Daten löschen möchten, können Sie für jeden Monat, jedes Jahr oder ähnliches separate Tabellen erstellen. Auf diese Weise können Sie "letzten Monat" entfernen und den Rest Ihrer Daten beibehalten.

So löschen Sie eine Tabelle in Java mit dem AWS SDK:

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

Wenn Sie Elemente nach einiger Zeit löschen möchten, z. Verwenden Sie nach einem Monat einfach die Option Time To Live. Es zählt not Schreibeinheiten.

In Ihrem Fall würde ich ttl hinzufügen, wenn die Protokolle ablaufen, und diese nach dem Löschen eines Benutzers belassen. TTL würde sicherstellen, dass eventuell Protokolle entfernt werden.

Wenn Time To Live für eine Tabelle aktiviert ist, prüft ein Hintergrundjob die TTL - Attribut der Elemente, um zu sehen, ob sie abgelaufen sind.

DynamoDB löscht abgelaufene Elemente normalerweise innerhalb von 48 Stunden nach Ablauf. Die genaue Dauer, in der ein Element wirklich gelöscht wird nach dem Ablauf ist abhängig von der Art der Arbeitslast und der Größe der Tabelle. Elemente, die abgelaufen sind und nicht gelöscht wurden, werden wird immer noch in Lesevorgängen, Abfragen und Scans angezeigt. Diese Elemente können immer noch .__ sein. Aktualisierte und erfolgreiche Aktualisierungen zum Ändern oder Entfernen des Ablaufs Attribut wird geehrt.

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

6
Lukas

Die Antwort auf diese Frage hängt von der Anzahl der Elemente und deren Größe und Ihrem Budget ab. Abhängig davon haben wir folgende 3 Fälle:

1- Die Anzahl der Elemente und die Größe der Elemente in der Tabelle sind nicht sehr groß. Dann, wie Steffen Opel sagte, können Sie Query anstelle von Scan verwenden, um alle Elemente für user_id abzurufen und dann alle zurückgegebenen Elemente zu durchlaufen und entweder DeleteItem oder BatchWriteItem zu ermöglichen. Denken Sie jedoch daran, dass hier viel Durchsatzkapazität verbrannt wird. Stellen Sie sich beispielsweise eine Situation vor, in der Sie 1000 Elemente aus einer DynamoDB-Tabelle löschen müssen. Nehmen Sie an, dass jedes Element eine Größe von 1 KB hat, was ungefähr 1 MB an Daten ergibt. Für diesen Massenlöschvorgang sind insgesamt 2000 Schreibkapazitätseinheiten für die Abfrage und das Löschen erforderlich. Um diesen Datenladevorgang innerhalb von 10 Sekunden durchzuführen (was in manchen Anwendungen sogar als nicht so schnell betrachtet wird), müssen Sie den bereitgestellten Schreibdurchsatz der Tabelle auf 200 Schreibkapazitätseinheiten einstellen. Wie Sie sehen können, ist es möglich, auf diese Weise zu verwenden, wenn die Anzahl der Objekte oder die Größe kleinerer Objekte geringer ist.

2- Wir haben viele Artikel oder sehr große Artikel in der Tabelle und können diese nach Zeit in verschiedenen Tabellen speichern. Dann können Sie als Jonathan Said die Tabelle löschen. Das ist viel besser, aber ich denke nicht, dass es mit Ihrem Fall übereinstimmt. Da Sie alle Benutzerdaten unabhängig vom Zeitpunkt der Erstellung der Protokolle löschen möchten, können Sie in diesem Fall eine bestimmte Tabelle nicht löschen. Wenn Sie für jeden Benutzer eine eigene Tabelle haben möchten, denke ich, wenn die Anzahl der Benutzer hoch ist, dann ist es so teuer und es ist für Ihren Fall nicht praktikabel.

3- Wenn Sie über viele Daten verfügen und Ihre heißen und kalten Daten nicht in verschiedene Tabellen aufteilen können und Sie häufig umfangreiche Löschvorgänge durchführen müssen, ist DynamoDB leider keine gute Option für Sie. Es kann teurer oder sehr langsam werden (abhängig von Ihrem Budget). In diesen Fällen empfehle ich Ihnen, eine andere Datenbank für Ihre Daten zu suchen.

2
Iman Sedighi

Wir haben keine Möglichkeit, Dynamotabellen abzuschneiden. Wir müssen die Tabelle löschen und erneut erstellen. DynamoDB-Gebühren basieren auf ReadCapacityUnits und WriteCapacityUnits. Wenn wir alle Elemente mit der BatchWriteItem-Funktion löschen, wird WriteCapacityUnits verwendet. Es empfiehlt sich, bestimmte Datensätze zu löschen oder die Tabelle zu löschen und erneut zu beginnen.

0
Shraavan Hebbar

Mein Ansatz zum Löschen aller Zeilen aus einer Tabelle in DynamoDb besteht darin, alle Zeilen mit DynamoDbs ScanAsync aus der Tabelle zu ziehen und die Ergebnisliste anschließend an DynamoDbs AddDeleteItems zu übergeben. Der folgende Code in C # funktioniert für mich gut.

        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();
    }

Hinweis: Das Löschen der Tabelle und das erneute Erstellen der Tabelle in der Webkonsole kann zu Problemen führen, wenn Sie YAML/CloudFront zum Erstellen der Tabelle verwenden. 

0
Mohammad