Խոհարարների և backoff
Կրկնությունները (retries) օգնում են գոյատևել ժամանակավոր ձախողումները, բայց սխալ փորձով առաջացնում են ավալանշներ, գործողությունների անկումներ և կասկադային անկումներ։ Ռետրոյի հուսալի քաղաքականությունը միշտ սկսվում է dedlins/timauts-ից, հաշվի է առնում գաղափարախոսությունը և օգտագործում է backoff + jitter։
1) Հիմնական սկզբունքները
1. Սկզբում թայմաութ/dedline, ապա retray։ Առանց ժամանակին Դավիթը միայն մերժում է։
2. Retray-ը միայն անվտանգ/idempotent վիրահատությունների համար է։ Անապահով մարդկանց համար 'idempotency-keys-ի և գործարքային երաշխիքների միջոցով։
3. Backoff-ը պարտական է։ Էքսպոնենցիալ կամ GCRA-ն նման է ջիթերի հետ, որպեսզի ապականվի ալիքները։
4. Սահմանափակեք փորձերի քանակը և ընդհանուր բյուջեն։ Մի թողեք օգտագործողի SLO։
5. Հարգեք ենթակառուցվածքի ազդանշանները '"429/503' +" Retry-After ", circuit breaker վիճակը, հերթերի սահմանները։
2) Թայմաուտները և Deadom propagation (deadom propagation)
Հարցման թայմաուտը Timauts: Ընդհանուր (առաջին փորձը + backoff + հաջորդ) ռուսական օգտագործողի dedline։ Տարբեր թայմաուտներ ընթերցանության/գրառումների համար 'ձայնագրությունները ավելի կարճ և ավելի խիստ են։ ընթերցանությունները թույլ են տալիս hedging։ 3) Իդեմպոտենտալությունը և անվտանգ կրկնությունները Ընթերցումները (GET/idempotent RPC) 'անվտանգ կրկնել «5xx», «UNAVAILABABE», ցանցային թայմաուտներում։ Գրառումներ Օգտագործեք «Idempotency-Key» (HTTP) կամ request-ID սահմանին։ սերվերը պետք է կրկնապատկվի։ Գրեք idempotent բուժողներ 'ups.ru, at-leport-once + փոխհատուցում (saga)։ Արտաքին վճարումները/փոխկապակցիչները միայն գաղափարական բեկորների և գործողությունների ամսագրերի հետ են։ 4) Backoff ալգորիթմներ Exponential: «big 2 ^ attempt», սահմանափակ «max _ backoff»։ Decorrelated Jitter (fox/equal jitter), պատահականություն հաճախորդների ռասինխրոնիզացիայի համար։ GCRA/Token-Bucket-նման ուշացումները համաձայնեցված են rate limits-ի հետ։ Սահմանները ՝ «initial _ backoff» (50-200 կարդալու։ 200-500 ձայնագրություններ), «max _ backoff» (1-5 s), «max _ elapsed» (օրինակ ՝ 3-10 s)։ Առաջարկվող ձևը 'էքսպոնենցիալ backoff + fultjitter։ 5) «Կրկնել/չկրկնել» որոշման կայացման քաղաքականությունը։ Կրկնում ենք Ցանցային սխալներ/թայմաուտներ, «429» (հարգանքով 'Retry-After «),» փափուկ «» 5xx «(» 502/503/504 «), gRPC' UNAVAILABLE/DEADPS _ EEDED D»։ Մենք չենք կրկնում «4xx» (բացառությամբ «4.9/429/4.9» որոշ սցենարներում), բիզնես սխալները, «401/403», վալիդային սխալները, որոնք ակնհայտ են «DoJ tRetry» դրոշի վրա։ Խելացի բացառություններ «409 Sylict» - երբեմն կրկնօրինակող է, որի տևողությունը 105/լոկից հետո։ «404» ընթերցանության eventually consistent-ը մեկ-երկու անգամ ռետրա է փոքրիկ backoff-ով։ 6) Concurrency caps և «retrav փոթորիկ» Սահմանափակեք per-client/per-tenae/per-endpoint-ը։ Հարցման փորձերի ընդհանուր սահմանը (օրինակ ՝ 2-3)։ Դանդաղեցրեք «տաք» էնդպոինտները admission corl-ի միջոցով, որպեսզի չփչացնենք հերթերը։ 7) Փոխազդեցությունը Circuit Breaker-ի և limits հետ Եթե CB open-ը, մի ուղղակիորեն կատարեք հետքերը, գնացեք fallback կամ սպասեք «half-open» փորձարկումներին։ «429» դեպքում հարգեք «Retry-After»; դրա բացակայության դեպքում օգտագործեք «փափուկ» backoff։ Retrai կարող են բարձրացնել բեռը։ օգտագործեք հարմարվողական շեմեր (նվազեցրեք «max _ attemprone» պատահականության ժամանակ)։ 8) Արձանագրություններ և պայմանագրեր HTTP Իսպանիա ՝ «407/429/5xx»։ Վերնագրերը ՝ «Retry-After», ընտանիքը 'Rance Limit-, «Idempotency-Key», «Request-Id»։ Հաճախորդը պետք է փոխանցի «X-Request-Timeout »/« Deadom-At» (եթե դուք դա սովորական եք)։ Օգտագործեք ենթատեքստը dedline; Հարգեք 'UNAVAILABABE "," DEADIM _ EEDED ", ռետրերի պոլիսներ մեթոդը։ Idempotent RPC-ի համար միացրեք retray-ը։ մուտացիաների համար միայն կուռքերի աջակցությամբ է։ 9) Գծեր, ֆոնային առաջադրանքներ և կոմպոզիցիաներ At-least-once-once-ի վերարտադրողները հակադրվում են idempotent գործողություններ, deduplication բանալին։ Diay queue-ի համար backoff-ը փորձերի միջև (օրինակ ՝ 5s/30s/2m)։ Dead-letter queue (DLQ) փորձարկումների և ձեռքի մշակման սահմանաչափով։ Windobox/CDC-ը, որպեսզի կրկնությունները չփորձեն գործարքային ամբողջականությունը։ 10) Hedging vs Retries Hedging (հայելային հարցում) օգտակար է բարձր կրիտիկ ընթերցումների համար պոչի լատենտության ժամանակ։ Սահմանափակեք, ոչ ավելի քան X տոկոսը, «սկսնակ-գրեյս» հետաձգումը (օրինակ ՝ p95-լատենտ), պարտվողների վերացումը։ Մի օգտագործեք hedging-ը ձայնագրելու համար առանց ուժեղ կուռքի։ 11) Թելեմետրիա և դիտողություն Теги: `tenant_id`, `endpoint`, `attempt`, `decision` (retry/skip), `reason`, `backoff_ms`, `deadline_ms`, `idempotency_key`. Մետրիկները 'գետերի մասնաբաժինը, հաջողությունը գետերից հետո, p95/p99 «end-to-end», ավելի բարձր dedlins, CB։ Loges-ը 'վերին N «աղմկոտ» 108/endpoints-ը, հարաբերակցությունը 429/503-ից։ 12) Փորձարկում և քաոս Պրոֆիլներ ՝ «պիլ» (burst-timier), «փոթորիկ» (զանգվածային թայմաուտներ), «լիպիկ» սխալներ (յուրաքանչյուրը N-րդ), լատենտության պոչեր։ Լիմիտերի/քեշի/հերթերի, clock-skew-ի ձախողումները։ Ստուգումը, որ ընդհանուր տևողությունը (attempation + backoff) տեղադրվում է SLO-ում։ 13) Քաղաքականության կեղծ դասը 14) Միգրացիայի ձևը (օրինակ) 15) Չեկ թուղթ մինչև վաճառելը 16) Տիպիկ սխալներ Կրկնությունները առանց թայմաուտների/դուդլինների '«հավիտենական սպասումներ»։ Ֆիքսված դադարները առանց ջիթերի 'սինխրոն ալիքները և DDoS-ինքնաբոտաժը։ Անապահով ձայնագրությունների ռետրոն առանց կուռքերի 'դուբլի և ռասինխրոնիզացիայի։ Անտեսելով 'Retry-After "և CB ազդանշանները' կոդավորման էսկալացիա։ Հերթերի նեղ տեղերը կապսի բացակայության և admission control-ի պատճառով։ Պատճառների հեռուստաչափության բացակայությունը/ռեգրեների լուծումները «կույր թռիչք» են։ 17) Արագ բաղադրատոմսեր API-ի հանրային ընթերցումները ՝ 3 փորձեր, «initial = 100.8», «max = 1s», fronjitter, hedging մինչև 5% ռուբլիա։ Քննադատական ձայնագրությունները (105) '1-2 փորձեր մաքս, խիստ թայմաուտ, պարտադիր «Idempotency-Key», առանց hedging։ Արտաքին պարամետրերը 'հարգել «429/Retry-After», «max _ attempium = 3», «max _ backoff = 2-5s», սահմանները հոսքի վրա։ Ֆոնային առաջադրանքները ՝ wwww.ay-backoff (5s 3530s 42m), DLQ, idempotent։ Խոհարարների լավ քաղաքականությունը հավասարակշռություն է արագ վերականգնման և վերահսկվող մերժման միջև։ Dedlines, idempotention, էքսպոնենցիալ backoff ջիթերի հետ, մրցակցության սահմանափակումը և ենթակառուցվածքի ազդանշանների հարգանքը վերածում են «փոթորիկից» դեպի SLO-ի հուսալիության և պահպանման գործիք։gRPC
pseudo handle(req, deadline):
attempt = 0 backoff = initial()
while attempt < MAX_ATTEMPTS and now() < deadline:
attempt += 1 with timeout(per_attempt_timeout(deadline, attempt)):
try:
resp = call(req)
if isRetryableStatus(resp): raise Retryable(resp. status)
return resp except Retryable as e:
if circuit. isOpen(dep) or! isIdempotent(req): break sleep(jitter(backoff))
backoff = min(exp(backoff), MAX_BACKOFF)
except NonRetryable:
break return fail_or_fallback(req)yaml retries:
default:
max_attempts: 3 initial_backoff_ms: 150 max_backoff_ms: 2000 strategy: exponential_full_jitter respect_retry_after: true per_attempt_timeout_fraction: 0. 4 # 40% of remaining deadline hedging:
enabled: false read_heavy:
max_attempts: 4 initial_backoff_ms: 80 max_backoff_ms: 1200 hedging:
enabled: true start_after_p95_ms: 300 max_extra_requests_ratio: 0. 05 write_strict:
max_attempts: 2 initial_backoff_ms: 250 max_backoff_ms: 1000 idempotency_required: true
limits:
concurrent_retries_per_tenant: 100 concurrent_retries_per_endpoint: 20
Եզրակացություն