GH GambleHub

Olay veri tekilleştirme

1) Neden veri tekilleştirme

Kopyalar, retray'ler, ağ zaman aşımları, yük devretme ve geçmiş verilerin yeniden oynatılması nedeniyle ortaya çıkar. Eğer kontrol edilmezse:
  • Değişmezler ihlal edilir (çift borçlar, tekrarlanan e-posta/SMS, "iki kez oluşturulmuş" sipariş);
  • Maliyet artışı (yeniden yazma/yeniden işleme)
  • çarpık analitik.

Veri tekilleştirmenin amacı, genellikle idempotency ile birlikte kabul edilebilir taşıma tekrarları ile bir kerelik gözlemlenen bir etki sağlamaktır.

2) Veri tekilleştirme nereye yerleştirilir (katmanlar)

1. Edge/API ağ geçidi - 'Idempotency-Keu'/body + imzası ile açık kopyaları kesin.
2. Broker/stream - anahtar/sıra ile mantıksal veri tekilleştirme, bir ıskalamada birleştirme (daha az sıklıkla - maliyet nedeniyle).
3. Olay alıcısı (tüketici) - ana konum: Gelen kutusu/anahtar tablosu/önbellek.
4. Lavabo (DB/önbellek) - benzersiz anahtarlar/UPSERT/sürümler/sıkıştırma.
5. ETL/analiz - zaman penceresine göre son tarih ve sütun yataklarındaki anahtar.

Kural: Mümkün olduğunca erken, ancak yanlış pozitiflerin maliyetini ve tekrar oynatma ihtiyacını dikkate alarak.

3) Veri tekilleştirme anahtarları

3. 1 Doğal (tercih edilen)

'Payment _ id', 'order _ id', 'saga _ id # step', 'aggregate _ id # seq'.
Stabiliteyi ve anlamı garanti eder.

3. 2 Kompozit

'(tenant_id, type, external_id, version)' или '(user_id, event_ts_truncated, payload_hash)'

3. 3 Parmak izi

Alanların deterministik bir alt kümesinin karma (normalize düzen/kayıtlar), isteğe bağlı olarak 'HMAC (gizli, yük)'.

3. 4 Diziler/Sürümler

Toplam başına monoton 'seq' (iyimser engelleme/sürüm oluşturma).

Anti-pattern: Bir işletme ile bağlantısı olmayan "rastgele UUID" imkansızdır.

4) Zaman pencereleri ve sipariş

Veri tekilleştirme penceresi - etkinliğin tekrar gelebileceği süre (genellikle 24-72 saat; Finans için - daha uzun).
Sıra dışı: Geç kalalım. Akış çerçevelerinde - etkinlik zamanı + filigranlar.
Sürgülü/Fix-pencere deadup: "Son N dakika içinde anahtarı gördünüz mü? ».
Sıra farkındalığı: eğer 'seq' son işleme ≤ - çift/tekrar.

5) Veri yapıları ve uygulamaları

5. 1 Tam muhasebe

Redis SET/STRING + TTL: 'SETNX key 1 EX 86400' -'ilk kez - işliyoruz, aksi takdirde - SKIP ".
LRU/LFU önbellek (in-proc): hızlı, ancak uçucu - sadece ilk engel olarak daha iyi.
SQL benzersiz indeksleri + UPPERT: "insert or update" (idempotent effect).

5. 2 Yaklaşık yapılar (olasılıksal)

Bloom/Cuckoo filtresi: ucuz bellek, yanlış pozitifler mümkündür. Finans/siparişler için değil, bariz bir "gürültülü" düşüş (örneğin, telemetri) için uygundur.
Count-Min Sketch: "Sıcak" çekimlere karşı korumak için frekansları tahmin etmek.

5. 3 Akış durumları

Kafka Streams/Flink: TTL ile anahtarlı hal mağazası, pencerede anahtarla dedup; Kontrol noktası/geri yükleme.
Filigran + izin verilen gecikme: Geç olaylar penceresini yönetir.

6) İşlemsel desenler

6. 1 Gelen Kutusu (gelen tablo)

'Message _ id'/tuşunu kaydedin ve yan etkilere neden olun:
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;

Tekrar oynatma kaydı görür ve efekti tekrarlamaz.

6. 2 Çıkış Kutusu

Bir işlemde iş kaydı ve olay - yayıncı komisyoncuya gönderir. Çifte tüketiciyi ortadan kaldırmaz, ancak "delikleri" hariç tutar.

6. 3 Benzersiz Dizinler/UPPERT

sql
INSERT INTO payments(id, status, amount)
VALUES ($1, $2, $3)
ON CONFLICT (id) DO NOTHING; -- "create once"
veya kontrollü sürüm yükseltme:
sql
UPDATE orders
SET status = $new, version = version + 1
WHERE id=$id AND version = $expected; -- optimistic blocking

6. 4 Agregaların sürümleri

Event if 'event geçerlidir. sürüm = toplam. sürüm + 1 '. Aksi takdirde - çift/tekrar/çatışma.

7) Deadup ve komisyoncular/akışlar

7. 1 Kafka

Idempotent Producer giriş çiftlerini azaltır.
İşlemler atomik olarak ofset + çıktı kayıtlarını işlemenizi sağlar.
Sıkıştırma: anahtar başına son değeri saklar - post-factum dedup/coalescing (ödemeler için değil).
Tüketici tarafı: Pencere anahtarları için eyalet mağazası/Redis/DB.

7. 2 NATS/JetStream

Ack/redelivery - en az bir kez. Tüketicide Dedup (Gelen Kutusu/Redis).
JetStream dizisi/tüketici çalışması tekrarları tanımlamayı kolaylaştırır.

7. 3 Kuyruk (Tavşan/SQS)

Görünürlük zaman aşımı + tekrarlanan teslimatlar - bir anahtar + deadstore'a ihtiyacınız var.
SQS FIFO, 'MessageGroupId'/' DeduplicationId'ile yardımcı olur, ancak TTL pencereleri sağlayıcı tarafından sınırlıdır - iş gerektiriyorsa anahtarları daha uzun süre saklayın.

8) Depolama ve analizörler

8. 1 ClickHouse/BigQuery

Pencere ile Dedup: 'ORDER BY key, ts've' argMax'/' any 'Last' koşullu.

ClickHouse:
sql
SELECT key,
anyLast(value) AS v
FROM t
WHERE ts >= now() - INTERVAL 1 DAY
GROUP BY key;

Veya "benzersiz" olayların maddeleşmiş bir katmanı (anahtar/sürüm ile birleştirme).

8. 2 Günlükleri/telemetri

Diyelim ki yaklaşık-dump (Bloom) üzerinde ingest> save network/disk.

9) Yeniden işleme, tekrar oynatma ve geri doldurma

Dedup tuşları tekrar oynatmada hayatta kalmalıdır (TTL ≥ tekrar penceresi).
Geri doldurma için, anahtar alanını sürümle birlikte kullanın ('anahtar # kaynak = batch2025') veya çevrimiçi pencereye müdahale etmemek için "sızıntıları" ayırın.
Sonuç artefaktlarını saklayın (hash/version) - bu, tekrarlarda "hızlı atlamayı" hızlandırır.

10) Metrikler ve gözlemlenebilirlik

'dedup _ hit _ total'/' dedup _ hit _ rate' - yakalanan kopyaların oranı.
Olasılıksal filtreler için 'dedup _ fp _ rate'.
'window _ size _ seconds' actual (geç gelen telemetri ile).
'inbox _ conflict _ total', 'upsert _ conflict _ total'.
'yeniden oynatılmış _ olaylar _ toplam', 'atlanmış _ by _ inbox _ toplam'.
Kiracı/anahtar/türe göre profiller: En çok nerede alınır ve neden.

Логи: 'message _ id', 'idempotency _ key', 'seq', 'window _ id','action = process 'skip'.

11) Güvenlik ve gizlilik

PII'yi anahtara koymayın; Özet/diğer ad kullanın.
Parmak izini imzalamak için - HMAC (gizli, canonical_payload) çarpışmaları/sahteciliği önlemek için.
Anahtarların depolama süresini uyumlulukla koordine edin (GDPR saklama).

12) Performans ve maliyet

In-proc LRU ≪ Redis, SQL'i işlem başına gecikme/maliyetle ≪.
Redis: ucuz ve hızlı, ancak anahtarların ve TTL'nin hacmini düşünün; 'kiracı/hash'tarafından shardy.
SQL: p99 tarafından pahalı, ancak güçlü garantiler ve kitle sağlar.
Olasılıksal filtreler: çok ucuz, ancak FP'ler mümkündür - "ekstra SKIP'in kritik olmadığı yerlerde kullanın.

13) Anti-desenler

"Kafka'ya tam olarak bir kez sahibiz - anahtara gerek yok. "Gerekli - bir çürük/iş katmanında.
Anahtarlar için çok kısa TTL - tekrarlar/gecikme bir çift sağlayacaktır.
Global tek dedup - hotspot ve SPOF; kiracı/anahtar tarafından paylaşılmaz.
Dedup sadece bellekte - süreç kaybı = alma dalgası.
Para/emirler için Bloom - yanlış pozitif meşru operasyonu mahrum edecek.
Tutarsız yük kanonizasyonu - anlam bakımından aynı olan mesajlar için farklı karmalar.
Sıra dışı yoksayma - geç olaylar hatalı olarak kopyalarla işaretlenir.

14) Uygulama kontrol listesi

  • Doğal bir anahtar (veya bileşik/parmak izi) tanımlayın.
  • Dedup penceresini ve 'gecikme' politikasını ayarlayın.
  • Belirli seviye (ler): kenar, tüketici, lavabo; Parçalanmayı sağlar.
  • Gelen Kutusu/UPSERT'i uygulayın; Akışlar için - anahtarlı durum + TTL.
  • Yaklaşık bir bariyere ihtiyacınız varsa - Bloom/Cuckoo (sadece kritik olmayan alanlar için).
  • Yeniden oynatma uyumluluğunu yapılandırın (TTL ≥ yeniden oynatma/geri doldurma penceresi).
  • Metrikler 'dedup _ hit _ rate', çakışmalar ve pencere gecikmeleri; kiracı başına gösterge panoları.
  • Oyun Günü: zaman aşımları/yeniden oynatmalar, tekrar oynatma, sıra dışı, önbellek düşüşü.
  • Belge yükü kanonizasyonu ve anahtar sürüm oluşturma.
  • Sıcak tuşlar ve uzun pencereler üzerinde yük testleri yapın.

15) Örnek Yapılandırmalar/Kod

15. 1 Redis SETNX + TTL (bariyer)

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 Gelen Kutusu

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 Kafka Streams

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 Flink (anahtarlı durum + TTL, sözde)

java
ValueState<Boolean> seen;
env. enableCheckpointing(10000);
onEvent(e):
if (!seen.value()) { process(e); seen. update(true); }

15. 5 NGINX/API ağ geçidi (Kenar üzerinde Idempotency-Key)

nginx map $http_idempotency_key $idkey { default ""; }
Proxy the key to the backend; backend solves deadup (Inbox/Redis).

16) SSS

S: Ne seçmeli: deadup mu yoksa saf idempotans mı?
C: Genellikle her ikisi de: deadup hızlı bir "filtre" (tasarruf), idempotans doğru etkinin garantisidir.

S: Hangi TTL koymak için?
A: ≥ maksimum olası yeniden teslimat süresi + envanter. Tipik olarak 24-72 saat; Finans ve ertelenmiş görevler için - günler/haftalar.

S: Geç olayları nasıl ele alıyorsunuz?
A: 'İzin verilen gecikme've alarm' late _ event 'yapılandırın; Daha sonra olanlar - ayrı bir dal aracılığıyla (yeniden hesaplama/atlama).

S: Tüm telemetri akışı tekilleştirilebilir mi?
C: Evet, yaklaşık filtreler (Bloom) kenarda, ancak FP'yi göz önünde bulundurun ve kritik iş etkileri için geçerli değildir.

S: Deadup geri doldurma yoluna mı giriyor?
C: Anahtar boşluklarını ayırın ('anahtar # batch2025') veya geri doldurma süresi boyunca bariyeri devre dışı bırakın; TTL anahtarları yalnızca çevrimiçi pencereleri kapsamalıdır.

17) Toplam

Veri tekilleştirme kompozisyondur: doğru anahtar, pencere ve durum yapısı + işlem desenleri (Gelen Kutusu/Giden Kutusu/UPSERT) ve sipariş ve geç olayların dikkatli bir şekilde ele alınması. Engelleri en ucuz olduğu yere yerleştirin, çürüklerde idempotans sağlayın, 'dedup _ hit _ rate' ölçün ve tekrarları/başarısızlıkları test edin - bu şekilde gereksiz gecikme ve maliyet kuyrukları olmadan "etkili bir şekilde tam olarak bir kez" elde edersiniz.

Contact

Bizimle iletişime geçin

Her türlü soru veya destek için bize ulaşın.Size yardımcı olmaya her zaman hazırız!

Entegrasyona başla

Email — zorunlu. Telegram veya WhatsApp — isteğe bağlı.

Adınız zorunlu değil
Email zorunlu değil
Konu zorunlu değil
Mesaj zorunlu değil
Telegram zorunlu değil
@
Telegram belirtirseniz, Email’e ek olarak oradan da yanıt veririz.
WhatsApp zorunlu değil
Format: +ülke kodu ve numara (örneğin, +90XXXXXXXXX).

Butona tıklayarak veri işlemenize onay vermiş olursunuz.