घटना डीडुप्लिकेशन
1) डिडुप्लिकेशन क्यों
ऐतिहासिक डेटा के रीट्रे, नेटवर्क टाइमआउट, फेलओवर और रीप्ले के कारण डुप्लिकेट दिखाई देते हैं। यदि वे नियंत्रित नहीं हैं:- अपरिवर्तनों का उल्लंघन किया जाता है (डबल डेबिट, बार-बार ईमेल/एसएमएस, "दो बार बनाया गया" आदेश);
- लागत में वृद्धि (पुन: लेखन/पुनर्प्रसंस्करण)
- विकृत एनालिटिक्स।
Deduplication का लक्ष्य स्वीकार्य परिवहन दोहराव के साथ एक बार मनाया प्रभाव प्रदान करना है, अक्सर पहचान के साथ।
2) डीडुप्लीकेशन (टियर्स) कहां रखें
1. एज/एपीआई गेटवे - 'आइडेम्पोटेंसी-केयू '/बॉडी + सिग्नेचर द्वारा स्पष्ट डुप्लिकेट काटें।
2. ब्रोकर/स्ट्रीम - कुंजी/अनुक्रम द्वारा तार्किक कमी, एक मिस पर सहवास (लागत के कारण कम अक्सर)।
3. घटना रिसीवर (उपभोक्ता) - मुख्य स्थान: इनबॉक्स/कुंजी तालिका/कैश।
4. सिंक (DB/cache) - अद्वितीय कुंजी/UPSERT/संस्करण/संपीड़न।
5. ईटीएल/विश्लेषण - समय विंडो द्वारा समय सीमा और स्तंभ बेड में कुंजी।
नियम: जितनी जल्दी हो सके, लेकिन झूठी सकारात्मकता की लागत और फिर से खेलने की आवश्यकता को ध्यान में रखते हुए।
3) Deduplication कुंजियाँ
3. 1 प्राकृतिक (पसंदीदा)
'payment _ id', 'ऑर्डर _ id', 'saga _ id # step', 'एग्रीगेट _ id # seq'।
गारंटी स्थिरता और अर्थ।
3. 2 समग्र
'(tenant_id, प्रकार, external_id, संस्करण)' или '(user_id, event_ts_truncated, payload_hash)'।
3. 3 फिंगरप्रिंट
फ़ील्ड के एक नियतात्मक सबसेट का हैश (सामान्यीकृत आदेश/रजिस्टर), वैकल्पिक रूप से 'एचएमएसी (गुप्त, पेलोड)'।
3. 4 अनुक्रम/संस्करण
नीरस 'seq' per कुल (आशावादी अवरोधन/वर्शनिंग)।
एंटी-पैटर्न: व्यावसायिक इकाई के साथ संबंध के बिना "यादृच्छिक यूयूआईडी" असंभव है।
4) टाइम विंडो और ऑर्डर
डीडुप्लिकेशन विंडो - वह अवधि जिसके दौरान घटना फिर से आ सकती है (आमतौर पर 24-72 घंटे; वित्त के लिए - लंबे समय तक)।
आउट-ऑफ-ऑर्डर: चलो विलंबता हो। स्ट्रीमिंग फ्रेमवर्क में - घटना समय + वॉटरमार्क।
स्लाइडिंग/फिक्स-विंडो डेडअप: "क्या आपने पिछले एन मिनटों में कुंजी देखी है? ».
अनुक्रम-जागरूक: यदि 'seq' - अंतिम संसाधित - डबल/रिपीट।
5) डेटा संरचनाएं और कार्यान्वयन
5. 1 सटीक लेखा
Redis SET/STRING + TTL: 'SETNX कुंजी 1 EX 86400' → "पहली बार - हम प्रसंस्करण कर रहे हैं, अन्यथा - SKIP।"
LRU/LFU कैश (इन-प्रोक): तेज, लेकिन अस्थिर - केवल पहली बाधा के रूप में बेहतर।
SQL अद्वितीय सूचकांक + UPSERT: "सम्मिलित या अद्यतन" (पहचान प्रभाव)।
5. 2 अनुमानित संरचनाएं (संभाव्य)
ब्लूम/कोयल फिल्टर: सस्ती मेमोरी, झूठी सकारात्मकता संभव है। यह एक स्पष्ट "शोर" ड्रॉप (उदाहरण के लिए, टेलीमेट्री) के लिए उपयुक्त है, वित्त/आदेशों के लिए नहीं।
काउंट-मिन स्केच: "हॉट" से बचाने के लिए आवृत्तियों का अनुमान लगाना।
5. 3 स्ट्रीमिंग राज्य
काफ्का स्ट्रीम/फ्लिंक: टीटीएल के साथ कीड स्टेट स्टोर, विंडो में कुंजी द्वारा डीडअप; चेकपॉइंट/पुनर्स्थापित करें।
वॉटरमार्क + अनुमत विलंबता: देर से घटनाओं की खिड़की का प्रबंधन करता है।
6) लेन-देन के पैटर्न
6. 1 इनबॉक्स (आने वाली तालिका)
'मेसेज _ आईडी '/कुंजी सहेजें और दुष्प्रभावों का परिणाम:pseudo
BEGIN;
ins = INSERT INTO inbox(id, received_at) ON CONFLICT DO NOTHING;
IF ins_not_inserted THEN RETURN cached_result;
result = handle(event);
UPSERT sink with result; -- idempotent sync
UPDATE inbox SET status='done', result_hash=... WHERE id=...;
COMMIT;
रिप्ले रिकॉर्डिंग देखेगा और प्रभाव को दोहराएगा नहीं।
6. 2 आउटबॉक्स
एक लेनदेन में व्यापार रिकॉर्ड और घटना - प्रकाशक दलाल को भेजता है। उपभोक्ता से दोहरे को समाप्त नहीं करता है, लेकिन "छेद" को बाहर करता है।
6. 3 अद्वितीय सूचकांक/UPSERT
sql
INSERT INTO payments(id, status, amount)
VALUES ($1, $2, $3)
ON CONFLICT (id) DO NOTHING; -- "create once"
या नियंत्रित संस्करण उन्न
sql
UPDATE orders
SET status = $new, version = version + 1
WHERE id=$id AND version = $expected; -- optimistic blocking
6. 4 समुच्चय का संस्करण
घटना यदि 'घटना' लागू होती है। संस्करण = कुल। संस्करण + 1 '। अन्यथा - दोहरा/दोहराएँ/विरोध करें।
7) डेडअप और दलालों/धाराओं
7. 1 काफ्का
आइडेम्पोटेंट प्रोड्यूसर एंट्री डबल्स को कम करता है।
लेनदेन आपको परमाणु रूप से ऑफसेट + आउटपुट रिकॉर्ड करने की अनुमति देता है।
संघनन: प्रति कुंजी अंतिम मूल्य संग्रहीत करता है - पोस्ट-फैक्टम डीडअप/कोलसिंग (भुगतान के लिए नहीं)।
उपभोक्ता-पक्ष: विंडो कुंजी के लिए राज्य स्टोर/रेडिस/डीबी।
7. 2 NATS/JetStream
Ack/redelivery - कम से कम एक बार। उपभोक्ता में डेडअप (इनबॉक्स/रेडिस)।
जेटस्ट्रीम अनुक्रम/उपभोक्ता कार्य पुनरावृत्तियों की पहचान करना आसा
7. 3 कतारें (खरगोश/एसक्यूएस)
दृश्यता समय समाप्ति + दोहराया डिलीवरी - आपको एक कुंजी + डेडस्टोर की आवश्यकता है।
SQS FIFO 'MessIgroupId '/' Dedupl Id' के साथ मदद करता है, लेकिन TTL विंडो प्रदाता-सीमित हैं - यदि व्यवसाय की आवश्यकता हो तो कुंजी लंबे समय तक रखें।
8) भंडारण और विश्लेषक
8. 1 क्लिकहाउस/BigQuery
विंडो द्वारा डेडअप: 'ऑर्डर बाय कुंजी, ts' और 'argMax '/' AnyLast' शर्त के साथ।
क्लिकहाउस:sql
SELECT key,
anyLast(value) AS v
FROM t
WHERE ts >= now() - INTERVAL 1 DAY
GROUP BY key;
या "अद्वितीय" घटनाओं की एक भौतिक परत (कुंजी/संस्करण द्वारा विलय)।
8. 2 लॉग/टेलीमेट्री
मान लीजिए कि नेटवर्क/डिस्क को सहेजें।
9) पुनर्संसाधन, रिप्ले और बैकफिल
Dedup कुंजी को पुनरावृत्ति से बचना चाहिए (TTL ≥ repray विंडो).
बैकफिल के लिए, संस्करण ('की # source = batch2025') या अलग "लीक" के साथ मुख्य स्थान का उपयोग करें ताकि ऑनलाइन विंडो में हस्तक्षेप न करें।
स्टोर परिणाम कलाकृतियों (हैश/संस्करण) - यह रिप्ले पर "फास्ट-स्किप" को गति देता है।
10) मेट्रिक्स और वेधशाला
'dedup _ hit _ total '/' dedup _ hit _ rate' - डुप्लिकेट का अनुपात पकड़ा गया।
'dedup _ fp _ rate' for संभाव्य फिल्टर।
'window _ size _ सेकंड' वास्तविक (टेलीमेट्री देर से आगमन द्वारा)।
'inbox _ collection _ total', 'upsert _ collection _ total'।
'replayed _ events _ total', 'skiped _ by _ inbox _ total'।
किरायेदार/कुंजी/प्रकार द्वारा प्रोफाइल: सबसे अधिक कहां हैं और क्यों।
Логи: 'message _ id', 'idempotency _ key', 'seq', 'window _ id', 'action = process' skip '।
11) सुरक्षा और गोपनीयता
पीआईआई को कुंजी में न रखें; हैश/उपनाम का उपयोग करें।
टकराव/जालसाजी से बचने के लिए फिंगरप्रिंट - एचएमएसी (गुप्त, canonical_payload) पर हस्ताक्षर करना।
अनुपालन (GDPR प्रतिधारण) के साथ कुंजियों के भंडारण समय का समन्वय करें।
12) प्रदर्शन और लागत
इन-प्रोक LRU ≪ Redis ≪ SQL प्रति ऑपरेशन विलंबता/लागत द्वारा।
रेडिस: सस्ता और तेज, लेकिन चाबियों और टीटीएल की मात्रा पर विचार करें; 'किरायेदार/हैश' द्वारा शर्मीली।
SQL: p99 द्वारा महंगा, लेकिन मजबूत गारंटी और दर्शक प्रदान करता है।
संभाव्य फिल्टर: बहुत सस्ता, लेकिन एफपी संभव है - जहां "अतिरिक्त SKIP" महत्वपूर्ण नहीं है, उपयोग करें।
13) एंटी-पैटर्न
"हमारे पास काफ्का बिल्कुल एक बार है - कोई कुंजी की आवश्यकता नहीं है। "जरूरत है - एक चोट/व्यावसायिक परत में।
कुंजियों के लिए बहुत छोटा टीटीएल → रिप्ले/देरी एक डबल वितरित करेगा.
ग्लोबल सिंगल डेडअप → हॉटस्पॉट और एसपीओएफ; किरायेदार/कुंजी द्वारा तेज नहीं।
डेडअप केवल मेमोरी में - प्रक्रिया की हानि = लेने की तरंग।
पैसे/आदेशों के लिए खिलना - गलत सकारात्मक वैध संचालन से वंचित हो जाएगा।
असंगत पेलोड कैनोनाइजेशन - संदेशों के लिए विभिन्न हैश जो अर्थ में समान हैं।
आउट-ऑफ-ऑर्डर - देर से घटनाओं को गलत तरीके से डुप्लिकेट के साथ चिह्नित किया जाता है।
14) कार्यान्वयन चेकलिस्ट
- एक प्राकृतिक कुंजी (या यौगिक/फिंगरप्रिंट) को परिभाषित करें।
- डेडअप विंडो और 'लेटनेस' पॉलिसी सेट करें।
- चयन स्तर (ओं): बढ़ त, उपभोक्ता, सिंक; शार्डनिंग के लिए प्रदान करते
- इनबॉक्स/यूपीएसईआरटी लागू करें; प्रवाह कुंजी राज्य + टीटीएल के लिए।
- यदि आपको एक अनुमानित अवरोध की आवश्यकता है - ब्लूम/कोयल (केवल गैर-महत्वपूर्ण डोमेन के लिए)।
- रीप्ले संगतता कॉन्फ़िगर करें (TTL ≥ repray/backfill विंडो)।
- मेट्रिक्स 'डीडअप _ हिट _ रेट', संघर्ष और विंडो लैग्स; डैशबोर्ड प्रति-किरायेदार।
- गेम डे: टाइमआउट/रिट्रे, रीप्ले, आउट-ऑफ-ऑर्डर, कैश ड्रॉप।
- दस्तावेज़ पेलोड कैनोनाइजेशन और कुंजी संस्करण।
- गर्म कुंजियों और लंबी खिड़कियों पर लोड परीक्षण करें।
15) नमूना कॉन्फ़िगरेशन/कोड
15. 1 Redis SETNX + TTL (बाधा)
lua
-- KEYS[1] = "dedup:{tenant}:{key}"
-- ARGV[1] = ttl_seconds local ok = redis. call("SET", KEYS[1], "1", "NX", "EX", ARGV[1])
if ok then return "PROCESS"
else return "SKIP"
end
15. 2 PostgreSQL इनबॉक्स
sql
CREATE TABLE inbox (
id text PRIMARY KEY,
received_at timestamptz default now(),
status text default 'received',
result_hash text
);
-- In the handler: INSERT... ON CONFLICT DO NOTHING -> check, then UPSERT in blue.
15. 3 काफ्का धाराएँ
java var deduped = input
.selectKey((k,v) -> v.idempotencyKey())
.groupByKey()
.windowedBy(TimeWindows. ofSizeWithNoGrace(Duration. ofHours(24)))
.reduce((oldV,newV) -> oldV) // first wins
.toStream()
.map((wKey,val) -> KeyValue. pair(wKey. key(), val));
15. 4 फ्लिंक (कीड स्टेट + टीटीएल, छद्म)
java
ValueState<Boolean> seen;
env. enableCheckpointing(10000);
onEvent(e):
if (!seen.value()) { process(e); seen. update(true); }
15. 5 NGINX/API गेटवे (किनारे पर Idempotency-Key)
nginx map $http_idempotency_key $idkey { default ""; }
Proxy the key to the backend; backend solves deadup (Inbox/Redis).
16) एफएक्यू
प्रश्न: क्या चुनना है: मृत्यु या शुद्ध पहचान?
A: आमतौर पर दोनों: डेडअप एक तेज "फिल्टर" (बचत) है, पहचान सही प्रभाव की गारंटी है।
प्रश्न: कौन सा टीटीएल डालना है?
A: ≥ अधिकतम संभव री-डिलीवरी टाइम + इन्वेंट्री। आमतौर पर 24-72 घंटे; वित्त और आस्थगित कार्यों के लिए - दिन/सप्ताह।
प्रश्न: आप देर से होने वाली घटनाओं को कैसे संभालते हैं?
A: 'स्वीकृत विलंबता' और अलार्म 'late _ event' कॉन्फ़िगर करें; बाद में - एक अलग शाखा के माध्यम से (पुनर्मिलन/स्किप)।
प्रश्न: क्या पूरे टेलीमेट्री स्ट्रीम को डीडुप्लिकेट किया जा सकता है?
A: हां, किनारे पर अनुमानित फिल्टर (ब्लूम), लेकिन FP पर विचार करें और महत्वपूर्ण व्यावसायिक प्रभावों पर लागू नहीं होते हैं।
प्रश्न: बैकफिल के रास्ते में डेडअप हो रहा है?
A: अलग कुंजी रिक्त स्थान ('कुंजी # batch2025') या बैकफिल की अवधि के लिए बाधा को अक्षम करें; टीटीएल कुंजियों को केवल ऑनलाइन विंडो को कवर करना चाहिए।
17) कुल
Deduplication रचना है: सही कुंजी, विंडो और राज्य संरचना + लेन-देन पैटर्न (Inbox/Outbox/UPSERT) और क्रम और देर से होने वाली घटनाओं की दिमागी हैंडलिंग। बाधाओं को रखें जहां यह सबसे सस्ता है, चोटों में पहचान सुनिश्चित करें, 'डीडअप _ हिट _ रेट' को मापें और परीक्षण रिप्ले/विफल करें - इस तरह आपको विलंबता और लागत की अनावश्यक पूंछ के बिना "प्रभावी रूप से बिल्कुल-एक बार" मिलता है।