Exactly-once semantika
exactly-once əslində nədir
«exactly-once» dedikdə çox vaxt iki fərqli şey başa düşülür:- Çatdırılma: mesaj tam olaraq bir dəfə istehlakçıya çatdırılacaq.
- Emal: Son yan təsir (DB-də qeyd, balans dəyişikliyi, başqa bir hadisənin emissiyası) daha çox çatdırılma və ya cəhd olsa belə, tam bir dəfə baş verəcəkdir.
Paylanmış sistemlərdə emal semantikası haqqında danışmaq daha etibarlıdır. Çatdırılma tam olaraq bir dəfə təmin etmək çətindir (təkrarlar və təkrarlar qaçılmazdır), lakin son vəziyyətin tək emala bərabər olmasını təmin etmək olar.
EOS lazım olduqda və lazım olmadıqda
Aşağıdakı hallarda EOS tələb olunur:- Pul əməliyyatları və balansları: ikiqat silinmə yolverilməzdir.
- Lisenziyaların/kvotaların uçotu, billing sayğacları.
- Geri dönməz xarici çağırışlar (məsələn, birdəfəlik açar aktivasiyası).
- Effektlər geri qaytarıla bilər və ya kompensasiya edilə bilər (dastanlar, geri qaytarmalar).
- Vitrinlərdə/lojlarda müvəqqəti dublikatlara icazə verilir.
- Bütün trakt boyunca əməliyyatları sürükləməkdən daha ucuz idempotent sink təmin etmək.
Model: end-to-end vs. hop-by-hop
Hop-by-hop EOS: Hər sayt (mənbə → prosessor → qəbuledici) tam olaraq bir dəfə tətbiq edilməsini təmin edir.
End-to-end EOS: Bütün zəncir "fakt 'dan" side effekti "nəticəsinin tək emala bərabər olduğunu təmin edir.
Praktikada end-to-end hər hopda əməliyyatlar və/və ya idempotentlik kombinasiyası ilə əldə edilir.
Əsas tikinti blokları
1. İdempotent əməliyyatları
Əməliyyat açarı ilə eyni sorğunun təkrarlanması eyni nəticəni verir.
Ключи: `idempotency_key`/`event_id`/`operation_id`.
Realizasiya: TTL ilə «görülən» əməliyyatlar cədvəli ≥ giriş log retensiyası.
2. «oxu-emal-yazma» əməliyyatları (read-process-write)
Bir atomik iş birliyində həm yan təsir, həm də oxu tərəqqisi (ofset/mövqe) qeydə alınır. Bu addımlar arasında düşdükdə «xəyalları» aradan qaldırır.
3. Version/SEQUENCE
Aqreqat üçün versiya/sayğac saxlanılır; dəyişikliklər yalnız 'expected _ version' uyğun olduqda tətbiq olunur. Eyni hadisənin təkrarlanması versiyanı artırmır → effekt bir dəfə.
4. Deduplikasiya
İndeks '(consumer_id, event_id)' və ya təbii 'business _ id' əməliyyatları üzrə.
Satış nümunələri
1) Əməliyyat log + ofset fiksasiyası ilə əməliyyat sink
Axın prosessinqi üçün idealdır.
Biz logdan oxuyuruq (yalnız təsdiqlənmiş qeydlər).
Emal edirik.
- a) sink (BD/cədvəl) təsiri qeyd,
- b) «N ofsetindən əvvəl oxundu» (eyni DB-də).
- Kommit. Restart zamanı hər şey gizli (və ofset köçürülür) və ya heç bir şey.
Xüsusiyyətləri: təkrar icra zərər vermir; Mesaj iki dəfə oxunsa belə, effektdə «tam bir dəfə».
2) Outbox + idempotent müştəri
Əməliyyat xidmətləri-prodüserlər üçün.
Bir DB əməliyyatında: domen girişini dəyişdiririk və hadisəni outbox-da yazırıq.
Republikator hadisəni eyni 'event _ id' ilə təkərə çatdırır.
Konsumerlər hadisələri idempotent olaraq tətbiq edirlər (dedup 'event _ id').
Xüsusiyyətləri: prodüser faktın itirilməyəcəyinə zəmanət verir; konsumerlər tam bir effekt təmin edir.
3) Kafka/Flink kimi sistemlərdə EOS (konseptual)
İdempotent prodüser: göndərmə retralarında dubllardan qoruyur.
Prodüser əməliyyatları: Topik qeydlər qrupu + konsumer dəyişikliyi atomik olaraq birləşdirilir; oxucular 'read _ committed' izolyasiyasından istifadə edirlər.
Prosessinq tərəfi (state store) sərvətini saxlayır və əməliyyat ilə birlikdə kommitit edir.
Xüsusiyyətləri: Store/Tusk yenidən başlaması ikiqat effekt vermir; downstream təkrarları «görünmür».
4) upsert/merge vasitəsilə idempotent «siki» (sinks)
Sink 'operation _ id '/' event _ id' qəbul edir və 'UPSERT... WHERE NOT EXISTS`.
Yan təsir (məsələn, hesablama) «artıq tətbiq edilməyib» yoxlaması ilə atomik olaraq yerinə yetirilir.
Xüsusiyyətlər: bölüşdürülmüş əməliyyatlar olmadan saxlama ilə sərhəddə ucuz EOS üsulu.
Əsas satış detalları
Əməliyyat identifikatorları
Təkrarlamalar üçün müəyyən edilməlidir (retrada yeni UUID yaratmayın).
Davamlı görünürlük sahəsi (konsumer/aqreqat/sistem).
Dekuplikasiya cədvəli
Колонки: `consumer_id`, `operation_id`, `applied_at`, `ttl_expires_at`.
Indekslər '(consumer_id, operation_id)' üzrə.
TTL maksimum təkrarlama pəncərəsi ≥ (giriş retensiyası + potensial gecikmələr).
Optimist rəqabət
Write modelində aqreqat versiyasını saxlayın.
Hadisə/əmri tətbiq edərkən 'WHERE version =: expected' istifadə edin; dublikat versiyasını artırmayacaq.
Sifariş/sifariş
EOS «tam eyni sifariş» bərabər deyil. Partisiyanın açarı (bütün aqreqat hadisələri → bir partisia) və/və ya 'sequence' müqayisəsi ilə sabitliyi təmin edin.
İdempotent xarici çağırışlar
Təhlükəli metodlar üçün (məsələn, üçüncü tərəf xidmətinə HTTP vebhukları) 'Idempotency-Key' əlavə edin və tərəfdaşın onu dəstəkləməsini tələb edin.
Tez-tez tələlər
EOS yalnız bir yerdə: sink idempotent olarsa, lakin idempotent olmadan ikincil hadisələri buraxırsınızsa, «tam olaraq dəfələrlə» downstream əldə edin.
İki kommit: əvvəlcə DB-də, sonra brokerdə kommit ofset - aralarında düşmə təkrarlanan effektlər yaradır.
Xammal CDC xaricində: DD sxeminin dəyişdirilməsi istehlakçıların idempotentliyini pozur.
Qeyri-sabit açarlar: 'operation _ id' zamandan/randomdan asılıdır və retrada dəyişir.
Dəyər və güzəştlər
Gecikmə: əməliyyatlar/təcrid oxu → p95/p99 artım.
Depolama: dedup cədvəlləri, state stores, əməliyyat qeydləri.
Əməliyyat mürəkkəbliyi: əməliyyatların taymautları, axınların rebalansı, «yapışmış» sessiyalar.
Diaqnostika: daha çox vəziyyət ("kamitdə", "necə read_committed", "yuvarlandı").
EOS nöqtəsini seçin: kritik aqreqatlar və effektlər üçün; qalan hissəni idempotentlik və kompensasiya ilə əhatə edin.
exactly-once test
1. Fault-injection: addımlar arasında prosesin düşməsi «qeyd effekti» və «qeyd ofset».
2. Dublikatlar: Eyni mesajı 2-5 dəfə pompalayın, bir effektə əmin olun.
3. Yenidənqurma və yenidən balans: workerlərin dayandırılması/yenidən başlaması, ikiqat emal olmamasının yoxlanılması.
4. Network Frappy: əməliyyatın ortasında vaxt, kommitin təkrarı.
5. Yükləmə testləri: növbələrin artması → «əməliyyatlarda əbədi olaraq» deqradasiya var.
Mini şablonlar (psevdo)
Ofset fiksasiya ilə idempotent sink
pseudo begin tx if not exists(select 1 from dedup where consumer_id=:c and op_id=:id)
then apply_effect(...) -- upsert / merge / add_one_time_action insert into dedup(c, id, applied_at) values(:c,:id, now)
end if update offsets set pos=:pos where consumer_id=:c commit
Aqreqat versiyası ilə komanda
pseudo begin tx update account set balance = balance +:delta,
version = version + 1 where id=:account_id and version=:expected_version;
if row_count=0 then error CONCURRENT_MODIFICATION commit
Təhlükəsizlik və uyğunluq
Dedup cədvəllərində PII/PCI: minimum saxlayın, «xam» məlumat əvəzinə tokenlərdən istifadə edin.
Audit: 'operation _ id', 'trace _ id', nəticə (APPLIED/ALREADY_APPLIED).
Saxlama siyasəti: Dedup cədvəllərində TTL, ofset/log arxivləşdirilməsi.
Anti-nümunələr
«Real exactly-once çatdırılma»: təsir idempotent olmadan nəqliyyat protokolu səviyyəsində dublları istisna etmək üçün cəhd.
Hər şeyə qlobal paylanmış əməliyyatlar: bütün xidmətlər vasitəsilə XA/2PC - kövrək və yavaş.
Qeyri-idempotent yan təsirlərin qarışdırılması (məsələn, e-mail ofset kommitindən əvvəl göndərilir).
Əməliyyat açarlarının olmaması: faydalı yükün «unikallığına» güvənmək.
Production çek siyahısı
- Hər bir kritik effektdə idempotent açar var.
- Ofset/oxu mövqeyi bir effekt əməliyyatında qeyd olunur.
- Babanın cədvəlləri indeksləşdirilmişdir; TTL ≥ log retensiyası.
- Aqreqatlar üçün optimist rəqabət (versiya/sequence) daxildir.
- Axınlar/topiklər «yalnız gizli» rejimində oxunur (varsa).
- Təkrarlanan və düşmə testləri CI/CD-də mövcuddur.
- Daşbordlar: təkrarlama payı, uğursuz əməliyyatlar, kilidləmə vaxtı, lag.
- «Idempotency-Keu »/təkrarlama/taymaut inteqratorları üçün sənədləşmə.
FAQ
EOS əməliyyatları olmadan təmin edilə bilərmi?
Çox vaxt bəli - sink 'oların idempotentliyi (upsert/merge) və aqreqatların versiyalaşdırılması ilə. Əməliyyatlar zəmanəti asanlaşdırır, lakin dəyəri artırır.
Hər kəsə «exactly-once» lazımdır?
Yox. O, bahalıdır. Kompensasiyanın/yolun mümkün olmadığı yerlərdə nöqtəli tətbiq edin.
EOS ilə e-poçtları/vebhukları necə əlaqələndirmək olar?
Kommitdən əvvəl bildirişi tampon edin, effekti düzəltdikdən sonra göndərin; 'notification _ id' saxlayın və idempotent göndərmə edin.
Daha vacib olan çatdırılma və ya emal?
Emal. Çatdırılma təkrarlana bilər; son vəziyyət düzgün və tək olmalıdır.
Yekun
Exactly-once - bu, naqildə dublların olmaması deyil, effektin düzgünlüyüdür. Bu idempotentlik, atom fiksasiya effekti və mütaliə tərəqqisi, ağlabatan partizanlaşdırma və versiya intizamı birləşməsi ilə əldə edilir. EOS-u səhv dəyərinin qəbuledilməz olduğu yerlərdə tətbiq edin və onun reallığını düşmə və ikiqat testlərlə yoxlayın - nəqliyyata inanmayın.