Հաղորդագրությունների կարգի երաշխիքներ
1) Ի՞ նչ է «կարգուկանոնը» և ինչո՞ ւ է այն անհրաժեշտ։
Հաղորդագրությունների կարգը «ինչ պետք է վերամշակվի» հարաբերությունն է մեկ էության իրադարձությունների համար (պատվեր, օգտագործող, դրամապանակ) կամ ամբողջ հոսքի համար։ Այն կարևոր է ինվարանտների համար '«A կարգավիճակը B-ի առջև», «հավասարակշռությունը մինչև դուրս գրելը», «n տարբերակը n + 1»։
Բաշխված համակարգերում ճանապարհների գլոբալ ընդհանուր կարգը հազվադեպ է անհրաժեշտ։ սովորաբար բավական է կարգուկանոն «բանալին»։
2) Կարգապահական երաշխիքների տեսակներ
1. Per-part.ru (տեղական կարգը լոգոյի բաժնում) - Kafka, կուսակցության ներսում կարգը պահպանվում է, կուսակցության միջև 'ոչ։
2. Per-key (ordering key/24group) - բոլոր հաղորդագրությունները մեկ բանալին ուղղվում են մեկ «հոսքի» (Kafka key, DRS FIFO Did, Pub/Sub ordering key)։
3. Global total order, ամբողջ համակարգը տեսնում է միասնական կարգ (բաշխված ամսագիր/sexvenser)։ Թանկ, վատացնում է հասանելիությունը և throughput-ը։
4. Causal order (պատճառահետևանքային) - "B իրադարձությունը A-ից հետո, եթե B-ն հետևում է A էֆեկտը։ Մենք հասնում ենք մետատվյալների միջոցով (վարկածներ, Lampium-ժամանակներ/վեկտորային ժամացույցներ) առանց գլոբալ հաջորդականության։
5. Best-effronorder-ը փորձում է պահպանել կարգը, բայց ձախողումների դեպքում հնարավոր են փոխարկումներ (հաճախ NATS Express, RabbitMQ-ում մի քանի վահանակներով)։
3) Որտե՞ ղ է կարգուկանոնը կոտրվում
Մեկ հերթի զուգահեռ վահանակները (RabbitMQ: Մի քանի consumers մի հերթով www.interleaving)։
Retrai/կրկնվող առաքումները (at-leport-once), թայմաուտները 'ack ", կրկին արտադրությունը։
Ռեբալանս/ֆեյլովեր (Kafka 'կուսակցության/առաջնորդի տեղափոխումը)։
DLQ/կրկնվող բուժումը '«թունավոր» հաղորդագրությունը գնում է DLQ-ում, հաջորդում են հետագա տրամաբանական բացը։
Multi-տարածաշրջանը և կրկնապատկումը տարբեր ուշացումներ են, որոնք կապված են ռասինխրոնիզացիայի հետ։
4) «Կարգի բանալին» դիզայնը
Բանալին ձևավորում է «պատվիրման միավորը»։ Առաջարկություններ
Օգտագործեք բնական բանալիներ '«order _ id», «wallet _ id», «aggregate _ id»։
Հետևեք «տաք բանալիներին», մեկ բանալին կարող է «արգելափակել» հոսքը (head-of-blocking)։ Անհրաժեշտության դեպքում բաժանեք բանալին '«order _ id # shard (0.. k-1)», որը սինքի վրա է։
Kafka-ում մեկ բանալին է, որը համապատասխանում է մեկ կուսակցությանը, կարգը կպահպանի բանալին։
Օրինակ (Kafka, Java)
java producer.send(new ProducerRecord<>("orders", orderId, eventBytes));
(Բանալին = «orts Id» երաշխավորում է տեղական կարգը։)
5) «Կարգավորում ընդունակությունների դեմ»
Ուժեղ երաշխիքները հաճախ բախվում են throughput-ի և հասանելի հետ
Մի վահանակ պահպանում է կարգը, բայց նվազեցնում է զուգահեռականությունը։
At-least-once + զուգահեռականությունը բարձրացնում է արտադրողականությունը, բայց պահանջում են idempotenty և/կամ վերականգնել կարգը։
Global order-ը ավելացնում է hop sexvenser-ը ռուսական լատենտ և ձախողման ռիսկ։
Փոխզիջում ՝ per-key կարգը, զուգահեռ = կուսակցության/խմբերի քանակը, + idempotent սինգլները։
6) Հատուկ բրոկերներում կարգուկանոնի վերահսկումը
Kafka
Կուսակցության ներսում կարգը։
Հետևեք 'max։ in. flight. requests. per. connection ≤ 5` с `enable. idempotence = 105 ", որպեսզի արտադրողը չփոխի կարգը։
Կոնսումեր խումբը 'մի կուսակցություն ժամանակի ընթացքում մեկ գողություն է արել։ Կրկնվող առաքումները հնարավոր են ռուսական պահել sequence/version բիզնես շերտում։
Գործարքները (read-process-write) պահպանում են «կարդացել/ձայնագրել/սկոմիտել օֆսեթները», բայց չեն ստեղծում գլոբալ կարգ։
Արտադրական նվազագույն (www.er. properties):properties enable.idempotence=true acks=all retries=2147483647 max.in.flight.requests.per.connection=5
RabbitMQ (AMQP)
Կարգը երաշխավորված է մեկ հերթով մեկ պահպանման համար։ Հաղորդագրությունների մի քանի վահանակներով կարող է գալ «խառնաշփոթ»։
Կարգի համար 'մեկ կոնսումեր կամ www.fetch = 1 + ack ավարտելուց հետո։ Զուգահեռականության համար, բաժանեք գծերը (sharding exchanges/consistent-hash)։
NATS / JetStream
NATS Express-ը best-effect է, ցածր լատենտ, կարգը կարող է խախտվել։
JetStream 'strim/հաջորդականության ներսում կարգավորում; հազվագյուտ դարակներում հնարավոր են վերափոխումներ, որոնք կարող են վերափոխվել վահանակի վրա 'օգտագործելով sequence և վերականգնման բուֆեր։
SQS FIFO
Exactly-once processing (արդյունավետ, դեդուպի պատճառով) և կարգը Intel DiD-ի ներսում։ Զուգահեռականությունը խմբերի քանակն է, head-of-2019 խմբի ներսում։
Google Pub/Sub
Ordering key-ը կարգավորում է բանալին։ սխալների դեպքում հրապարակումը արգելափակվում է մինչև վերականգնումը, հետևեք backpressure-ին։
7) Պահպանելու և վերականգնելու արտոնագրերը
7. 1 Sequence/տարբերակումը
Յուրաքանչյուր իրադարձություն կրում է «seq »/« version»։ Կոնսյումեր
վերցնում է իրադարձությունը միայն եթե «seq = lection _ seq + 1»;
հակառակ դեպքում, նա դնում է սպասման բուֆեր մինչև անհայտ կորածների գալը («lance _ seq + 1»)։
Prindocod
pseudo if seq == last+1: apply(); last++
else if seq > last+1: buffer[seq] = ev else: skip // дубль/повтор
7. 2 Ալյումինե և պատուհաններ (stream processing)
Time-24+ watermark: Մենք ընդունում ենք out-of-order պատուհանի սահմաններում, watermark-ում «փակենք» պատուհանը և պատվիրում ենք։
Allowed lateness: ալիքը ուշացողների համար (recomport/ignore)։
7. 3 Sticky-routing բանալին
«hash (key)% shards» -ը ուղարկում է բանալիների բոլոր իրադարձությունները մեկ գողերի մեջ։
Kubernetes-ում, աջակցեք ստանդարտներին (sticky) հերթի/շերդայի մակարդակում, ոչ թե HTTP-ի L4 հավասարակշռության վրա։
7. 4 Actor-մոդել/« մեկ հոսք բանալին »
Կրիտիկական ագրեգատների համար (դրամապանակ), ակտորը վերարտադրում է հաջորդաբար, մնացած զուգահեռականությունը ակտորների քանակն է։
7. 5 Idempotention + reordering
Նույնիսկ կարգուկանոնի վերականգնմամբ հնարավոր են կրկնություններ։ Համատեղեք UPS.RU-ը + տարբերակը և Inbox-ը (տե՛ ս «Exactly-once vs At-least-once»)։
8) «թունավոր» հաղորդագրությունների հետ աշխատելը (poison pills)
Կարգադրության պահպանումը բախվում է առաջադրանքի. <<Ինչպե՞ ս ապրել, եթե մեկ հաղորդագրություն չի մշակվում>>։
Խիստ կարգ 'ստեղնաշարի հոսքի արգելափակում (SDS FIFO' ամբողջ խումբը)։ Լուծումը by-key DLQ-ն է, մենք փոխանցում ենք միայն խնդրահարույց բանալին/խմբին առանձին/ձեռքով վերլուծության մեջ։
Ճկուն կարգուկանոն 'թույլ ենք տալիս 108/108; տրամաբանություն և շարունակում ենք (ոչ ֆինանսական/քննադատական ագրեգատների համար)։
Ռետրերի քաղաքականությունը 'սահմանափակ' max-mediver '+ backoff + ավիդեմենտային էֆեկտներ։
9) Multi-տարածաշրջանը և գլոբալ համակարգերը
Cluster-linking/կրկնօրինակումը (Kafka) չի երաշխավորում միջտարածաշրջանային գլոբալ կարգը։ Առաջնահերթություն տվեք տեղական per-key-ին և idempotent կապերին։
Truly-global order-ի համար օգտագործեք sexvenser (կենտրոնական լոգ), բայց դա ազդում է հասանելիության վրա (CAP: մինուս A ցանցային պայթյունների ժամանակ)։
Այլընտրանքը 'causal order + CRDT որոշ օրինագծերի համար (հաշվիչներ, հավաքածուներ) խիստ կարգ չէ։
10) Կարգուկանոնի դիտարկումը
Метрики: `out_of_order_total`, `reordered_in_window_total`, `late_events_total`, `buffer_size_current`, `blocked_keys_total`, `fifo_group_backlog`.
11) Anti-patterna
Մեկ հերթը + շատ վահանակներ առանց շարդինգի բանալին, կարգուկանոնը անմիջապես կոտրվում է։
Նույն հերթին, առանց idempotency - դուբլի + out-of-order։
Համաշխարհային կարգը «ամեն դեպքում» լատենտության և արժեքի պայթյունն է առանց իրական օգուտների։
MSS FIFO-ն ամեն ինչի համար մեկ խումբ է 'ամբողջական head-of-2019։ Օգտագործեք WindoWind Id per բանալին։
Անտեսելով «տաք պարամետրերը» 'մեկ «դրամապանակ» արգելակում է ամեն ինչ։ բանալին բաժանեք բանալիների վրա, որտեղ հնարավոր է։
Քննադատական և bulk հոսքերի խառնուրդը մեկ հերթում/խմբում փոխադարձ ազդեցություն և կարգի կորուստ։
12) Ներդրման չեկի ցուցակ
- Երաշխավորման մակարդակը 'per-key/per-part.ru/causal/global?
- Նախագծված է պատվիրման և ռազմավարության բանալին «տաք տարածքների» դեմ։
- Տրամադրված է երթուղիչ 'խմբաքանակ/WindoWind Id/ordering key։
- Վահանակները մեկուսացված են բեկորներով (sticky-routing, shard-workers)։
- Ներառված են idempotention և/կամ Inbox/UPSS.RU կապիկների վրա։
- Իրականացվել է sequence/version և reordering բուֆեր (եթե անհրաժեշտ է)։
- DLQ by key եւ retray backoff.
- Կարգի և ալերտայի մետրերը 'out-of-order, blocked _ keys, late _ events։
- Game day: Rebalans, հանգույցի կորուստ, «թունավոր» հաղորդագրություն, ցանցային ձգումներ։
- Lenta.ru: invariants, պատուհանների սահմաններ, ազդեցություն SLA-ի վրա։
13) Միգրացիայի օրինակներ
13. 1 Kafka Consumer (կարգի խախտման նվազեցում)
properties max.poll.records=500 enable.auto.commit=false # коммит после успешной обработки батча isolation.level=read_committed
13. 2 RabbitMQ (զուգահեռականության գինը)
Մեկ վահանակ + «basic» -ի վրա։ qos(prefetch=1)`
Զուգահեռականության համար մի քանի հերթեր և hash-2019
bash rabbitmq-plugins enable rabbitmq_consistent_hash_exchange публикуем с хедером/ключом для консистентного хеша
13. 3 SQS FIFO
Տվեք WindoWind = key։ Զուգահեռ = խմբերի քանակը։
Deduplant Id-ը պաշտպանելու համար դուբլներից (պրովայդերի պատուհանում)։
13. 4 NATS JetStream (ordered consumer, ուրվագիծ)
bash nats consumer add ORDERS ORD-KEY-42 --filter "orders.42.>" --deliver pull \
--ack explicit --max-deliver 6
14) FAQ
Q 'Ես համաշխարհային կարգի կարիք ունեմ։
Ա 'Գրեթե երբեք։ Գրեթե միշտ բավականաչափ per-key։ Համաշխարհային կարգը թանկ է և ծեծում է հասանելիությամբ։
Q 'Ինչպե՞ ս լինել «թունավոր» հաղորդագրությամբ խիստ կարգով։
A 'Թարգմանել միայն նրա բանալին/խումբը DLQ-ում, մնացած մասը' շարունակել։
Q 'Հնարավո՞ ր է միաժամանակ կարգուկանոն ստանալ։
A 'Այո, բանալիով կարգուկանոնը + շատ կոմպոզիցիաներ/կուսակցություններ + գաղափարական վիրահատություններ և reordering ալգորիթմներ, որտեղ անհրաժեշտ է։
Q 'Ի՞ նչն է ավելի կարևոր' կարգը կամ exactly-once-ը։
Ա 'Ածխաջրերի մեծամասնության համար կարգուկանոնը + արդյունավետ exactly-once էֆեկտները (idempotention/UPSSSA)։ Տեղափոխությունը կարող է լինել at-leport-once։
15) Արդյունքները
Կարգը տեղական երաշխիք է բիզնեսի ստեղնի շուրջ, ոչ թե թանկ համաշխարհային կարգապահություն։ Նախագծեք բանալիներ և խմբաքանակներ, սահմանափակեք «տաք» բանալիները, օգտագործեք գաղափարախոսություն և որտեղ պետք է, sequence + bufer reordering։ Հետևեք «out-of-order» և «blocked keys» մետրերին, փորձարկեք ձախողումները, և դուք կստանաք կանխատեսելի բուժում առանց զոհերի արտադրողականության և հասանելիության։