Fortgeschritten9 Min. Lesezeit

DynamoDB Auto-Scaling einrichten

DynamoDB Auto-Scaling passt die Lese- und Schreibkapazität einer provisionierten Tabelle in Richtung einer Ziel-Auslastung an, die du wählst — damit du RCU/WCU nicht länger von Hand nachjustierst und nicht länger rund um die Uhr für eine Worst-Case-Reservierung bezahlst. Dieser Guide ist die praktische Hälfte der Kapazitätsgeschichte: der Weg über die Konsole, die CLI-Befehle, wie du die Zahlen tatsächlich wählst, und die Timing-Grenzen, die eine scharfe Spitze trotzdem drosseln. Wenn du dich noch nicht auf einen Kapazitätsmodus festgelegt hast, starte bei On-Demand vs. Provisioned Capacity — Auto-Scaling gilt nur für Provisioned.

Wie aktiviere ich Auto-Scaling für eine DynamoDB-Tabelle?

In der Konsole: Öffne deine Tabelle, geh zu Additional settingsRead/write capacityEdit, wähle Provisioned und setze Auto scaling auf On — für die Lesekapazität, die Schreibkapazität oder beides, jeweils mit einem Minimum, einem Maximum und einer Ziel-Auslastung (einstellbar zwischen 20 und 90 Prozent). Über die CLI registrierst du ein skalierbares Ziel und hängst mit aws application-autoscaling eine Zielverfolgungs-Scaling-Policy daran. Über die Konsole erstellte Tabellen haben Auto-Scaling standardmäßig aktiviert.

Was Auto-Scaling tatsächlich tut

Eine Scaling-Policy weist Application Auto Scaling an, das Verhältnis von verbrauchter zu provisionierter Kapazität einer Tabelle nahe deiner Ziel-Auslastung zu halten, innerhalb der minimalen und maximalen Kapazitätsgrenzen, die du festlegst. Unter der Haube legt sie ein Paar CloudWatch-Alarme für die obere und die untere Grenze an; kreuzt der Verbrauch einen davon, setzt Application Auto Scaling einen UpdateTable-Aufruf ab, um die provisionierte Kapazität zu verschieben.

Zwei strukturelle Fakten zählen schon vor dem Einrichten:

  • Policies gelten pro Tabelle und pro GSI. Jeder Global Secondary Index hat seinen eigenen provisionierten Durchsatz, also braucht jeder seine eigene Policy (oder das Kontrollkästchen „same settings for all GSIs“ der Konsole). Ein unterdimensionierter GSI kann Writes der Basistabelle drosseln — siehe warum ein GSI Basistabellen-Writes drosselt.
  • Über die Konsole erstellte Tabellen sind standardmäßig dabei; später hinzugefügte GSIs skalieren während des Aufbaus nicht. Ein neuer GSI auf einer bestehenden Tabelle startet in seinem Backfill mit manueller Kapazität — behalte ihn im Auge, bis die Policy greift.

Das Timing, auf das du dich einlässt

Auto-Scaling ist reaktiv, und seine Reaktionszeiten liegen fest — AWS dokumentiert, dass die Anzahl der Alarm-Datenpunkte nicht anpassbar ist:

  • Das Hochskalieren wird ausgelöst, nachdem die verbrauchte Kapazität das Ziel zwei aufeinanderfolgende Minuten lang überschritten hat (plus bis zu einigen Minuten CloudWatch-Alarmverzögerung).
  • Das Herunterskalieren wartet auf 15 aufeinanderfolgende Ein-Minuten-Datenpunkte unterhalb des Ziels.
  • Nach jedem der beiden Auslöser braucht der UpdateTable-Aufruf mehrere Minuten, bis er greift — und Anfragen oberhalb der alten Obergrenze werden währenddessen gedrosselt.
DynamoDBApplication AutoScalingCloudWatchTrafficDynamoDBApplication AutoScalingCloudWatchTrafficrequests above the old ceiling throttle until the update landsconsumed > target, minute 1consumed > target, minute 2alarm firesUpdateTable (several minutes)

Dieser Boden von ~5 Minuten zwischen Überschreitung und neuer Kapazität ist die ehrliche Grenze des Features: Auto-Scaling fängt Traffic ab, der wächst, nicht Traffic, der springt. Ein Flash Sale, der die Last in einer Minute verdreifacht, wird auf Provisioned Capacity drosseln, egal wie deine Policy aussieht; diese Form verlangt nach On-Demand, das sofort bis zum Doppelten deiner bisherigen Spitze aufnimmt (und jenseits des Doppelten innerhalb von 30 Minuten drosselt — seine eigene Version derselben Physik).

Einrichten in der Konsole

Für eine bestehende Tabelle (AWS-Schritte):

  1. DynamoDB-Konsole → Tables → Tabelle auswählen.
  2. Tab Additional settingsRead/write capacityEdit.
  3. Capacity mode: Provisioned.
  4. Unter Table capacity Auto scaling für Reads, Writes oder beides auf On stellen, dann jeweils Minimum capacity units, Maximum capacity units und Target utilization setzen.
  5. Optional dieselben Einstellungen auf jeden GSI anwenden, dann Save.

Eine Einschränkung der Konsole solltest du kennen: Cooldowns gibt es dort nicht. AWS' eigene Doku verweist dich für „fortgeschrittenere Funktionen wie das Setzen von Scale-in- und Scale-out-Cooldown-Zeiten“ auf die CLI.

Einrichten über die CLI

Zwei Aufrufe pro Dimension: das skalierbare Ziel registrieren (die Min-/Max-Grenzen), dann die Zielverfolgungs-Policy anhängen. Wörtlich aus AWS' CLI-Anleitung, für die Schreibkapazität einer Tabelle:

aws application-autoscaling register-scalable-target \
    --service-namespace dynamodb \
    --resource-id "table/TestTable" \
    --scalable-dimension "dynamodb:table:WriteCapacityUnits" \
    --min-capacity 5 \
    --max-capacity 10

Die Policy-Konfiguration liegt in einer JSON-Datei:

{
  "PredefinedMetricSpecification": {
    "PredefinedMetricType": "DynamoDBWriteCapacityUtilization"
  },
  "ScaleOutCooldown": 60,
  "ScaleInCooldown": 60,
  "TargetValue": 50.0
}
aws application-autoscaling put-scaling-policy \
    --service-namespace dynamodb \
    --resource-id "table/TestTable" \
    --scalable-dimension "dynamodb:table:WriteCapacityUnits" \
    --policy-name "MyScalingPolicy" \
    --policy-type "TargetTrackingScaling" \
    --target-tracking-scaling-policy-configuration file://scaling-policy.json

Für Reads tauschst du die Dimension gegen dynamodb:table:ReadCapacityUnits und die Metrik gegen DynamoDBReadCapacityUtilization. Für einen GSI wird die Resource-ID zu table/TestTable/index/test-index mit den dynamodb:index:*-Dimensionen. Eine Tabelle mit drei GSIs, die beide Dimensionen skaliert, braucht damit acht Ziel-/Policy-Paare — skripte das.

Die beiden Cooldowns stehen bei DynamoDB standardmäßig auf 0 und sind die Stellschrauben, die es nur über die CLI gibt: ScaleOutCooldown ist die Mindestanzahl an Sekunden zwischen Kapazitätserhöhungen (ein größeres Hochskalieren geht trotzdem sofort durch), und ScaleInCooldown blockiert die nächste Senkung — wobei ein Hochskalieren einen laufenden Scale-in-Cooldown unterbricht, statt auf ihn zu warten.

Die Zahlen wählen

Ziel-Auslastung ist ein Regler zwischen Puffer und Kosten. Bei einem Ziel von T Prozent bezahlst du grob das 100/T-Fache deiner verbrauchten Kapazität: Ein 70-%-Ziel kauft ~1,4-mal Puffer über dem stetigen Traffic, ein 50-%-Ziel doppelt so viel. Niedrigere Ziele überstehen schärferes Wachstum ohne Drosselung; höhere Ziele verschwenden weniger Reservierung. Der Bereich ist 20–90 %.

Der Regler hängt direkt an der Rechnung. Nach den aktuellen us-east-1-Raten (dieselbe Herleitung wie Kann DynamoDB automatisch skalieren?): Provisionierte Kapazität ist bei 100 % Auslastung pro Anfrage ~3,46-mal günstiger als On-Demand, und der Break-even liegt bei ~29 % Auslastung. Die Aufgabe von Auto-Scaling ist es, die echte Auslastung nahe deinem Ziel zu halten — das Ziel wählt also faktisch deinen Rabatt: bei gehaltenen 70 % läuft Provisioned ~2,4-mal günstiger als On-Demand, bei 50 % ~1,7-mal; unterhalb von ~29 % solltest du stattdessen auf On-Demand sein. Prüfe die Zahlen deines eigenen Workloads im Preisrechner.

Minimale Kapazität ist dein Boden für Spitzen: die Kapazität, die während der ~5 Minuten, die Auto-Scaling zum Reagieren braucht, schon da ist. Leite sie vom schärfsten Burst ab, den du ohne Drosselung auffangen musst, nicht vom durchschnittlichen Traffic.

Maximale Kapazität ist der Schutz vor Ausreißern — die Obergrenze dessen, was ein Bug, eine heiße Lambda-Schleife oder ein Lasttest dir in Rechnung stellen kann. Setze sie über deine realistische Spitze und behandle es als Alarm, wenn sie erreicht wird, nicht als Normalbetrieb.

Das Herunterskalieren ist kontingentbegrenzt. Senkungen der provisionierten Kapazität kommen aus einem Token-Bucket: Du startest jeden UTC-Tag mit 4 verfügbaren, eine weitere kommt pro Stunde hinzu (maximal 4 gehalten), für höchstens 27 Senkungen pro Tabelle und Tag — GSI-Limits sind davon getrennt, aber eine einzelne Anfrage, die Tabelle und Index gemeinsam senkt, wird komplett zurückgewiesen, wenn einer der beiden Seiten das Kontingent fehlt. Auto-Scalings konservatives 15-Minuten-Herunterskalieren respektiert das in der Praxis ohnehin, aber es ist der Grund, warum die Kapazität nach einer Spitze nur langsam zurückgeht — und warum schwankender Traffic den Tag höher beendet als seinen Durchschnitt.

In DynoTable umsetzen

Das Minimum zu dimensionieren und das Ziel zu validieren startet beides bei echten Zahlen, nicht bei Schätzungen: wie groß die Items sind, wie viele es sind und was ein repräsentativer Lese- oder Schreibvorgang tatsächlich verbraucht. DynoTables Tabellenansicht zeigt die aktuelle Item-Anzahl und Tabellengröße, und die Kostenvorschau für Queries zeigt die RCU-Schätzung eines Statements, bevor es läuft — genau die Zahlen, aus denen ein Kapazitätsplan gemacht ist. Um ein einzelnes Item zu dimensionieren, berechnet der kostenlose Item-Größen-Rechner seinen RCU/WCU-Fußabdruck.

Fallstricke und nächste Schritte

  • Auto-Scaling schlägt die Physik pro Partition nicht. Ein heißer Schlüssel drosselt selbst dann, wenn Kapazität übrig ist — siehe Hot Partitions und Adaptive Capacity.
  • Vergiss die GSIs nicht. Jeder Index skaliert (oder drosselt) für sich.
  • Reserved Capacity stapelt sich nur auf Provisioned. Wenn ein Workload stetig genug ist, dass Auto-Scaling kaum etwas bewegt, ist Reserved Capacity (nur Standard-Tabellenklasse, nur Provisioned-Modus) der nächste Rabatt — Tabellen im On-Demand-Modus können sie nicht nutzen.
  • Beobachte den ersten Tag. ConsumedReadCapacityUnits / ConsumedWriteCapacityUnits gegen die provisionierte Linie in CloudWatch sagt dir schnell, ob das Ziel hält oder schwingt.

Kapazität ist eine Achse des Kostenmodells; was deine Queries verbrauchen, ist die andere — Scan vs. Query und das SQL-Scan-Kostenmodell decken diese Hälfte ab.

Lade DynoTable herunter, um die echte Größe, Item-Anzahl und Kosten pro Query deiner Tabelle zu lesen, bevor du Kapazitätszahlen darauf festlegst.

Aktualisiert