GH GambleHub

Event Sourcing: Հիմքեր

Ի՞ նչ է Event Sourcing-ը

Event Sourcing-ը (ES) հիբրիդային օբյեկտների վիճակը պահելու միջոց է ոչ թե «ներկա տողի» տեսքով, այլ որպես իրադարձությունների անփոփոխ ամսագիր, որը նկարագրում է այն ամենը, ինչ տեղի ունեցավ։ Ագրեգատի ներկա վիճակը ստացվում է նրա իրադարձությունների մի փաթեթ (replay), իսկ կարդալու համար ցանկացած ներկայացում կառուցվում է որպես կանխատեսումներ այս ամսագրի վերևում։

Հիմնական սկզբունքները

Պատմությունը «ճշմարտության առաջնային աղբյուրն է», վիճակը պատմության պրոյեկտն է։

Ցանկացած վիճակ կարող է վերարտադրվել, ստուգել և բացատրել (աուդիտ)։

Նոր ներկայացումների ավելացումը և վերլուծաբանները չեն պահանջում հին «նկարներ», բավական է կորցնել իրադարձությունները։

Հիմնական տերմինները

Ագրեգատը էքսպորտային միավորն է, որն ունի հստակ ինվարանտներ (Order, Payment, UserBalts)։

Իրադարձությունը անփոփոխ փաստ է, որը տեղի ունեցավ անցյալում («payment»)։ authorized`, `order. shipped`).

Event Store-ը append-onley ամսագիրն է, որն ապահովում է իրադարձությունների կարգը ագրեգատի սահմաններում։

Ագրեգատի տարբերակը վերջին օգտագործված իրադարձության թիվ է (optimistic concurrency)։

Կեղտաջրերը պետության պարբերական կույր են, որպեսզի արագացնեն այն։

Պրոյեկցիան (read-մոդել) նյութականացված տեսք է կարդալու/որոնելու/հաշվետվության համար (հաճախ ասինխրոն)։

Ինչպե՞ ս է այն աշխատում (թիմերի հոսքը ռուսական պրոյեկտների իրադարձություններին)

1. Հաճախորդը ուղարկում է թիմը («Captom Payment», «Plant Order»)։

2. Ագրեգատը առաջնորդում է ինվարանտները, և եթե ամեն ինչ տեղի է ունենում, տեղի է ունենում։

3. Ատոմային իրադարձությունները ավելացվում են Event Store-ում տարբերակի ստուգմամբ (optimistic concurrency)։

4. Պրոյեկտների իրականացումը ստորագրվել է իրադարձությունների հոսքի վրա և թարմացնում է read մոդելները։

5. Հաջորդ թիմի համար ագրեգատը բեռնելիս վիճակը վերականգնվում է 'դիպուկահարները (եթե կա) ռուսական իրադարձություններ են դիպուկից հետո։

Իրադարձությունների դիզայն

Պարտադիր ատրիբուտներ (միջուկ)

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" }
}

Առաջարկություններ

Անունը '"domain. action. v{major}`.

Addimation 'նոր դաշտերը օբյեկտիվ են, առանց հին իմաստի փոփոխության։

Մինիմալիզմ 'միայն փաստերը, առանց հեշտությամբ վերականգնվող տվյալների։

Պայմանագրեր և սխեմաներ

Գրանցեք սխեմաները (Avro/JSON Schema/Delobuf) և ստուգեք CI-ի համատեղելիությունը։

«Կոտրող» փոփոխությունների համար իրադարձության նոր մաժոր տարբերակն է և զուգահեռ հրատարակումը '«v1 »/« v2» ժամանակահատվածի համար։

Մրցակցային հասանելիություն 'optimistic concurrency

Նոր իրադարձությունների ձայնագրումը հնարավոր է միայն եթե «expected _ version = = = current _ version»։

Prindocod

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

Այսպիսով, մենք երաշխավորում ենք ինվարանտների ամբողջականությունը առանց բաշխված գործարքների։

Դիպուկահարներ (արագացում)

Վերցրեք յուրաքանչյուր N իրադարձության կափարիչը կամ թայմերը։

Храните `snapshot_state`, `aggregate_id`, `version`, `created_at`.

Միշտ ստուգեք և վերցրեք իրադարձությունները կեղևից հետո (մի վստահեք միայն կույր)։

Վերցրեք կեղտաջրերը այնպես, որ դրանք կարողանան վերազինել հատակից (մի պահեք «կախարդական» դաշտերը)։

Պրոյեկտներ և CQRS

ES-ը բնականաբար զուգորդվում է CQRS-ի հետ

Write-մոդելը = միավորներ + Event Store։

Read-մոդելներ = պրոյեկտներ, որոնք թարմացվում են իրադարձություններով (Redis քարտ, OpenSearch, որոնման համար, ClickHouse/OLAP մրցույթի համար)։

Idempotent պրոյեկտները 'նույն «event _ id» -ի վերարտադրումը չի փոխում արդյունքը։

Սխեմաների էվոլյուցիան և համատեղելիությունը

Delitive-first 'ավելացրեք դաշտերը։ մի փոխեք տեսակները/սեմանտիկան։

Բարդ փոփոխությունների համար 'նոր տեսակի իրադարձություններ արտադրեք և գրեք պրոյեկտորների բաղադրիչներ։

Աջակցեք կրկնակի ձայնագրությանը («v1 '+' v2») անցումային ժամանակահատվածում և նկարահանեք «v1», երբ բոլոր պրոյեկտները պատրաստ են։

Անվտանգություն, PII և «մոռացման իրավունք»

Պատմությունը հաճախ պարունակում է զգայուն տվյալներ։ Մոտեցումներ

Microsoft PII-ը իրադարձությունների մեջ (ցուցիչներ տվյալների փոխարեն, մանրամասները պաշտպանված կողմերում)։

Ծպտյալ լվացք 'ծածկագրեք դաշտերը և պահանջեք, որ լուծեք բանալին (իրադարձությունը մնում է, բայց տվյալները անհասանելի են)։

Իրադարձություններ-2019: 'user. piiredacted. v1 '' զգայուն դաշտերը պրոյեկտներում փոխարինելով (պատմությունը պահպանում է խմբագրման փաստը)։

Ռեթենացիայի քաղաքականությունները. Որոշ ֆորումների համար իրադարձությունների մի մասը կարելի է արխիվացնել WORM-2019-ում։

Արտադրողականություն և մեծացում

Կուսակցությունը 'կարգը կարևոր է ագրեգատի ներսում' նվագակցեք «aggregate _ id»։

Սառը սկիզբը 'կեղտաջրերը + պարբերական «բազմապատկող»։

Batch Append 'խմբավորել իրադարձությունները մեկ գործարքով։

Backpressure և DLQ պրոյեկտների համար։ չափեք լամպը (ժամանակը և հաղորդագրությունների քանակը)։

Event Store ինդեքսավորումը 'արագ մուտք' (aggregate _ type, aggregate _ id) և ժամանակի ընթացքում։

Թեստավորում

Speciforment tes.ru-ը ագրեգատների համար '«թիմերը կանխատեսելի իրադարձություններ են» սցենարը։

Projw.tes.ru: Դարձրեք իրադարձությունների հոսքը և հաստատեք նյութականացված վիճակը/ինդեքսները։

Replayability tes.ru-ը 'հատեք «զրոյի» պրոյեկտները պատին, համոզվեք, որ արդյունքը համընկնում է։

Chaos/latency: Ներարկեք հետաձգումներ և կրկնապատկումներ, ստուգեք կուռքերը։

Օրինակների օրինակներ

1) Վճարումներ

Իրադարձությունները '<pay.ru։ initiated`, `payment. authorized`, `payment. captured`, `payment. refunded`.

Invariants: Դուք չեք կարող «capture» առանց «authorized»; գումարը ոչ բացասական է. արժույթը անփոփոխ է։

Պրոյեկտներ ՝ «մրցույթի քարտը» (KV), գործարքների որոնումը (OpenSearch), հաշվետվությունները (OLAP)։

2) Պատվերներ (e-commerce)

Իրադարձությունները 'order. placed`, `order. paid`, `order. packed`, `order. shipped`, `order. delivered`.

Invariants 'պետական դիագրամում ստատուսների անցում; վերացումը հնարավոր է մինչև «shipped»։

Պրոյեկտներ 'օգտագործողի պատվերների ցանկը, SLA-dashbords կարգավիճակների վրա։

3) Հավասարակշռություններ (ֆինանսներ/iGaming)

Իրադարձությունները '"bal.ru. deposited`, `balance. debited`, `balance. credited`, `balance. adjusted`.

Կոշտ ինվարանտը 'հավասարակշռությունը չի հեռանում <0; հրամաններ են «operation _ id»։

Կրիտիկական վիրահատությունները կարդում են հենց ագրեգատից (խիստ համաձայնություն), UI-ից 'պրոյեկտից (eventae)։

Event Store-ի տիպային կառուցվածքը (տարբերակը BD-ից)

events

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

Ինդեքսը ՝ «(aggregate _ type, aggregate _ id, version)»։

snapshots

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

Ինդեքսը ՝ «(aggregate _ type, aggregate _ id)»։

consumers_offsets

«consumer _ id», «event _ id »/« pos.ru», «contated _ at» (պրոյեկցիաների և ռետրլեյի համար)։

Հաճախակի հարցեր (FAQ)

Արդյո՞ ք պետք է օգտագործել ES-ը ամենուր։

Ոչ։ ES-ը օգտակար է, երբ կարևոր են աուդիտը, բարդ ինվարիատները, վերարտադրողականությունը և տվյալների տարբեր ներկայացումները։ Պարզ CRUD-ի համար դա չափազանց մեծ է։

Ինչպե՞ ս լինել «իրական վիճակի» պահանջների հետ։

Կամ պատրաստված է պրոյեկցիայից (արագ, eventae) կամ ագրեգատից (ավելի թանկ, բայց խիստ)։ Կրիտիկական վիրահատությունները սովորաբար օգտագործում են երկրորդ ճանապարհը։

Արդյո՞ ք Kafka/strem-brocker-ը կարիք ունի։

Event Store-ը ճշմարտության աղբյուրն է։ բրոքերը հարմար է իրադարձությունների տարածման համար պրոյեկտորների և արտաքին համակարգերի համար։

Ի՞ նչ անել «մոռացության իրավունքի» հետ։

Նվազագույնի հասցնել PII-ը, ծածկել զգայուն դաշտերը և օգտագործել ծպտյալ լվացում/խմբագրություն նախագծերում։

Ինչպե՞ ս հին տվյալները գաղթել։

Գրեք հետադարձ կապ ունեցող իրադարձությունների մասին («re-hestori») կամ սկսեք «վիճակից» և հրապարակեք իրադարձությունները միայն նոր փոփոխությունների համար։

Antipatterny

Event Sourcing-ը «սովորությամբ» բարդացնում է համակարգը առանց հիբրիդային օգուտների։

Fat events: բաժանված payload 'a PII-ի և դուբլների հետ' արգելակներ և կոմպլանսի խնդիրներ։

Optimistic concurrency-ի բացակայությունը 'ինվարանտների կորցումը մրցավազքում։

Ոչ ոգեշնչող պրոյեկտներ. Ոչ մի ռեփլե/դիպուկահարներ չկան։

Հում CDC-ն որպես հիբրիդային իրադարձություններ 'BD սխեմաների արտահոսք և կոշտ կապ։

Ներքին և ինտեգրացիոն իրադարձությունների խառնուրդը 'հրապարակեք կայունացված «վիտրինը»։

Chek Lister-ը վաճառելու համար

  • Հայտնաբերվել են ագրեգատները, ինվարանտները և իրադարձությունները (անուններ, տարբերակներ, սխեմաներ)։
  • Event Store-ը կարգավորում է ագրեգատի և optimistic concurrency-ի սահմաններում։
  • Միացեք կեղևները և դրանց վերամշակման պլանը։
  • Idempotent պրոյեկտները, կան DLQ և լագայի չափումներ։
  • Սխեմաները վալիդացվում են CI-ի վրա, տարբերակների քաղաքականությունը փաստագրված է։
  • PII նվազագույն է, դաշտերը կոդավորված են, կա «մոռացման» ռազմավարություն։
  • Պրոյեկցիաների ռեպլեյը ստուգված է պատին; վերականգնման ծրագիր կա։
  • Dashbords: Appenda արագություն, պրոյեկցիաների լագը, օգտագործման սխալները, գետերի մասնաբաժինը։

Արդյունքը

Event Sourcing-ը ստեղծում է համակարգի պատմությունը առաջին կարգի արտեֆակտով, մենք արձանագրում ենք փաստերը, դրանցից մենք վերարտադրում ենք վիճակը և ազատորեն կառուցում ենք ցանկացած ներկայացում։ Սա տալիս է աուդիտ, փոփոխությունների դիմադրություն և վերլուծության ճկունություն 'ենթակա սխեմաների, մրցակցային վերահսկման և զգայուն տվյալների հետ աշխատելուն։

Contact

Կապ հաստատեք մեզ հետ

Կապ հաստատեք մեզ հետ ցանկացած հարցի կամ աջակցության համար։Մենք միշտ պատրաստ ենք օգնել։

Սկսել ինտեգրացիան

Email-ը՝ պարտադիր է։ Telegram կամ WhatsApp — ըստ ցանկության։

Ձեր անունը ըստ ցանկության
Email ըստ ցանկության
Թեմա ըստ ցանկության
Նամակի բովանդակություն ըստ ցանկության
Telegram ըստ ցանկության
@
Եթե նշեք Telegram — մենք կպատասխանենք նաև այնտեղ՝ Email-ի дополнение-ով։
WhatsApp ըստ ցանկության
Ձևաչափ՝ երկրի կոդ և համար (օրինակ՝ +374XXXXXXXXX)։

Սեղմելով կոճակը՝ դուք համաձայնում եք տվյալների մշակման հետ։