Idempotentlik va kalitlar
Idempotentlik nima
Idempotentlik - xuddi shu identifikator bilan takrorlash yakuniy samarani o’zgartirmaydigan operatsiya xususiyatidir. Taqsimlangan tizimlarda bu natijani retrajlar, xabarlarning dublikatlari va taymautlarga qaramay, «aynan bitta ishlov berish» ga tenglashtirishning asosiy usulidir.
Asosiy g’oya: har bir potentsial takrorlanadigan operatsiya tizim «buni allaqachon qilgan» deb tan oladigan va natijani ko’pi bilan bir marta qo’llaydigan kalit bilan belgilanishi kerak.
Qayerda muhim
To’lovlar va balanslar:’operation _ id’bo’yicha hisobdan chiqarish/o’tkazish.
Bron qilish/kvotalar/limitlar: bir xil slot/resurs.
Vebxuki/ogohlantirishlar: Qayta yetkazib berish samarani takrorlamasligi kerak.
Import/migratsiya: fayllar/paketlarni takrorlash.
Strim-protsessing: broker/CDC dublikatlari.
Kalitlarning turlari va ularning amal qilish sohasi
1. Operation key - biznes-operatsiyaning aniq urinish identifikatori
Masalan:’idempotency _ key’(HTTP),’operation _ id’(RPC).
Viloyat: servis/agregat; duplikatsiya jadvalida saqlanadi.
2. Event key - voqea/xabarning noyob identifikatori
Namunalar:’event _ id’(UUID),’(producer_id, sequence)’.
Viloyat: iste’molchi/iste’molchilar guruhi; proyeksiyalarni himoya qiladi.
3. Business key - fan sohasining tabiiy kaliti
Namunalar:’payment _ id’,’invoice _ number’,’(user_id, day)’.
Viloyat: agregat; o’ziga xoslik/versiya tekshiruvlarida qo’llaniladi.
TTL va saqlash siyosati
TTL kalitlari ≥ mumkin boʻlgan takrorlash oynasi: logning retentsiyasi + tarmoq/jarayon kechikishlari.
Kritik domenlar (to’lovlar) uchun TTL - kunlar/haftalar; telemetriya uchun - soat.
Dedup jadvallarni joblar bilan tozalang; audit uchun - arxivlang.
Kalitlar ombori (deduplikatsiya)
Tranzaksion DB (tavsiya etiladi): ishonchli upsert/unique-indekslar, effektli birgalikda tranzaksiya.
KV/Redis: tez, qisqa TTL uchun qulay, lekin OLTP bilan qo’shma tranzaksiyasiz - ehtiyot bo’ling.
State store strim-protsessor: lokal + brokerdagi cheynjlog; Flink/KStreams’da yaxshi.
- idempotency_keys
`consumer_id` (или `service`), `op_id` (PK на пару), `applied_at`, `ttl_expires_at`, `result_hash`/`response_status` (опц.) .
Indekslar:’(consumer_id, op_id)’- noyob.
Amalga oshirishning bazaviy usullari
1) «Effekt + taraqqiyot» tranzaksiyasi
Natijani yozish va o’qish/pozitsiya taraqqiyotini qayd etish - bitta tranzaksiyada.
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 (agregat versiyasi)
Poygalarda ikki tomonlama effektdan himoya qiladi: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) Idempotent sinks (upsert/merge)
«Bir marta hisoblash» operatsiyasi:sql insert into bonuses(user_id, op_id, amount)
values(:u,:op,:amt)
on conflict (user_id, op_id) do nothing;
Protokollardagi idempotentlik
HTTP/REST
’Idempotency-Key’ sarlavhasi: <uid’hash>’.
Server kalit yozuvini saqlaydi va xuddi shu javobni qaytaradi (yoki invariantlar toʻqnashganda’409 ’/’ 422’kodi).
«Xavfli» POST uchun - majburiy’Idempotency-Key’+ barqaror taymout/retray-siyosat.
gRPC/RPC
Meta maʼlumotlar’idempotency _ key’,’request _ id’+ deadline.
Server amalga oshirish - xuddi RESTdagi kabi: tranzaksiyadagi dedup jadvali.
Brokerlar/striming (Kafka/NATS/Pulsar)
Prodyuser: barqaror’event _ id ’/idempotent prodyuser (u yerda qo’llab-quvvatlanadi).
Konsumer: «(consumer_id, event_id)» va/yoki agregatning biznes-versiyasi bo’yicha dedup.
Indempotent bo’lmagan/shikastlangan xabarlar uchun alohida DLQ.
Vebxuklar va tashqi sheriklar
Kontraktda’Idempotency-Key ’/’ event _ id’ni talab qiling; qayta yetkazib berish xavfsiz bo’lishi kerak.
’notification _ id’ va joʻnatish maqomlarini saqlang; retrada - takrorlamang.
Kalitlarni loyihalash
Determinatsiya: retrajlar xuddi shu kalitni yuborishi kerak (oldindan mijoz/orkestratorda ishlab chiqaring).
Koʻrinish maydoni:’op _ id’ni’service: aggregate: id: purpose’sifatida shakllantiring.
Qarama-qarshiliklar: UUIDv7/ULID yoki biznes parametrlari xeshidan foydalaning (kerak bo’lganda tuz bilan).
Ierarxiya: frontdagi umumiy’operation _ id’→ barcha kichik operatsiyalarda (idempotent zanjiri) translyatsiya qilinadi.
UX va mahsulot jihatlari
Kalit boʻyicha takroriy soʻrov xuddi shu natijani (shu jumladan tana/maqom) yoki aniq «allaqachon bajarilgan» ni qaytarishi kerak.
Muvaffaqiyatli boʻlish uchun takrorlash oʻrniga, foydalanuvchiga «operatsiya bajarilmoqda/tugallanmoqda» holatini koʻrsating.
Uzoq muddatli operatsiyalar uchun - kalit bo’yicha polling (’GET/operations/{ op _ id}’).
Kuzatish
’op _ id’,’event _ id’,’trace _ id’, natijasi:’APPLIED ’/’ ALREADY _ APPLIED’.
Metrika: takrorlash ulushi, dedup jadvallar hajmi, tranzaksiya vaqti, versiyalar ziddiyatlari, DLQ-stavka.
Trace: kalit buyruq orqali o’tishi kerak → hodisa → proyeksiya → tashqi chaqiruv.
Xavfsizlik va komplayens
PIIni kalitlarda saqlamang; kalit - identifikator, payload emas.
Uzoq davom etadigan TTLda dedup yozuvlaridagi sezgir maydonlarni shifrlang.
Saqlash siyosati: TTL va arxivlar; unutish huquqi - javoblarni/meta-ma’lumotlarni kripto-o’chirish orqali (agar ularda PII mavjud bo’lsa).
Test sinovi
1. Dublikatlar: bitta xabar/so’rovni 2-5 marta uzatish - samarasi bir xil.
2. Effektni yozishdan oldin/keyin, ofsetni tuzatishdan oldin/keyin qadamlar orasiga tushish.
3. Restart/isteʼmolchilar balansi: ikki marta qoʻllanilmaydi.
4. Raqobat: bitta’op _ id’bilan parallel so’rovlar → bitta effekt, ikkinchisi -’ALREADY _ APPLIED/409’.
5. Uzoq davom etadigan kalitlar: TTL va qayta tiklangandan keyin tugashini tekshirish.
Antipatternlar
Har bir retraj uchun tasodifiy yangi kalit: tizim takrorlashni tanimaydi.
Ikkita alohida kommita: avval effekt, keyin ofset - ular orasidagi yiqilish effektni takrorlaydi.
Faqat brokerga ishonch: ko’k/agregatda bobning yo’qligi.
Agregat versiyasi mavjud emas: takroriy hodisa holatni ikkinchi marta oʻzgartiradi.
Fat keys: kalit biznes maydonlarini/PII → oqish va murakkab indekslarni o’z ichiga oladi.
Takrorlanadigan javoblar mavjud emas: mijoz xavfsiz ravishda retraj qila olmaydi.
Namunalar
To’lov POST
Mijoz:’POST/payments’+’Idempotency-Key: k-789’.
Server: tranzaksiya -’payment’va’idempotency _ keys’yozuvlarini yaratadi.
Takrorlash: xuddi shu’201 ’/tanani qaytaradi; invarant to’qnashuvida -’409’.
Bonusni hisoblash (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;
Voqealardan proyeksiya
Konsumer agregatning’seen (event_id)’va’version’ni saqlaydi; takrorlash - ignor/idempotent upsert.
O’qish jarayoni proyeksiyani yangilash bilan bir xil tranzaksiyada qayd etiladi.
Ishlab chiqarish chek-varaqasi
- Barcha xavfli operatsiyalar uchun idempotent kaliti va uning ko’rinish maydoni belgilangan.
- TTL va noyob indeksli dedup jadvallari mavjud.
- O’qish samarasi va taraqqiyoti atomik jihatdan birlashtiriladi.
- Write-modelda optimistik raqobat mavjud (versiya/sequence).
- API shartnomalari’Idempotency-Key ’/’ operation _ id’va takrorlash xatti-harakatlarini qayd etadi.
- Metrika va loglarda’op _ id ’/’ event _ id ’/’ trace _ id’mavjud.
- Dublikatlar, yiqilish va poygalar uchun testlar - CI.
- TTL/arxiv siyosatiga va PII xavfsizligiga rioya qilingan.
FAQ
’Idempotency-Key’ ning’Request-Id’dan farqi nimada?
«Request-Id» - trastirovka; u retrajlarda o’zgarishi mumkin.’Idempotency-Key’- operatsiyaning semantik identifikatori, takrorlashda bir xil bo’lishi shart.
DBsiz idempotentlik qilish mumkinmi?
Qisqa oyna uchun - ha (Redis/protsessual kesh), lekin birgalikda tranzaksiyasiz dubl xavfi ortadi. Tanqidiy domenlarda - bitta BD tranzaksiyasida yaxshiroq.
Tashqi hamkorlar bilan nima qilish kerak?
Kalitlar va takroriy javoblar haqida kelishib oling. Agar sherik qo’llab-quvvatlamasa, qo’ng’iroqni idempotent qatlamingizga aylantiring va «allaqachon qo’llanilgan» ni saqlang.
TTLni qanday tanlash kerak?
Maksimal kechikishlarni jamlang: log retensiyasi + worst-case tarmoq/rebalance + bufer. Zaxirani qoʻshing (× 2).
Jami
Idempotentlik - bu kalitlar, tranzaktsiyalar va versiyalar intizomi. Operatsiyalarning barqaror identifikatorlari + o’qish effekti va taraqqiyotining atomik belgilanishi + idempotent sinks/proyeksiyalari transport darajasidagi sehrsiz «aynan bir ta’sir» beradi. Kalitlarni determinizatsiya qiling, TTLni realistik va testlarni zararli qiling. Shunda retrajlar va dublikatlar hodisalar emas, balki odatiy holga aylanadi.