GH GambleHub

Event Sourcing: asoslari

Event Sourcing nima

Event Sourcing (ES) - bu domen obʼektlarining holatini «joriy satr» koʻrinishida emas, balki sodir boʻlgan hamma narsani tasvirlaydigan oʻzgarmas voqea daftari sifatida saqlash usuli. Agregatning joriy holati uning voqealari bilan bog’lanadi va har qanday o’qish taqdimotlari ushbu jurnalning ustiga proyeksiya sifatida tuziladi.

Asosiy oqibatlar:
  • Tarix - «haqiqatning birlamchi manbai», holat - tarixning bashorati.
  • Har qanday holatni yangidan takrorlash, tekshirish va tushuntirish (audit) mumkin.
  • Yangi tasavvurlar va tahlillarni qo’shish eski «rasmlar» ning ko’chishini talab qilmaydi - voqealarni yo’qotish kifoya.

Bazaviy atamalar

Agregat - aniq invariantlar (Order, Payment, UserBalance) bilan muvofiqlik domen birligi.
Hodisa - oʻtmishda yuz bergan oʻzgarmas holat (’payment. authorized`, `order. shipped`).
Event Store - agregat doirasida voqealar tartibini ta’minlaydigan append-onli jurnali.
Agregat versiyasi - oxirgi qoʻllanilgan hodisa raqami (optimistic concurrency uchun).
Snapshot - o’rashni tezlashtirish uchun davriy holat qolipi.
Proyeksiya (o’qish-model) - o’qish/qidirish/hisobot berish uchun materiallashtirilgan tur (ko’pincha - asinxron).

Bu qanday ishlaydi (buyruqlar oqimi → voqealar → proyeksiyalar)

1. Mijoz buyruqni yuboradi (’CapturePayment’,’PlaceOrder’).
2. Agregat invariantlarni tasdiqlaydi va agar hammasi yaxshi boʻlsa, hodisalarni keltirib chiqaradi.
3. Hodisalar (optimistic concurrency) versiyasini tekshirish bilan Event Store-ga atomik ravishda qoʻshiladi.
4. Proyeksiya protsessorlari voqealar oqimiga obuna bo’lib, o’qish modellarini yangilaydi.
5. Agregatni quyidagi buyruq uchun yuklashda holat tiklanadi: snapshot (agar mavjud boʻlsa) → snapshotdan keyingi voqealar.

Hodisa dizayni

Majburiy atributlar (yadro)

json
{
"event_id": "uuid",
"event_type": "payment. authorized. v1",
"aggregate_type": "Payment",
"aggregate_id": "pay_123",
"aggregate_version": 5,
"occurred_at": "2025-10-31T10:42:03Z",
"payload": { "amount": 1000, "currency": "EUR", "method": "card" },
"meta": { "trace_id": "t-abc", "actor": "user_42" }
}
Tavsiyalar:
  • Nomlanishi:’domain. action. v{major}`.
  • Qo’shimcha: yangi maydonlar - eski ma’nosini o’zgartirmasdan, ixtiyoriy.
  • Minimalizm: faqat faktlar, hech qanday takrorlanmaydigan ma’lumotlar.

Kontraktlar va sxemalar

Sxemalarni tuzating (Euro/JSON Schema/Protobuf) va CI mosligini tekshiring.
«Buzuvchi» o’zgarishlar uchun - voqeaning yangi major versiyasi va migratsiya davrida’v1 ’/’ v2’ning parallel e’lon qilinishi.

Raqobatbardosh foydalanish: optimistic concurrency

Qoida: Agar’expected _ version = = current_version' boʻlsa, yangi voqealarni yozib olish mumkin.

Psevdokod:
pseudo load: snapshot(state, version), then apply events > version new_events = aggregate. handle(command)
append_to_store(aggregate_id, expected_version=current_version, events=new_events)
//if someone has already written an event between load and append, the operation is rejected -> retray with reload

Shunday qilib, biz taqsimlangan tranzaksiyalarsiz invariantlarning yaxlitligini kafolatlaymiz.

Snapshotlar (aylanishni tezlashtirish)

Har bir N voqeani yoki taymer bilan snapshot qiling.
Храните `snapshot_state`, `aggregate_id`, `version`, `created_at`.
Har doim tekshirib turing va snapshotdan keyin yetib oling.
Snapshotlarni uyadan qayta yaratish uchun olib tashlang («sehrli» maydonlarni saqlamang).

Proyeksiyalar va CQRS

ES tabiiy ravishda CQRS bilan birlashadi:
  • Write modeli = agregatlar + Event Store.
  • Read-modellar = voqealar bilan yangilanadigan proyeksiyalar (Redis kartochkalari, qidirish uchun OpenSearch, hisobotlar uchun ClickHouse/OLAP).
  • Proyeksiyalar idempotentdir: bir xil’event _ id’ni qayta ishlash natijani oʻzgartirmaydi.

Sxemalar evolyutsiyasi va mosligi

Additive-first: maydonlarni qoʻshing; turlarni/semantikani o’zgartirmang.
Murakkab o’zgarishlar uchun: yangi turdagi voqealarni chiqaring va projektorlarni yozing.
Oʻtish davri uchun ikki marta (’v1’+’v2’) yozib oling va barcha proyeksiyalar tayyor boʻlganda’v1’ni olib tashlang.

Xavfsizlik, PII va «unutish huquqi»

Tarix ko’pincha sezgir ma’lumotlarni o’z ichiga oladi. Yondashuvlar:
  • Hodisalarda PIIni minimallashtiring (maʼlumotlar oʻrniga identifikatorlar, himoyalangan tomonlarda detallar).
  • Kripto oʻchirish: maydonlarni shifrlang va oʻchirishni soʻrashda kalitni yoʻq qiling (hodisa saqlanib qoladi, ammo maʼlumotlar mavjud emas).
  • ’user. piiredacted. v1’proyeksiyalarda sezgir maydonlarni almashtirish bilan (tarix tahrirlash faktini saqlab qoladi).
  • Retensiya siyosati: baʼzi domenlar uchun voqealarning bir qismini WORM saqlash joyida arxivlash mumkin.

Unumdorlik va masshtablash

Partiyalashtirish: tartib agregat ichida muhim -’aggregate _ id’bo’yicha partiyalashtiring.
Sovuq start: snapshotlar + davriy «zichlovchi» o’rash.
Batch append: voqealarni bitta bitim bilan guruhlang.
Backpressure va DLQ proyeksiya protsessorlari uchun; lag (vaqt va xabar sonini) o’lchang.
Event Store indeksatsiyasi:’(aggregate_type, aggregate_id) va vaqt boʻyicha tez kirish.

Test sinovi

Agregatlar uchun Specification tests: «buyruqlar → kutilayotgan voqealar» skripti.
Projection tests: hodisalar oqimini koʻrsating va materiallashtirilgan holat/indekslarni tekshiring.
Replayability tests: stenddagi «noldan» proyeksiyalarni qayta saralab oling - natija mos kelishiga ishonch hosil qiling.
Chaos/latency: kechikishlar va dubllarni injektatsiya qiling, idempotentlikni tekshiring.

Domen namunalari

1) To’lovlar

Hodisalar:’payment. initiated`, `payment. authorized`, `payment. captured`, `payment. refunded`.
Invariantlar:’capture’bilan’authorized’; summalar salbiy emas; valyuta o’zgarmaydi.
Proyeksiyalar: «to’lov kartochkasi» (KV), tranzaksiyalarni qidirish (OpenSearch), hisobot (OLAP).

2) Buyurtmalar (e-commerce)

Hodisalar:’order. placed`, `order. paid`, `order. packed`, `order. shipped`, `order. delivered`.
Invariantlar: holatlar diagrammasi bo’yicha maqom o’tishlari; ’shipped’ gacha bekor qilinishi mumkin.
Proyeksiyalar: foydalanuvchi buyurtmalari ro’yxati, maqomi bo’yicha SLA-dashbordlar.

3) Balanslar (moliya/iGaming)

Hodisalar:’balance. deposited`, `balance. debited`, `balance. credited`, `balance. adjusted`.
Qattiq invariant: balans <0; buyruqlar’operation _ id’boʻyicha idempotentdir.
Tanqidiy operatsiyalar to’g «ridan to’g» ri agregatdan (qat’iy muvofiqlik), UI proyeksiyadan (eventual) o’qiladi.

Event Store namunaviy tuzilmasi (DB bilan variant)

events

`event_id (PK)`, `aggregate_type`, `aggregate_id`, `version`, `occurred_at`, `event_type`, `payload`, `meta`

Indeks:’(aggregate_type, aggregate_id, version)’.

snapshots

`aggregate_type`, `aggregate_id`, `version`, `state`, `created_at`

Indeks:’(aggregate_type, aggregate_id)’.

consumers_offsets

’consumer _ id’,’event _ id ’/’ position’,’updated _ at’(proyeksiya va retlay uchun).

Tez-tez savollar (SSS)

ES hamma joyda ishlatilishi kerakmi?
Yo’q. ES muhim audit, murakkab invariantlar, takrorlanuvchanlik va turli xil ma’lumotlar taqdim etilganda foydalidir. Oddiy CRUD uchun bu ortiqcha.

«Dolzarb holat» soʻrovlari haqida nima deyish mumkin?
Yoki proyeksiyadan (tez, eventual) yoki agregatdan (qimmatroq, lekin qat’iy) o’qing. Tanqidiy operatsiyalar odatda ikkinchi yo’ldan foydalanadi.

Kafka/strim brokeri kerakmi?
Event Store - haqiqat manbai; broker voqealarni loyihachilar va tashqi tizimlarga tarqatish uchun qulay.

«Unutish huquqi» bilan nima qilish kerak?
PII ni minimallashtirish, sezgir maydonlarni shifrlash va proyeksiyalarda kripto-o’chirish/tahririyatni qo’llash.

Eski maʼlumotlarni qanday koʻchirish mumkin?
Voqealarni retrospektiv ishlab chiqarish skriptini yozing yoki «holat-qanday» bilan boshlang va voqealarni faqat yangi o’zgarishlar uchun nashr qiling.

Antipatternlar

Event Sourcing «odat bo’yicha»: domensiz tizimni murakkablashtiradi.
Fat events: PII va dublli shishirilgan payload’lar - tormozlar va komplayens muammolari.
Optimistik concurrency yo’qligi: poygalarda invariantlarning yo’qolishi.
Qayta ishlab chiqarilmaydigan proyeksiyalar: replay/snapshotlar yo’q → qo’l fikslari.
Xom CDC domen hodisalari sifatida: DB sxemalarining chiqib ketishi va qattiq aloqa.
Ichki va integratsiya voqealarini aralashtirish: barqaror «vitrin» ni nashr qiling.

Ishlab chiqarish uchun chek-varaq

  • Agregatlar, invariantlar va hodisalar (nomlar, versiyalar, sxemalar) aniqlandi.
  • Event Store agregat va optimistic concurrency doirasida tartibni ta’minlaydi.
  • Snapshotlar va ularni qayta qurish rejasi kiritilgan.
  • Proyeksiyalar idempotent, DLQ va lag metrikalari mavjud.
  • Sxemalar CI da tasdiqlanadi, versiyalar siyosati - hujjatlashtirilgan.
  • PII minimallashtirilgan, maydonlar shifrlangan, «unutish» strategiyasi mavjud.
  • Proyeksiyalarning takrorlanishi stendda tekshirilgan; avariya holatida tiklash rejasi mavjud.
  • Dashbordlar: appendning tezligi, lag proyeksiyalari, qo’llash xatolari, retraylarning ulushi.

Jami

Event Sourcing tizimning tarixini birinchi darajali artefaktga aylantiradi: biz faktlarni yozib olamiz, ularning holatini takrorlaymiz va har qanday tasavvurni bemalol yaratamiz. Bu audit, o’zgarishlarga chidamlilik va tahlilning moslashuvchanligini ta’minlaydi - sxemalarda intizom, raqobat nazorati va sezgir ma’lumotlar bilan savodli ishlash sharti bilan.

Contact

Biz bilan bog‘laning

Har qanday savol yoki yordam bo‘yicha bizga murojaat qiling.Doimo yordam berishga tayyormiz.

Integratsiyani boshlash

Email — majburiy. Telegram yoki WhatsApp — ixtiyoriy.

Ismingiz ixtiyoriy
Email ixtiyoriy
Mavzu ixtiyoriy
Xabar ixtiyoriy
Telegram ixtiyoriy
@
Agar Telegram qoldirilgan bo‘lsa — javob Email bilan birga o‘sha yerga ham yuboriladi.
WhatsApp ixtiyoriy
Format: mamlakat kodi va raqam (masalan, +998XXXXXXXX).

Yuborish orqali ma'lumotlaringiz qayta ishlanishiga rozilik bildirasiz.