GH GambleHub

Idempotenz und Schlüssel

Was ist Idempotenz

Idempotenz ist eine Eigenschaft einer Operation, bei der eine Wiederholung mit derselben ID den endgültigen Effekt nicht ändert. In verteilten Systemen ist dies der primäre Weg, um das Ergebnis trotz Retrays, doppelten Nachrichten und Timeouts „genau einer Verarbeitung“ gleichzusetzen.

Die Grundidee: Jede potenziell wiederholbare Operation muss mit einem Schlüssel gekennzeichnet werden, an dem das System erkennt, dass „es bereits getan wurde“ und das Ergebnis nicht mehr als einmal anwendet.

Wo es wichtig ist

Zahlungen und Salden: Abbuchungen/Gutschriften unter 'operation _ id'.
Buchungen/Kontingente/Limits: das gleiche Slot/Ressource.
Webhooks/Benachrichtigungen: Die wiederholte Lieferung sollte den Effekt nicht duplizieren.
Import/Migrationen: Dateien/Pakete erneut ausführen.
Stream-Processing: Takes vom Broker/CDC.

Schlüsseltypen und deren Umfang

1. Betriebsschlüssel - ID eines bestimmten Geschäftsvorgangsversuchs

Beispiele: 'idempotency _ key' (HTTP), 'operation _ id' (RPC).
Bereich: Service/Aggregat; in der Deduplizierungstabelle gespeichert.

2. Event key - eindeutige ID des Ereignisses/der Nachricht

Beispiele: 'event _ id' (UUID),'(producer_id, sequence)'.
Bereich: Verbraucher/Verbrauchergruppe; schützt die Projektionen.

3. Geschäftsschlüssel - der natürliche Schlüssel des Fachgebiets

Beispiele: „payment _ id“, „invoice _ number“, „(user_id, Tag)“.
Bereich: Aggregat; wird in Eindeutigkeits-/Versionsprüfungen angewendet.

💡 Häufig zusammen verwendet: 'operation _ id' schützt den Befehl, 'event _ id' die Lieferung, 'business key' die Invarianten des Aggregats.

TTL und Aufbewahrungsrichtlinie

TTL-Schlüssel ≥ mögliches Wiederholungsfenster: Log-Retention + Netzwerk-/Prozessverzögerungen.
Für kritische Domains (Zahlungen) TTL - Tage/Wochen; für Telemetrie - Stunden.
Reinigen Sie die Dedup-Tabellen mit Background-Jobs; für Audit - Archivieren.

Schlüsselspeicher (Deduplizierung)

Transaktions-DB (empfohlen): zuverlässige Upsert/Unique-Indizes, gemeinsame Transaktion mit Wirkung.
KV/Redis: schnell, bequem für kurze TTL, aber ohne gemeinsame Transaktion mit OLTP - Vorsicht.
State Store des Stream-Prozessors: lokal + Changelog im Broker; gut in Flink/KStreams.

Schema (Variante im DB):
  • idempotency_keys

`consumer_id` (или `service`), `op_id` (PK на пару), `applied_at`, `ttl_expires_at`, `result_hash`/`response_status` (опц.) .

Indizes:'(consumer_id, op_id)'- einzigartig.

Grundlegende Implementierungstechniken

1) Effekt + Fortschritt Transaktion

Erfassung des Ergebnisses und Erfassung des Lese-/Positionsfortschritts - in einer Transaktion.

pseudo begin tx if not exists(select 1 from idempotency_keys where consumer=:c and op_id=:id) then
-- apply effect atomically (upsert/merge/increment)
apply_effect(...)
insert into idempotency_keys(consumer, op_id, applied_at)
values(:c,:id, now)
end if
-- record reading progress (offset/position)
upsert offsets set pos=:pos where consumer=:c commit

2) Optimistic Concurrency (Aggregatversion)

Schützt vor Doppelwirkung bei Rennen:
sql update account set balance = balance +:delta,
version = version + 1 where id=:account_id and version=:expected_version;
-- if 0 rows are updated → retry/conflict

3) Idempotente sinks (upsert/merge)

Einmal aufladen:
sql insert into bonuses(user_id, op_id, amount)
values(:u,:op,:amt)
on conflict (user_id, op_id) do nothing;

Idempotenz in Protokollen

HTTP/REST

Überschrift „Idempotency-Key: <uuid 'hash>“.
Der Server speichert einen Schlüsseleintrag und gibt dieselbe Antwort (oder Code' 409 '/' 422 'bei Invarianzkonflikt) zurück.
Für „unsichere“ POSTs ist ein 'Idempotency-Key' + nachhaltiger Timeout/Retray-Policy Pflicht.

gRPC/RPC

Metadaten 'idempotency _ key', 'request _ id' + deadline.
Server-Implementierung - wie in REST: Deduplizierungstabelle in einer Transaktion.

Broker/Streaming (Kafka/NATS/Pulsar)

Produzent: stabiler 'event _ id '/idempotenter Produzent (wo unterstützt).
Consumer: Dedup durch'(consumer_id, event_id) 'und/oder durch die Geschäftsversion der Einheit.
Separater DLQ für nicht-idempotente/beschädigte Nachrichten.

Webhooks und externe Partner

Fordern Sie' Idempotency-Key '/' event _ id 'im Vertrag an; Nachlieferung muss sicher sein.
Speichern Sie' notification _ id 'und Sendestatus; Bei Retrae - nicht duplizieren.

Schlüsselentwurf

Determinität: Retrays müssen denselben Schlüssel senden (im Voraus auf dem Client/Orchestrator generieren).
Bereich: Form 'op _ id' als' service: aggregate: id: purpose'.
Kollisionen: Verwenden Sie UUIDv7/ULID oder Hash von Geschäftsparametern (bei Bedarf mit Salz).
Hierarchie: Die allgemeine „operation _ id“ an der Front wird → in alle Unteroperationen übersetzt (idempotente Kette).

UX und Produktaspekte

Eine wiederholte Schlüsselabfrage sollte das gleiche Ergebnis (einschließlich Körper/Status) oder ein explizites „bereits erfüllt“ zurückgeben.
Zeigen Sie dem Benutzer den Status „Vorgang wird bearbeitet/abgeschlossen“ an, anstatt erneut „auf Glück“ zu versuchen.
Für lange Operationen - Polling nach Schlüssel ('GET/operations/{ op _ id}').

Beobachtbarkeit

Loggen Sie' op _ id', 'event _ id', 'trace _ id', Ergebnis: 'APPLIED '/' ALREADY _ APPLIED'.
Metriken: Wiederholungsrate, Größe der Dedup-Tabellen, Transaktionszeiten, Versionskonflikte, DLQ-Rate.
Trace: Der Schlüssel muss durch ein Team → ein Ereignis → eine Projektion → eine externe Herausforderung gehen.

Sicherheit und Compliance

Speichern Sie PII nicht in Schlüsseln; key - ID, nicht payload.
Verschlüsseln Sie sensible Felder in Deduplizierungsdatensätzen mit langer TTL.
Aufbewahrungspolitik: TTL und Archive; Recht auf Vergessenwerden - durch Krypto-Löschung von Antworten/Metadaten (wenn sie PII enthalten).

Testen

1. Duplikate: Führen Sie eine einzelne Nachricht/Anfrage 2-5 Mal durch - der Effekt ist genau einer.
2. Tropfen zwischen den Schritten: vor/nach der Aufzeichnung des Effekts, vor/nach der Fixierung des Offsets.
3. Neustart/Rebalance der Verbraucher: keine doppelte Anwendung.
4. Wettbewerb: Parallele Abfragen mit einem 'op _ id' → einen Effekt, der zweite ist 'ALREADY _ APPLIED/409'.
5. Langlebige Schlüssel: Überprüfen Sie den Ablauf von TTL und Wiederholungen nach der Wiederherstellung.

Antimuster

Zufälliger neuer Schlüssel für jeden Rückzug: Das System erkennt keine Wiederholungen.
Zwei separate Commits: zuerst der Effekt, dann der Offset - der Fall zwischen ihnen dupliziert den Effekt.
Vertrauen Sie nur dem Broker: Kein Deduplex im Sync/Aggregat.
Keine Aggregatversion: Ein wiederholtes Ereignis ändert den Zustand ein zweites Mal.
Fat Keys: Der Schlüssel umfasst Geschäftsfelder/PII → Lecks und komplexe Indizes.
Keine wiederholbaren Antworten: Der Kunde kann nicht sicher zurücktreten.

Beispiele

POST-Zahlung

Kunde: „POST/Zahlungen“ + „Idempotency-Key: k-789“.
Server: Transaktion - erstellt 'payment' und einen Eintrag in 'idempotency _ keys'.
Wiederholung: Gibt den gleichen '201 '/Körper zurück; wenn der Invarianzkonflikt „409“ ist.

Bonusguthaben (sink)

sql insert into credits(user_id, op_id, amount, created_at)
values(:u,:op,:amt, now)
on conflict (user_id, op_id) do nothing;

Projektion aus Ereignissen

Consumer speichert 'seen (event_id)' und 'version' der Einheit; repeat - Ignoriere/idempotent upsert.
Der Lesefortschritt wird in derselben Transaktion erfasst wie die Aktualisierung der Projektion.

Checkliste für die Produktion

  • Für alle unsicheren Vorgänge ist ein idempotenter Schlüssel und sein Sichtbarkeitsbereich definiert.
  • Es gibt Deduplizierungstabellen mit TTL und eindeutigen Indizes.
  • Der Effekt und der Fortschritt des Lesens sind atomar.
  • Im Write-Modell ist ein optimistischer Wettbewerb enthalten (Version/sequence).
  • API-Verträge erfassen den 'Idempotency-Key '/' operation _ id' und das Wiederholungsverhalten.
  • Metriken und Protokolle enthalten 'op _ id '/' event _ id '/' trace _ id'.
  • Dubletten-, Sturz- und Renntests - in CI.
  • Die TTL/Archiv-Richtlinie und die PII-Sicherheit werden eingehalten.

FAQ

Wie unterscheidet sich „Idempotency-Key“ von „Request-Id“?
„Request-Id“ - Nachverfolgung; 'Idempotency-Key' ist die semantische Kennung der Operation, die bei Wiederholungen gleich sein muss.

Ist Idempotenz ohne DB möglich?
Für ein kurzes Fenster - ja (Redis/In-Process-Cache), aber ohne eine gemeinsame Transaktion steigt das Risiko von Takes. In kritischen Domänen - besser in einer einzigen DB-Transaktion.

Was tun mit externen Partnern?
Verhandeln Sie Schlüssel und wiederholbare Antworten. Wenn der Partner nicht unterstützt - wickeln Sie den Anruf in Ihre idempotente Schicht ein und speichern Sie „bereits angewendet“.

Wie wählt man TTL?
Summieren Sie die maximalen Verzögerungen: Log-Retention + Worst-Case Netzwerk/Rebalance + Puffer. Füge einen Vorrat hinzu (× 2).

Summe

Idempotenz ist die Disziplin der Schlüssel, Transaktionen und Versionen. Stabile Operations-IDs + atomare Fixierung des Effekts und des Lesefortschritts + idempotente Sinks/Projektionen ergeben „genau einen Effekt“ ohne die Magie der Transportebene. Machen Sie die Schlüssel deterministisch, die TTL realistisch und die Tests bösartig. Dann werden Retrays und Duplikate zur Routine und nicht zu Vorfällen.

Contact

Kontakt aufnehmen

Kontaktieren Sie uns bei Fragen oder Support.Wir helfen Ihnen jederzeit gerne!

Integration starten

Email ist erforderlich. Telegram oder WhatsApp – optional.

Ihr Name optional
Email optional
Betreff optional
Nachricht optional
Telegram optional
@
Wenn Sie Telegram angeben – antworten wir zusätzlich dort.
WhatsApp optional
Format: +Ländercode und Nummer (z. B. +49XXXXXXXXX).

Mit dem Klicken des Buttons stimmen Sie der Datenverarbeitung zu.