Репликалау және eventual consistency
Репликалау және eventual consistency
1) Неге eventual consistency
Жүйе аймақтар/өңірлер бойынша бөлінген кезде, ілеспе жазба барлық жерде желілік іркілістер кезінде жоғары латенттілік пен төмен қолжетімділік береді. Eventual consistency (EC) репликаларды:- жазудың төмен кідіруі (жергілікті қабылдау),
- желіні бөлу кезінде қол жетімділікті жақсарту,
- көлденең масштабтау.
Негізгі міндет - бақылаусыз үйлесімділік: пайдаланушы «өте жаңа» деректерді көреді, домен инварианттары сақталады, қақтығыстар анықталады және алдын ала шешіледі.
2) Келісу модельдері - клиентке не уәде береміз
Strong: оқу бірден соңғы жазбаны көреді.
Bounded stale/read-not-older-than (RNOT): оқу белгісінен үлкен емес (LSN/нұсқа/уақыт).
Causal: «себеп-салдарлық» қатынастар сақталады (А-дан В-ға дейін).
Read-Your-Writes: клиент өзінің соңғы жазбаларын көреді.
Monotonic Reads: әрбір келесі оқылым «кері жылжытылмайды».
Session: бір сессия шеңберінде кепілдіктер жиынтығы.
Eventual: жаңа жазбалар болмағанда барлық репликалар бір-біріне қосылады.
Тәжірибе: сындарлы жолдарда Session + RNOT және витриналарда/кэштерде Eventual біріктіріңіз.
3) Репликация: механика және anti-entropy
Синхронды (кворум/RAFT): жазба N түйіндермен расталғаннан кейін табысты болып саналады; ең аз RPO, p99 жоғары.
Асинхронды: коммитит көшбасшысы жергілікті, журналды кейінірек таратады; төмен латенттілік, RPO> 0.
Физикалық (WAL/binlog): жылдам, гомогенді.
Логикалық/CDC: жол/оқиға деңгейіндегі өзгерістер ағыны, икемді бағыттау, сүзгілер.
Anti-entropy: мерзімді салыстыру және жөндеу (Merkle-ағаштар, хэштерді салыстыру, фондық re-sync).
4) Нұсқа сәйкестендіргіштері және себептік тапсырыстар
Монотонды нұсқалар: increment/LSN/epoch; қарапайым, бірақ параллелизмді кодтамайды.
Lamport timestamp: логикалық сағат бойынша ішінара реті.
Vector clock: параллель тармақтарды бекітеді және қақтығыс апдейттерін (concurrent) анықтауға мүмкіндік береді.
Hybrid/TrueTime/Clock-SI: жаһандық тәртіп үшін «T-ден ерте емес» логикасы.
Ұсыным: CRDT/жанжалдық жаңартпалар үшін - vector clock; «үлкен емес» үшін - LSN/GTID.
5) Жанжалдар: анықтау және шешу
Үлгілік жағдайлар: екі өңірден бір объектіге жазылу.
Стратегиялар:1. Last-Write-Wins (LWW) сағаттық/логикалық штамп бойынша - қарапайым, бірақ «жоғалтуы» мүмкін.
2. Домендік логика бойынша Merge функциялары:- (G-Counter/PN-Counter),
- жиындар «add-wins/remove-wins»,
- сомалар/баланстар - жай LWW арқылы емес, тек транзакциялық журналдар арқылы.
- 3. CRDT (конвергенттік типтер): G-Counter, OR-Set, LWW-Register, тізімдер үшін RGA.
- 4. Операциялық трансформациялар (ДБ үшін сирек, редакторлар үшін жиі).
- 5. Manual resolution: «inbox» ішіндегі қайшылық, пайдаланушы дұрыс нұсқаны таңдайды.
Ереже: домен инварианттары стратегияны білдіреді. Ақша/қалдықтар үшін - LWW-ден аулақ болыңыз; өтемақысы бар транзакцияларды/оқиғаларды пайдаланыңыз.
6) Жазбалардың кепілдіктері және
Командалардағы іспеттес кілттер (payment, withdraw, create) → қайталау қауіпсіз.
«кірістегі» (inbox) және «шығыстағы» (outbox) сәйкестілік кілті/сериялық нөмірі бойынша дедупликация.
Exactly-once күшті алғышарттарсыз қол жеткізуге болмайды; at-least-once + іспеттілікті практикалаңыз.
Outbox/Inbox-паттерн: ДБ-ға жазу және оқиғаны жариялау атомарлық (жергілікті транзакция), алушы idempotency-key бойынша өңдейді.
7) «X-тен үлкен емес» (RNOT) оқулары
Техника:- LSN/GTID-гейт: клиент ең аз нұсқасын (жазбаның жауабынан) береді, роутер/прокси LSN ≥ X-ді қуып жеткен репликаға жібереді, әйтпесе - көшбасшыға жібереді.
- Time-bound: «2 секундтан артық емес» - нұсқасыз қарапайым SLA.
- Session pinning: N секунд жазылғаннан кейін тек көшбасшыны оқимыз (Read-Your-Writes).
8) Өзгерістер ағындары және кэшті келісу
CDC → оқиғалар шинасы (Kafka/Pulsar) → тұтынушылар (кэштер, индекстер, витриналар).
Кэштің мүгедектігі: 'invalidate: {ns}: {id}'; idempotent өңдеу.
Rebuild/Backfill: Рассинхронда оқиғалар журналынан проекцияларды қайта тексеріңіз.
9) Сағалар мен өтемақылар (қызмет аралық транзакциялар)
EC-әлемде ұзақ өмір сүретін операциялар өтемдік әрекеттері бар қадамдарға бөлінеді:- Оркестрлеу: үйлестіруші қадамдарды және олардың орнын толтыруды шақырады.
- Хореография: қадамдар оқиғаларға әсер етеді және өздері мыналарды жариялайды.
Инварианттар (мысал): «баланс ≥ 0» - адым шекарасында тексеру + ауытқу кезіндегі өтемақы.
10) Мульти-өңір және желілік бөліністер
Local-write, async-replicate: жергілікті аймақта жазылу + басқаларға жеткізу (EC).
Geo-fencing: деректер аймаққа «жапсырылған» (төмен жасырындылық, аз жанжалдар).
CP-деректер үшін кворумды БД (Raft); кэштер/витриналар - AP/EC.
Split-brain жоспары: байланыс жоғалған жағдайда өңірлер домендік лимиттер (write fencing, квоталар), содан кейін - reconcile шеңберінде жұмыс істеуді жалғастырады.
11) Бақылау және SLO
Өлшемдері:- Replica lag: уақыт/LSN-қашықтық/offset (p50/p95/p99).
- Staleness: шектен үлкен жауаптардың үлесі (мысалы,> 2s немесе LSN
- Conflict rate: қайшылықтар мен табысты merge жиілігі.
- Convergence time: шыңнан кейін репликалардың жақындау уақыты.
- Reconcile backlog: артта қалған партиялардың көлемі/уақыты.
- Деректер санаттары бойынша RPO/RTO (CP/AP).
- Lag> мақсатты, қайшылықтардың өсуі, «ұзын» сәйкессіздік терезелері.
12) EC астында деректер схемасын жобалау
Әрбір жазбадағы айқын нұсқа/вектор ('version', 'vc' бағандары).
Сыни инварианттар үшін Append-only журналдары (баланстар, есептеулер).
Тәртіп пен атаға арналған оқиға идентификаторлары (snowflake/ULID).
Коммутативті табиғаты бар өрістер (есептегіштер, жиындар) → CRDT кандидаттары.
API дизайны: if-match/etag бар PUT, precondition бар PATCH.
13) Сақтау және оқу паттерндері
Read model/CQRS: «дереккөзге» жазу, проекциялардан оқу (артта қалуы мүмкін → «жаңартылады»...).
Stale-OK бағыттары (каталог/лента) vs Strict (әмиян/лимиттер).
Сұраудағы Sticky/Bounded-stale жалаулары (тақырыбы 'x-read-consistency').
14) Енгізу чек-парағы (0-45 күн)
0-10 күн
Деректерді санаттау: CP-критикалық (ақша, тапсырыстар) vs ЕС/стале-ОК (каталогтар, іздеу индекстері).
SLO стейлін (мысалы, «2s-тен үлкен емес»), нысаналы лагтарды анықтау.
Нысандарды және idempotency-keys нұсқаларын API-ге қосу.
11-25 күн
CDC және outbox/inbox, кэштің мүгедектік бағыттарын енгізу.
Жазу-сыни жолдарға RNOT (LSN-гейт) және session pinning қосу.
Кем дегенде бір merge-стратегияны (LWW/CRDT/домендік) және жанжалдар журналын іске асыру.
26-45 күн
Anti-entropy (салыстыру/жөндеу) және стейл бойынша есептерді автоматтандыру.
Game-day өткізу: желіні бөлу, қайшылықтар өрбуі, қалпына келтіру.
Дашбордтарда визуализациялау: lag, staleness, conflict rate, convergence.
15) Қарсы үлгілер
Критикалық инварианттар үшін соқыр LWW (ақша/ұпай жоғалту).
Ретра кезінде idempotency → екі операцияның болмауы.
Барлық → шектен тыс p99 қалдықтарындағы «күшті» модель және іркілістер кезіндегі морт.
RNOT/Session кепілдіктері жоқ → UX «жыпылықтайды», пайдаланушылар өздерінің өзгерістерін «көрмейді».
Кэш пен көздің жасырын синхрондалуы (CDC/мүгедектігі жоқ).
reconcile/anti-entropy құралының болмауы - деректер «ғасырларға» бөлінеді.
16) Жетілу метрикасы
Replica lag p95 нысаналы ≤ (мысалы, өңір ішінде ≤ 500 ms, ≤ 2 s өңіраралық).
Staleness SLO «қатаң» бағыттардағы сұраныстардың 99% ≥ орындалады.
Conflict resolution success ≥ 99. 9%, рұқсаттың орташа уақыты ≤ 1 мин.
Convergence time шыңдардан кейін - минуттар, сағаттар емес.
100% «ақша» операциялары idempotency-кілттермен және outbox/inbox жабылған.
17) Рецепттер (сниппеттер)
If-Match/ETag (HTTP)
PUT /profile/42
If-Match: "v17"
Body: { "email": "new@example.com" }
Егер нұсқасы өзгерсе - '412 Precondition Failed' → клиент қайшылықты шешеді.
«LSN-ден үлкен емес» сұрауы (жалған)
x-min-lsn: 16/B373F8D8
Router 'replay _ lsn ≥ x-min-lsn' репликасын таңдайды, әйтпесе - басшы.
CRDT G-Counter (идея)
Әрбір өңір өзінің есептегішін сақтайды; жиынтық - барлық компоненттердің жиынтығы; репликация - коммутативті операция.
18) Қорытынды
Eventual consistency - сапа мәмілесі емес, саналы келісім-шарт: бір жерде біз жылдамдық пен қолжетімділік үшін жаңашылдықпен төлейміз, бірақ домендік стратегиялар мен құралдармен сындарлы инварианттарды қорғаймыз. Нұсқаларды, idempotency, RNOT/Session кепілдіктерін, CDC және anti-entropy енгізіңіз, lag/staleness/conflicts өлшеңіз - және сіздің таратылған жүйеңіз ақаулықтар мен ең жоғары жүктемелер кезінде де жылдам, тұрақты және болжамды болады.