Ταυτότητα και κλειδιά
Τι είναι η ιδιαιτερότητα
Idempotency είναι μια ιδιότητα μιας πράξης στην οποία η επανάληψη με τον ίδιο αναγνωριστικό κωδικό δεν αλλάζει το τελικό αποτέλεσμα. Στα κατανεμημένα συστήματα, αυτός είναι ο βασικός τρόπος για να γίνει το αποτέλεσμα ισοδύναμο με «ακριβώς μία επεξεργασία», παρά τις ρετράι, τα διπλά μηνύματα και τα χρονοδιαγράμματα.
Βασική ιδέα: κάθε δυνητικά επαναλαμβανόμενη λειτουργία πρέπει να επισημαίνεται με ένα κλειδί με το οποίο το σύστημα αναγνωρίζει «αυτό έχει ήδη γίνει» και εφαρμόζει το αποτέλεσμα μόνο μία φορά.
Όπου έχει σημασία
Πληρωμές και υπόλοιπα: διαγραφές/πιστώσεις κατά «πράξη _ id».
Επιφυλάξεις/ποσοστώσεις/όρια: ίδια χρονοθυρίδα/πόρος.
Webhooks/κοινοποιήσεις: η επαναλαμβανόμενη παράδοση δεν πρέπει να επαναλαμβάνει το αποτέλεσμα.
Εισαγωγή/μετάβαση - Επαναλάβετε τα αρχεία/πακέτα.
Επεξεργασία ροής: αντίγραφα από μεσίτες/ΚΕΕΛΠΝΟ.
Τύποι κλειδιών και πεδίο εφαρμογής τους
1. Κλείδα λειτουργίας - Αναγνωριστικός κωδικός της συγκεκριμένης απόπειρας της επιχειρηματικής συναλλαγής
Παραδείγματα: 'idempotency _ key' (HTTP), 'operation _ id' (RPC).
Πεδίο εφαρμογής: υπηρεσία/σύνολο· αποθηκεύεται σε πίνακα αφαίρεσης.
2. Κλειδί γεγονότος - αποκλειστικός αναγνωριστικός κωδικός του γεγονότος/μηνύματος
Παραδείγματα: 'event _ id' (UUID), '(producer_id, ακολουθία)'.
Τομέας: ομάδα καταναλωτών/καταναλωτών· προστατεύει τις προβολές.
3. Κλειδιά επιχειρήσεων - κλειδί φυσικού τομέα
Παραδείγματα: "πληρωμή _ i ," τιμολόγιο _ αριθμός "," ( , ημέρα) ".
Πεδίο: συγκεντρωτικό· χρησιμοποιείται σε ελέγχους μοναδικότητας/έκδοσης.
TTL και πολιτική διατήρησης
Πλήκτρα TTL ≥ ένα πιθανό παράθυρο επανάληψης: διατήρηση καταγραφής + καθυστερήσεις δικτύου/διεργασίας.
για κρίσιμους τομείς (πληρωμές) TTL - ημέρες/εβδομάδες· για την τηλεμετρία - ώρες.
Καθαρισμός πινάκων αφαίρεσης με θέσεις εργασίας υποβάθρου· για τον έλεγχο - αρχείο.
Καταστήματα κλειδιά (αφαίρεση)
Βάση δεδομένων συναλλαγών (συνιστάται): αξιόπιστοι δείκτες upsert/μοναδικοί δείκτες, κοινή συναλλαγή με ισχύ.
KV/Redis: γρήγορη, βολική για σύντομη TTL, αλλά χωρίς κοινή συναλλαγή με την OLTP - προσεκτική.
Επεξεργαστής State store stream: τοπικά + changelog σε μεσίτη. καλό στο Flink/KStreams.
- idempotency_keys
'consumer _ i ( ' υπηρεσία '),' op _ i (PK ), 'applied _ at', 'ttl _ λήγει _ at', 'result _ hash '/' response _ status' ( .) .
Ευρετήρια: '(consumer_id, op_id)' - μοναδικά.
Βασικές τεχνικές εφαρμογής
1) Επίδραση + συναλλαγή προόδου
Καταγραφή του αποτελέσματος και καταγραφή της προόδου ανάγνωσης/θέσης σε μία συναλλαγή.
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) Αισιόδοξο νόμισμα (unit version)
Προστατεύει από το διπλό αποτέλεσμα κατά την αγωνιστική: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) Ευέλικτοι νεροχύτες (upsert/συγχώνευση)
Συσσώρευση μιας φοράς:sql insert into bonuses(user_id, op_id, amount)
values(:u,:op,:amt)
on conflict (user_id, op_id) do nothing;
Ιδιαιτερότητα σε πρωτόκολλα
HTTP/REST
Κεφαλίδα 'Idempotency-Key: <uuid' hash> '.
Ο εξυπηρετητής αποθηκεύει το αρχείο κλειδιών και επιστρέφει την ίδια απάντηση και πάλι (ή κωδικός '409 '/' 422' σε περίπτωση αμετάβλητης σύγκρουσης).
Για την «επισφαλή» POST, απαιτείται πολιτική «Idempotency-Key» + σταθερή timeout/retray.
gRPC/RPC
Μεταδεδομένα 'idempotency _ key', 'request _ id' + προθεσμία.
Εφαρμογή εξυπηρετητή - όπως στην περίπτωση REST: πίνακας απεμπλοκής μιας συναλλαγής.
Μεσίτες/Streaming (Kafka/NATS/Pulsar)
Παραγωγός: σταθερός παραγωγός "event _ i /idempotent (όπου υποστηρίζεται).
Καταναλωτής: dedup by '(consumer_id, event_id)' and/or business version of the college.
Διαχωρισμός DLQ για μη ευδιάκριτα/διεφθαρμένα μηνύματα.
Webhooks και εξωτερικοί εταίροι
Απαίτηση 'Idempotency-Key '/' event _ id' στη σύμβαση. η επανακυκλοφορία πρέπει να είναι ασφαλής.
Να αποθηκεύεται το «notice _ id» και το καθεστώς αποστολής. στο retray - μην επαναλαμβάνεται.
Βασικός σχεδιασμός
Προσδιορισμός: Τα retrays πρέπει να στέλνουν το ίδιο κλειδί (παράγουν εκ των προτέρων στον πελάτη/ενορχηστρωτή).
Πεδίο εφαρμογής: Έντυπο «op _ id» ως «υπηρεσία: σύνολο: id: σκοπός».
Συγκρούσεις: χρήση UUIDv7/ULID ή χασίς από τις επιχειρηματικές παραμέτρους (με αλάτι, εάν είναι απαραίτητο).
Ιεραρχία: η γενική «λειτουργία _ id» στο → μέτωπο μεταφράζεται σε όλες τις υποεπιχειρήσεις (idempotent chain).
UX και πτυχές προϊόντων
Ένα επαναλαμβανόμενο βασικό αίτημα πρέπει να επιστρέφει το ίδιο αποτέλεσμα (συμπεριλαμβανομένου του φορέα/καθεστώτος) ή ρητή «ήδη εκτελεσθείσα».
Εμφάνιση στο χρήστη της κατάστασης «η λειτουργία επεξεργάζεται/ολοκληρώνεται» αντί να προσπαθήσει ξανά «για καλή τύχη».
Για μεγάλες λειτουργίες - δημοσκόπηση ανά κλειδί («GET/operations/{ op _ id}»).
Παρατηρησιμότητα
Log 'op _ i ,' event _ id ',' trace _ id ', αποτέλεσμα:' APPLIED '/' ILISED _ APPLIED '.
Μετρήσεις: ρυθμός επανάληψης, μέγεθος πίνακα αποσύνθεσης, χρόνος συναλλαγής, συγκρούσεις έκδοσης, ρυθμός DLQ.
Ίχνος: το κλειδί πρέπει να διέρχεται από το συμβάν → εντολής → προβολή → εξωτερικής κλήσης.
Ασφάλεια και συμμόρφωση
Μην φυλάσσετε το PII σε πλήκτρα. κλειδί - αναγνωριστικό, όχι ωφέλιμο φορτίο.
Κρυπτογράφηση ευαίσθητων πεδίων σε εγγραφές αφαίρεσης με μακρύ TTL.
Πολιτική διατήρησης: TTL και αρχεία. δικαίωμα να λησμονείται - μέσω της κρυπτογράφησης των απαντήσεων/μεταδεδομένων (εάν περιέχουν PII).
Έλεγχος
1. Αντίγραφα: εκτελέστε ένα μήνυμα/αίτημα 2-5 φορές - αποτέλεσμα ακριβώς ένα.
2. Πτώση μεταξύ των βαθμίδων: πριν/μετά την καταγραφή της επίδρασης, πριν/μετά τον καθορισμό της όφσετ.
3. Επανεκκίνηση/επανεξισορρόπηση των καταναλωτών: καμία διπλή χρήση.
4. Ανταγωνισμός: παράλληλες ερωτήσεις με ένα 'op _ i ένα αποτέλεσμα, το δεύτερο -' ILLASS _ '.
5. Μακρόβια κλειδιά: Έλεγχοι για τη λήξη του TTL και τις επαναλήψεις μετά την ανάκτηση.
Αντι-μοτίβα
Τυχαίο νέο κλειδί για κάθε επανάληψη: το σύστημα δεν αναγνωρίζει επαναλήψεις.
Δύο διαφορετικές δεσμεύσεις: πρώτα το αποτέλεσμα, μετά η όφσετ - η πτώση μεταξύ τους αναπαράγει το αποτέλεσμα.
Εμπιστοσύνη μόνο στον μεσίτη: καμία απεμπλοκή στον μώλωπα/στο σύνολο.
Απουσία συνολικής έκδοσης: επαναλαμβανόμενες αλλαγές γεγονότος δηλώνουν μια δεύτερη φορά.
Πλήκτρα λίπους: το κλειδί περιλαμβάνει επιχειρηματικά πεδία/διαρροές PII → και σύνθετους δείκτες.
Δεν υπάρχουν επαναλαμβανόμενες απαντήσεις: Ο πελάτης δεν μπορεί να αποσυρθεί με ασφάλεια.
Παραδείγματα
Payment POST
Πελάτης: 'POST/πληρωμές' + 'Idempotency-Key: k-789'.
Εξυπηρετητής: συναλλαγή - δημιουργεί μια 'πληρωμή' και μια εγγραφή στο 'idempotency _ key .
Redo: επιστρέφει το ίδιο '201 '/σώμα; σε περίπτωση αναλλοίωτης σύγκρουσης - '409'.
Συσσώρευση μπόνους (νεροχύτης)
sql insert into credits(user_id, op_id, amount, created_at)
values(:u,:op,:amt, now)
on conflict (user_id, op_id) do nothing;
Προβολή από γεγονότα
Τα καταστήματα καταναλωτών «seen (event_id)» και «version» της μονάδας· επανάληψη - αγνοήστε/idempotent upsert.
Ανάγνωση προόδου καταγράφεται στην ίδια συναλλαγή με την ενημέρωση προβολής.
Κατάλογος ελέγχου παραγωγής
- Όλες οι μη ασφαλείς λειτουργίες έχουν ένα ταυτόσημο κλειδί και το πεδίο εφαρμογής του ορίζεται.
- Υπάρχουν πίνακες αφαίρεσης με TTL και μοναδικούς δείκτες.
- Το αποτέλεσμα και η πρόοδος της ανάγνωσης δεσμεύονται ατομικά.
- Ο αισιόδοξος ανταγωνισμός (έκδοση/ακολουθία) περιλαμβάνεται στο μοντέλο γραφής.
- Οι συμβάσεις API αποτυπώνουν το 'Idempotency-Key '/' operation _ id' και τη συμπεριφορά επανάληψης.
- Μετρικά και αρχεία καταγραφής περιέχουν 'op _ id '/' event _ i /' trace _ id'.
- Δοκιμές για αντίγραφα, πτώσεις και αγώνες - σε CI.
- Ακολουθούνται η πολιτική TTL/Archive και η ασφάλεια του PII.
ΣΥΧΝΈΣ ΕΡΩΤΉΣΕΙΣ
Πώς είναι το "Idempotency-Key 'different από το" Request-Id "
«Αναγνωριστικό αίτησης» - ίχνος· μπορεί να αλλάξει σε retrays. Το 'Idempotency-Key' είναι το σημασιολογικό αναγνωριστικό της λειτουργίας, το οποίο απαιτείται να είναι το ίδιο κατά τη διάρκεια επαναλήψεων.
Είναι δυνατή η ταυτότητα χωρίς βάση δεδομένων
Για ένα σύντομο χρονικό διάστημα - ναι (Redis/in-process cache), αλλά χωρίς κοινή συναλλαγή, ο κίνδυνος διπλών αντιγράφων αυξάνεται. Σε κρίσιμους τομείς, είναι καλύτερα σε μια συναλλαγή βάσης δεδομένων.
Τι σχέση έχει με τους εξωτερικούς εταίρους
Διαπραγμάτευση κλειδιών και επαναλαμβανόμενων απαντήσεων. Εάν ο σύντροφος δεν υποστηρίξει - περιτυλίξτε την κλήση στο idempotent στρώμα σας και αποθηκεύστε την «ήδη εφαρμοσμένη».
Πώς να επιλέξετε το TTL
Άθροισμα των μέγιστων καθυστερήσεων: κατακράτηση ημερολογίου + καθαρή/ισορροπία χειρότερη περίπτωση + απόθεμα ασφαλείας. Προσθήκη αποθέματος (× 2).
Σύνολο
Η ταυτότητα είναι μια πειθαρχία κλειδιών, συναλλαγών και εκδόσεων. Τα αναγνωριστικά σταθερής λειτουργίας + ατομική στερέωση της επίδρασης και ανάγνωση της προόδου + idempotent νεροχύτες/προβολές δίνουν «ακριβώς ένα αποτέλεσμα» χωρίς μαγεία επιπέδου μεταφοράς. Κάντε τα κλειδιά προσδιοριστικά, TTL ρεαλιστικά και δοκιμές κακόβουλες. Στη συνέχεια, οι επαναλήψεις και τα αντίγραφα θα γίνουν ρουτίνα, όχι περιστατικά.