Сага-паттерн және бөлінген транзакциялар
Сага-паттерн және бөлінген транзакциялар
1) Сағалар не үшін қажет
Классикалық 2PC (екі фазалы фиксация) нашар масштабталады, істен шығулар кезінде күрделі және ресурстарды бұғаттайды. Сага жалпы бизнес-процесті жергілікті транзакциялардың (қадамдардың) бірізділігіне бөледі, олардың әрқайсысы тәуелсіз қосылады. Жаңылыс кезінде келесі қадамдар алынып тасталады, ал орындалған қадамдар кері операциялармен өтеледі.
Нәтиже: жаһандық бұғаттаусыз басқарылатын eventual consistency, жоғары өміршеңдік және нақты қалпына келтіру хаттамасы.
2) Базалық модельдер
2. 1 Оркестрлеу
Таңдалған сага үйлестірушісі қадамдарды басқарады: командаларды жібереді, жауаптар/оқиғаларды күтеді, өтемақыларды бастайды.
Артықшылықтары: орталықтандырылған бақылау, қарапайым бақылау, айқын мерзім. Кемшіліктері: қосымша компонент.
2. 2 Хореография
Үйлестіруші жоқ; сервистер бір-бірінің оқиғаларына жауап береді («OrderPlaced» → «PaymentCaptured» → «InventoryReserved»...).
Артықшылықтары: әлсіз байланыстылығы. Минустар: нақты ережесіз «өлім билеу» қаупін қадағалау қиынырақ.
2. 3 TCC (Try-Confirm/Cancel)
Ресурстарды «мұздату» нұсқасы:1. Try - дайындық/резерв,
2. Confirm - бекіту,
3. Cancel - кері қайтару.
Кепілдіктер жоғары, бірақ келісімшарттар мен резервтер таймауттары күрделірек.
3) Қадамдар мен өтемақылар келісімшарттары
Әрбір қадам = жергілікті транзакция + өтемақы (іспеттес, қайталауға жол береді).
Өтемақы толығымен «әлемді қайтаруға» міндетті емес - домендік балама жеткілікті (мысалы, «төлемді жою» орнына «қайтаруды төлеу»).
Инварианттарды анықтаңыз: ақша үшін - баланс минусқа кетпейді; тапсырыстар үшін - «ілінген» мәртебелер жоқ.
Мерзімі өткен әрекеттер үшін/TTL резервтерін және «garbage collector» енгізіңіз.
4) Келісімділік және жеткізу семантикасы
Хабарламаларды жеткізу: at-least-once (дефолт) → барлық операциялар іспеттес болуы тиіс.
Тәртіп: корреляциялық кілт бойынша маңызды (мысалы, 'order _ id', 'player _ id').
Exactly-once - сағаның мақсаты емес; іспеттес кілттер, outbox/inbox және дұрыс коммитирлеу арқылы тиімді біркелкілікке қол жеткіземіз.
5) Сағаның жай-күйі және оның
Не сақтау керек:- 'saga _ id', 'correlation _ id', ағымдағы күйі (Running/Completed/Compensating/Compensated/Failed),
- қадам және оның ауыспалы (төлемдердің/резервтердің IDs),
- оқиғалар/шешімдер тарихы (журналы), таймстемптер, мерзім, ретрайлер саны.
- Үйлестірушіге қол жетімді жеке Saga Store (кесте/құжат).
- Хореография үшін - дастанның жергілікті «агенттері» мәртебе оқиғаларын жалпы топикке жариялайды.
6) Сенімді жариялау үлгілері: outbox/inbox
Outbox: қадамы өзгерістерді жинақтайды және оқиғаны/пәрменді бір транзакцияда outbox кестесіне жазады; воркер шинаға жариялайды.
Inbox: тұтынушы өңделген 'message _ id' → дедуп + идемпотенттік кестесін жүргізеді.
Сәтті жанама әсерден кейін коммитим offset/ACK (Kafka/RabbitMQ) - бұрын емес.
7) Сага қадамдарын жобалау
7. 1 Мысал (iGaming/e-commerce сатып алу)
1. PlaceOrder → 'PENDING' мәртебесі.
2. AuthorizePayment (Try) → `payment_hold_id`.
3. ReserveInventory → `reservation_id`.
4. CapturePayment (Confirm).
5. FinalizeOrder → `COMPLETED`.
- егер (3) сәтсіз болса → 'CancelPaymentHold';
- егер (4) (3) → 'ReleaseInventory' кейін сәтсіз болса;
- егер (5) → 'RefundPayment' және 'ReleaseInventory' сәтсіз болса.
7. 2 Мерзімдік/Ретраялар
Экспоненциалды кідірісі бар максималды N ретраев + джиттер.
Асып кеткеннен кейін - 'Compensating' дегенге өту.
Әрбір қадам үшін next_attempt_at мен deadline_at сақтаңыз.
8) Оркестратор vs платформа
Нұсқалар:- Жеңіл үй оркестрі (микросервис + Saga кестесі).
- Платформалар: Temporal/Cadence, Camunda, Netflix Conductor, Zeebe - таймерлер, ретрайлер, ұзақ өмір сүретін воркфлоу, көріну және веб-консоль береді.
- Хореография үшін оқиғалар каталогын және мәртебе/кілттер туралы қатаң келісімді пайдаланыңыз.
9) Интеграция хаттамалары
9. 1 Асинхронды (Kafka/RabbitMQ)
'payments. authorize. v1`, `inventory. reserve. v1`.
Оқиғалар: 'payments. authorized. v1`, `inventory. reserved. v1`, `payments. captured. v1`, `payments. refunded. v1`.
Партия кілті = 'order _ id '/' player _ id' үшін.
9. 2 Қадамның ішіндегі синхронды (HTTP/gRPC)
«Қысқа» қадамдар үшін рұқсат етіледі, бірақ әрқашан таймауттармен/ретралармен/демпотенттілікпен және асинхронды өтемақыға fallback.
10) Теңсіздік және кілттер
Командалар мен өтемақылар сұрауларында 'idempotency _ key' дегенді беріңіз.
Жанама әсерлер (ДБ-ға жазу/есептен шығару) шартты түрде орындалады: «егер 'idempotency _ key' әлі көрмесе орындау».
Өтемақылар да бірдей: 'RefundPayment (id = X)' қайталауы қауіпсіз.
11) Қателерді өңдеу
Сыныптар:- Transient (желілер/таймауттар) → ретраи/backoff.
- Business (жеткілікті қаражат, лимиттер) → шұғыл өтемақы/балама жол.
- Irrecoverable (инварианттың бұзылуы) → қолмен араласу, «қолмен» өтемақы.
- Шешім матрицасын жасаңыз: қате түрі → әрекет (retry/compensate/escalate).
12) Бақылау және SLO саг
SLI/SLO:- End-to-end latency сагасы (p50/p95/p99).
- Success rate (өтемақысыз аяқталғандар үлесі).
- Mean time to compensate и compensation rate.
- Orphaned sagas (аспалы) және GC дейінгі уақыт.
- 'trace _ id '/' saga _ id' қадамдар арасындағы span link ретінде; қате бюджеттеріне арналған burn-rate өлшемдері.
Логи: саған мәртебесінің әрбір ауысуы = себебімен құрылымдалған жазба.
13) Мысалдар (жалған құжат)
13. 1 Оркестратор (идея)
python def handle(OrderPlaced e):
saga = Saga. start(e. order_id)
saga. run(step=authorize_payment, compensate=cancel_payment)
saga. run(step=reserve_inventory, compensate=release_inventory)
saga. run(step=capture_payment, compensate=refund_payment)
saga. run(step=finalize_order, compensate=refund_and_release)
saga. complete()
def run(step, compensate):
try:
step () # local transaction + outbox except Transient:
schedule_retry()
except Business as err:
start_compensation(err)
13. 2 Outbox (кесте идеясы)
outbox(id PK, aggregate_id, event_type, payload, created_at, sent_at NULL)
inbox(message_id PK, processed_at, status)
saga(order_id PK, state, step, next_attempt_at, deadline_at, context JSONB)
saga_log(id PK, order_id, time, event, details)
13. 3 Хореография (тақырыптар идеясы)
`orders. placed '→ тұтынушылары: ' payments. authorize`, `inventory. reserve`
`payments. authorized` + `inventory. reserved` → `orders. try_finalize`
Кез келген бас тарту → 'orders. compensate '→ инициализацияланады' payments. cancel/refund`, `inventory. release`.
14) 2PC және ES салыстыру
2PC: күшті үйлесімділік, бірақ бұғаттау, тар жерлер, «мыс құбырлар».
Сага: eventual consistency, өтемақы және телеметрия тәртібі қажет.
Event Sourcing: оқиғаларды ақиқат көзі ретінде сақтайды; ондағы сағалар табиғи, бірақ көші-қонның/снапшоттың күрделілігін қосады.
15) Қауіпсіздік және комплаенс
Көліктің секьюреттілігі (TLS/mTLS), ACL per topic/queue.
Оқиғаларда - минимум PII, сезімтал өрістерді шифрлау, токенизация.
Өтемақы сағаттары мен журналдарына қол жеткізу аудиті.
Сыртқы провайдерлермен SLA (төлемдер/жеткізу) = ретрайлардың шекті мерзімдері мен лимиттерінің параметрлері.
16) Енгізу чек-парағы (0-45 күн)
0-10 күн
Кандидат процестерді бөліңіз (мультисервистік, өтемақымен).
Модельді (оркестрлеу/хореография/ТСС) және корреляциялық кілтті таңдаңыз.
Қадамдарды/өтемақыларды, инварианттар мен мерзімдерді сипаттаңыз. 'saga', 'outbox', 'inbox' кестелерін көтеріңіз.
11-25 күн
outbox/inbox, теңсіздік және backoff ретрациясын қосыңыз.
Бірінші сағаларды жіберіңіз; SLI/SLO дашбордтарын және трассировканы қосыңыз.
Runbook өтемақыларды (оның ішінде қолмен) және эскалацияларды жазыңыз.
26-45 күн
GC «аспалы» сағаларды автоматтандырыңыз, мерзімді қайта іске қосу/мерзімінен бұрын жалғастыру.
Ойынды өткізіңіз: қадамның істен шығуы, мерзімнің артуы, брокердің қол жетімсіздігі.
Оқиғалар келісімшарттарын (нұсқалар, үйлесімділік) стандарттаңыз, «саг каталогын» жасаңыз.
17) Қарсы үлгілер
«Өтемақы = DҚ-дан delete» домендік дұрыс кері әрекеттің орнына.
Жоқ outbox/inbox → оқиғаларды жоғалту/қос әсерлер.
Джиттерсіз ретрайлер → өзі-DDoS тәуелділіктер.
«өңдеусіз» оқуда күшті келісуді күту....
Барлық → монолитті басқару үшін бір үлкен оркестратор.
Көрінімсіз жалпы хореография және SLA → басқарылмайтын би.
Мерзімдерді елемеу → мәңгілік резервтер/холдингтер.
18) Жетілу метрикасы
Сыни процестердің 90% ≥ сагалармен/компенсациялармен жабылған және сипатталған инварианттары бар.
Outbox/inbox барлық Tier-0/1 продюсерлері/консьюмерлері үшін біріктірілген.
SLO: p95 end-to-end сағасы қалыпты, success rate тұрақты, orphaned <мақсатты.
Мөлдір трассалау және «қадамдар бойынша» дашбордтар, burn-rate алерта.
Тоқсан сайынғы game-day және қол runbook өтемақыларын тексеру.
19) Қорытынды
Сага - бұл бөлінген жүйелер үшін практикалық келісім-шарт: нақты қадамдар мен кері әрекеттер, жариялау тәртібі (outbox/inbox), мерзімдік және ретрайлер, бақылау және өтемақы процестері. Модельді таңдаңыз (оркестрлеу/хореография/ТСС), инварианттар мен кілттерді бекітіңіз, өңдеушілерді іспеттес етіңіз - және сіздің мультисервистік бизнес-процестеріңіз қымбат 2PC жоқ болжамды және тұрақты болады.