

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Verwenden globaler sekundärer Indizes für materialisierte Aggregationsabfragen in DynamoDB
<a name="bp-gsi-aggregation"></a>

Die Wartung von Aggregationen, die beinahe in Echtzeit ausgeführt werden, und Schlüsselmetriken für Daten, die sich schnell verändern, wird zunehmend wichtiger für Unternehmen, um schnell Entscheidungen treffen zu können. Beispielsweise möchte eine Musikbibliothek möglicherweise ihre am häufigsten heruntergeladenen Songs nahezu in Echtzeit präsentieren, oder eine E-Commerce-Plattform muss möglicherweise Trendprodukte nach Kategorien anzeigen.

Da DynamoDB Aggregationsoperationen wie `SUM` oder `COUNT` zwischen Elementen nicht nativ unterstützt, würde die Berechnung dieser Werte zur Lesezeit das Scannen einer großen Anzahl von Elementen erfordern — was langsam und teuer sein kann. Stattdessen können Sie * Aggregationen bei Datenänderungen * vorab berechnen und die Ergebnisse als reguläre Elemente in Ihrer Tabelle speichern. Dieses Muster wird als * materialisierte Aggregation bezeichnet. *

**Topics**
+ [Beispielszenario und Zugriffsmuster](#bp-gsi-aggregation-scenario)
+ [Warum Aggregationen vorab berechnen](#bp-gsi-aggregation-why)
+ [Tabellendesign](#bp-gsi-aggregation-table-design)
+ [Aggregationspipeline mit Streams und AWS Lambda](#bp-gsi-aggregation-pipeline)
+ [GSI-Design mit geringer Dichte](#bp-gsi-aggregation-sparse-gsi)
+ [Das GSI abfragen](#bp-gsi-aggregation-querying)
+ [Überlegungen](#bp-gsi-aggregation-considerations)

## Beispielszenario und Zugriffsmuster
<a name="bp-gsi-aggregation-scenario"></a>

Stellen Sie sich eine Musikbibliotheksanwendung mit den folgenden Anforderungen vor:
+ Die Anwendung zeichnet einzelne Lieddownloads mit hoher Lautstärke auf (Tausende pro Sekunde).
+ Benutzer müssen die am häufigsten heruntergeladenen Songs eines bestimmten Monats mit einer Latenz im einstelligen Millisekundenbereich sehen.
+ Die Anwendung muss auch Abfragen wie „Die 10 besten Songs dieses Monats“ und „Alle Songs, die in einem bestimmten Monat heruntergeladen wurden“ unterstützen.

Die Berechnung der Downloadzahlen zum Lesezeitpunkt durch Scannen aller Download-Datensätze kann bei dieser Größenordnung teuer sein. Stattdessen können Sie eine fortlaufende Zählung verwalten, die bei jedem Download aktualisiert wird, und sie so speichern, dass effiziente Abfragen unterstützt werden.

## Warum Aggregationen vorab berechnen
<a name="bp-gsi-aggregation-why"></a>

Es gibt mehrere Ansätze zur Berechnung von Aggregationen. In der folgenden Tabelle werden gängige Alternativen verglichen und erklärt, warum die materialisierte Aggregation in DynamoDB für diese Art von Anwendungsfall oft am besten geeignet ist.


| Ansatz | Kompromisse | Wann sollte dies verwendet werden? | 
| --- | --- | --- | 
| Scannen und zählen Sie zur Lesezeit | Erfordert das Lesen aller Download-Datensätze für jede Abfrage. Die Latenz wächst mit dem Datenvolumen und verbraucht erhebliche Lesekapazität. | Nur für sehr kleine Datensätze geeignet, bei denen Latenz kein Problem darstellt. | 
| Externer Aggregationsspeicher (z. B. Amazon) ElastiCache | Erhöht die betriebliche Komplexität durch einen separaten Service, der verwaltet werden muss. Erfordert eine Synchronisationslogik zwischen DynamoDB und dem Cache. | Wenn Sie Lesevorgänge unter einer Millisekunde oder eine komplexe Aggregationslogik benötigen, die über einfache Zählungen hinausgeht. | 
| Application-level Aggregation beim Schreiben | Koppelt die Aggregationslogik mit dem Schreibpfad. Wenn die Anwendung nach der Aufzeichnung des Downloads, aber vor der Aktualisierung der Anzahl fehlschlägt, wird die Aggregation inkonsistent. | Wenn Sie eine synchrone, stark konsistente Aggregation benötigen und zusätzliche Schreiblatenz tolerieren können. | 
| Materialisierte Aggregation mit Streams und Lambda  | Entkoppelt die Aggregation vom Schreibpfad. Die Aggregation ist letztendlich konsistent (in der Regel Sekunden im Rückstand). Fügt die Kosten für Lambda-Aufrufe hinzu. | Wenn Sie Aggregationen nahezu in Echtzeit mit niedriger Leselatenz benötigen und eventuelle Konsistenzen tolerieren können.  Dies ist der auf dieser Seite beschriebene Ansatz. | 

Der materialisierte Aggregationsansatz hält den Schreibpfad einfach (zeichnen Sie einfach den Download auf), verlagert die Aggregation in einen asynchronen Prozess und speichert das Ergebnis in DynamoDB, wo es mit einer Latenz im einstelligen Millisekundenbereich abgefragt werden kann.

## Tabellendesign
<a name="bp-gsi-aggregation-table-design"></a>

Dieses Design verwendet eine einzelne Tabelle mit zwei Elementtypen, die denselben Partitionsschlüssel () verwenden, aber unterschiedliche Sortierschlüsselmuster verwenden, um zwischen ihnen zu unterscheiden: `songID`
+ **Datensätze herunterladen ** — Einzelne Download-Ereignisse. Der Sortierschlüssel ist der `DownloadID` (eine eindeutige Kennung für jeden Download).
+ **Monatliche Aggregationselemente ** — Anzahl der Pre-computed Downloads pro Song pro Monat. Der Sortierschlüssel ist der Monat im `YYYY-MM` Format (z. B.`2018-01`). Diese Elemente enthalten auch ein `DownloadCount` Attribut mit der laufenden Summe.

Nur die monatlichen Aggregationselemente enthalten das `Month` Attribut. Diese Unterscheidung ist wichtig für das GSI-Design mit geringer Dichte, das später beschrieben wird.

Das folgende Diagramm zeigt das Tabellenlayout mit beiden Elementtypen:

![Tabellenlayout der Musikbibliothek mit Download-Datensätzen und monatlichen Aggregationselementen, die denselben Partitionsschlüssel (SongID) verwenden.](http://docs.aws.amazon.com/de_de/amazondynamodb/latest/developerguide/images/AggregationQueries.png)



| Elementart | Partitionsschlüssel (SongID) | Sortierschlüssel | Zusätzliche Attribute | 
| --- | --- | --- | --- | 
| Datensatz herunterladen | song1 | download-abc123 | UserID, Timestamp | 
| Monatliche Aggregation | song1 | 2018-01 | Month=2018-01, DownloadCount=1,746,992 | 

## Aggregationspipeline mit Streams und AWS Lambda
<a name="bp-gsi-aggregation-pipeline"></a>

Die Aggregationspipeline funktioniert wie folgt:

1. Wenn ein Song heruntergeladen wird, schreibt die Anwendung mit `Partition-Key=songID` und `Sort-Key=DownloadID` ein neues Objekt in die Tabelle.

1. DynamoDB Streams erfasst diesen Schreibvorgang als Stream-Datensatz.

1. Eine Lambda-Funktion, die an den Stream angehängt ist, verarbeitet den neuen Datensatz. Es identifiziert den `songID` und den aktuellen Monat und aktualisiert dann das entsprechende monatliche Aggregationselement, indem das `DownloadCount` Attribut erhöht wird.

1. Das aktualisierte Aggregationselement ist dann für Abfragen über das überschaubare GSI verfügbar.

Die Lambda-Funktion verwendet einen `UpdateItem` Aufruf mit einem `ADD` Ausdruck, um die Anzahl der Downloads atomar zu erhöhen. Dadurch werden Rennbedingungen wie Lesen, Ändern und Schreiben vermieden:

```
import boto3

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('MusicLibrary')

def handler(event, context):
    for record in event['Records']:
        if record['eventName'] == 'INSERT':
            new_image = record['dynamodb']['NewImage']
            song_id = new_image['songID']['S']
            # Derive the month from the download timestamp
            timestamp = new_image['Timestamp']['S']
            month = timestamp[:7]  # Extract YYYY-MM

            table.update_item(
                Key={
                    'songID': song_id,
                    'SK': month
                },
                UpdateExpression='ADD DownloadCount :inc SET #m = :month',
                ExpressionAttributeNames={
                    '#m': 'Month'
                },
                ExpressionAttributeValues={
                    ':inc': 1,
                    ':month': month
                }
            )
```

**Anmerkung**  
Wenn eine Lambda-Ausführung nach dem Schreiben des aktualisierten Aggregationswerts fehlschlägt, kann der Stream-Datensatz erneut versucht werden. Da der `ADD` Vorgang die Anzahl bei jeder Ausführung erhöht, würde ein erneuter Versuch die Anzahl für denselben Download mehrmals erhöhen, sodass Sie einen ungefähren Wert erhalten. * * Für die meisten Anwendungsfälle in den Bereichen Analytik und Bestenlisten ist diese geringe Fehlerquote akzeptabel. Wenn Sie genaue Zählungen benötigen, sollten Sie erwägen, eine Idempotenzlogik hinzuzufügen. Verwenden Sie beispielsweise einen Bedingungsausdruck, der überprüft, ob die Spezifik bereits verarbeitet wurde. `DownloadID`

## GSI-Design mit geringer Dichte
<a name="bp-gsi-aggregation-sparse-gsi"></a>

Um die aggregierten Ergebnisse effizient abzufragen, erstellen Sie einen globalen sekundären Index mit dem folgenden Schlüsselschema:
+ **GSI-Partitionsschlüssel: ** `Month` (Zeichenfolge)
+ **GSI-Sortierschlüssel: ** `DownloadCount` (Zahl)

Dieser GSI ist * spärlich, * da nur die monatlichen Aggregationselemente das Attribut enthalten. `Month` Die einzelnen Download-Datensätze haben dieses Attribut nicht und werden daher automatisch aus dem Index ausgeschlossen. Das bedeutet, dass der GSI nur die vorberechneten Aggregationselemente enthält — einen kleinen Bruchteil der gesamten Elemente in der Tabelle.

Ein überschaubarer GSI bietet zwei wichtige Vorteile:
+ **Niedrigere Kosten ** — Da nur Aggregationselemente in den Index repliziert werden, verbrauchen Sie im Vergleich zu einem Index, der jedes Element in der Tabelle enthält, weitaus weniger Schreibkapazität und Speicherplatz.
+ **Schnellere Abfragen ** — Der Index enthält nur die Daten, die Sie für die Abfrage benötigen, sodass Lesevorgänge effizient sind und Ergebnisse mit einer Latenz im einstelligen Millisekundenbereich zurückgegeben werden.

Weitere Hinweise zur Funktionsweise von Indizes mit geringer Dichte finden Sie unter. [Verwendung von Sparse Indexes](bp-indexes-general-sparse-indexes.md)

## Das GSI abfragen
<a name="bp-gsi-aggregation-querying"></a>

Mit dem überschaubaren GSI können Sie mehrere Arten von Abfragen effizient beantworten:

**Holen Sie sich den Song, der in einem bestimmten Monat am häufigsten heruntergeladen wurde: **

```
aws dynamodb query \
    --table-name "MusicLibrary" \
    --index-name "MonthDownloadsIndex" \
    --key-condition-expression "#m = :month" \
    --expression-attribute-names '{"#m": "Month"}' \
    --expression-attribute-values '{":month": {"S": "2018-01"}}' \
    --scan-index-forward false \
    --limit 1
```

Bei Einstellung `ScanIndexForward` auf `false` werden die Ergebnisse `DownloadCount` in absteigender Reihenfolge sortiert und nur der beste Song `Limit=1` zurückgegeben.

**Ruft die 10 besten Songs eines bestimmten Monats ab: **

```
aws dynamodb query \
    --table-name "MusicLibrary" \
    --index-name "MonthDownloadsIndex" \
    --key-condition-expression "#m = :month" \
    --expression-attribute-names '{"#m": "Month"}' \
    --expression-attribute-values '{":month": {"S": "2018-01"}}' \
    --scan-index-forward false \
    --limit 10
```

**Ruft alle Songs ab, die in einem bestimmten Monat heruntergeladen wurden ** (sortiert nach Anzahl der Downloads):

```
aws dynamodb query \
    --table-name "MusicLibrary" \
    --index-name "MonthDownloadsIndex" \
    --key-condition-expression "#m = :month" \
    --expression-attribute-names '{"#m": "Month"}' \
    --expression-attribute-values '{":month": {"S": "2018-01"}}' \
    --scan-index-forward false
```

## Überlegungen
<a name="bp-gsi-aggregation-considerations"></a>

Beachten Sie bei der Implementierung dieses Musters Folgendes:
+ **Eventuelle Konsistenz ** — Die Aggregationswerte werden asynchron über DynamoDB Streams und Lambda aktualisiert. In der Regel gibt es eine Verzögerung von einigen Sekunden zwischen der Aufzeichnung eines Downloads und der Aktualisierung der Aggregation. Das bedeutet, dass das GSI Daten nahezu in Echtzeit wiedergibt, keine Echtzeitdaten.
+ **Lambda-Parallelität ** — Wenn Ihre Tabelle ein hohes Schreibvolumen hat, versuchen möglicherweise mehrere Lambda-Aufrufe, dasselbe Aggregationselement gleichzeitig zu aktualisieren. Die atomare `ADD` Operation verarbeitet dies sicher, aber Sie sollten die Lambda-Metriken für Parallelität und Drosselung überwachen, um sicherzustellen, dass Ihre Funktion mit dem Stream Schritt halten kann.
+ **GSI-Schreibkapazität ** — Da die GSI mit geringer Dichte nur Aggregationselemente enthält, benötigt sie deutlich weniger Schreibkapazität als die Basistabelle. Sie sollten jedoch trotzdem genügend Kapazität bereitstellen (oder den On-Demand-Modus verwenden), um die Geschwindigkeit der Aggregationsupdates bewältigen zu können.
+ **Ungefähre Anzahl ** — Wie bereits erwähnt, können Lambda-Wiederholungsversuche dazu führen, dass die Anzahl leicht überzählt wird. Implementieren Sie für Anwendungsfälle, die genaue Zählungen erfordern, Idempotenzprüfungen in der Lambda-Funktion.