Գաղափարախոսություն և բանալիներ
Ի՞ նչ է գաղափարախոսությունը
Idempotenty-ը վիրահատության հատկությունն է, որի դեպքում նույն բաղադրիչը չի փոխում վերջնական ազդեցությունը։ Բաշխված համակարգերում սա հիմնական միջոցն է արդյունքն դարձնել համարժեք «ճիշտ մեկ վերամշակման», չնայած հետքերով, հաղորդագրությունների կրկնօրինակները և թայմաուտները։
Հիմնական գաղափարն այն է, որ յուրաքանչյուր պոտենցիալ կրկնվող վիրահատություն պետք է նշվի բանալին, որով համակարգը ճանաչում է «դա արդեն արել» և օգտագործում արդյունքը ոչ ավելի, քան մեկ անգամ։
Որտե՞ ղ է դա կարևոր
Վճարումները և հավասարակշռությունները 'դուրս գրելը/հաշվարկել «operation _ id»։
Ամրագրում/քվոտաներ/լիմիտներ ՝ նույն փղը/ռեսուրսը։
Վեբհուկի/ծանուցում. Կրկնվող առաքումը չպետք է կրկնապատկի ազդեցությունը։
Windows/www.ru: Կրկնակի ֆայլերի/wwww.ru։
Սթրիմ պրոցեսինգ 'բրոքեր/CDC։
Տեսակներ կղզիների և նրանց գործողությունների տարածքը
1. Operation key - բիզնես վիրահատության հատուկ փորձերի իրականացում
Օրինակներ ՝ «idempotency _ key» (HTTP), «operation _ id» (RPC)։
Տարածքը 'ծառայություն/ագրեգատ; պահվում է դեդուպլյացիայի աղյուսակում։
2. Event key - յուրահատուկ ռուսական իրադարձություններ/հաղորդագրություն
Օրինակներ ՝ «event _ id» (UUID), «(meder _ id, sequence)»։
Տարածքը 'սպառողը/սպառողների խումբը; պաշտպանում է պրոյեկտները։
3. Business key-ը բնական բանալին է առարկայական ոլորտում
Օրինակներ ՝ «payment _ id», «www.oice _ num.ru», «(user _ id, day)»։
Տարածքը ՝ ագրեգատ; օգտագործվում է եզակի/տարբերակի ստուգումներում։
TTL և պահպանման քաղաքականությունը
TTL-ն նկարագրում է կրկնօրինակների հնարավոր պատուհանի ցանկը 'լոգոյի վերականգնումը + ցանցային/պրոցեսորային ուշացումներ։
Քննադատական օրինագծերի (վճարումների) TTL-ի համար 'օրեր/շաբաթ; հեռուստաչափության համար ժամացույց է։
Մաքրեք dedup աղյուսակները background job; կոմպոզիցիաների համար արխիվացրեք։
Windows համար (deduplication)
Գործարքային BD (խորհուրդ) 'հուսալի ups.ru/unique ինդեքսներ, համատեղ գործարք ազդեցության հետ։
KV/Redis: արագ, հարմար կարճ TTL-ի համար, բայց առանց համատեղ գործարքի OLTP-ի հետ, զգուշորեն։
State store strem-2019 'տեղական + cheinjolog բրոկերում; լավ է Flink/KStreams-ում։
Սխեմա (տարբերակը BD)
idempotency_keys
`consumer_id` (или `service`), `op_id` (PK на пару), `applied_at`, `ttl_expires_at`, `result_hash`/`response_status` (опц.) .
Ինդեքսները ՝ "(consumer _ id, op _ id) եզակի են։
Իրականացման հիմնական մեթոդները
1) Գործարքը + առաջընթացի էֆեկտը "
Արդյունքի ձայնագրումը և կարդալու/դիրքի առաջընթացի ամրագրումը մեկ գործարքում է։
pseudo begin tx if not exists(select 1 from idempotency_keys where consumer=:c and op_id=:id) then
-- apply effect atomically (upsert/merge/increment)
apply_effect(...)
insert into idempotency_keys(consumer, op_id, applied_at)
values(:c,:id, now)
end if
-- record reading progress (offset/position)
upsert offsets set pos=:pos where consumer=:c commit
2) Optimistic Concurrency (ագրեգատի տարբերակը)
Պաշտպանում է կրկնակի էֆեկտից մրցավազքում
sql update account set balance = balance +:delta,
version = version + 1 where id=:account_id and version=:expected_version;
-- if 0 rows are updated → retry/conflict
3) Idempotent sinks (ups.ru/merge)
Վիրահատությունը «մեկ անգամ հաշվարկել»
sql insert into bonuses(user_id, op_id, amount)
values(:u,:op,:amt)
on conflict (user_id, op_id) do nothing;
Idempotenty արձանագրություններում
HTTP/REST
"Idempotency-Key:
Սերվերը պահպանում է ստեղնաշարի ձայնագրումը և նորից վերադարձնում նույն պատասխանը (կամ կոդը '409 '/' 422 "ինվարանտների հակամարտության ժամանակ)։
«Անապահով» POST-ի համար պարտական է «Idempotency-Key» + կայուն թայմաուտ/ռետրո քաղաքականությունը։
gRPC/RPC
«Idempotency _ key», «request _ id» + deadics։
Սերվերային ֆորումը, ինչպես REST-ում, գործարքում ռուսական դեդուպը։
Բրոկերներ/սթրիմինգ (Kafka/NATS/Pulsar) (Kafka/NATS/Pulsar)
Արտադրողը 'կայուն «event _ id »/idempotent արտադրողը (որտեղ աջակցվում է)։
Կոնսյումեր '«(consumer _ id, event _ id)» և/կամ ագրեգատի բիզնես տարբերակով։
Առանձնացված DLQ-ը ոչ համակարգային/վնասված հաղորդագրությունների համար։
Webhuki և արտաքին գործընկերներ
Պահանջեք 'Idempotency-Key '/' event _ id' պայմանագրում; կրկնվող առաքումը պետք է ապահով լինի։
Պահեք «notifice _ id» և ուղարկման կարգավիճակները։ գետնին, մի կրկնեք։
Դիզայն 2019
Դետերմինալ 'ռետրերը պետք է ուղարկեն նույն բանալին (առաջացրեք նախօրոք կլիենտով/նվագարկիչով)։
Տեսադաշտը 'կազմեք «op _ id» որպես «aggregate: id: purpose»։
Կոլիզիա 'օգտագործեք UUIDv7/ULID կամ հեշը բիզնես կոդից (աղով, անհրաժեշտության դեպքում)։
Հիերարխիա 'ընդհանուր «operation _ id» -ը առջևի մասում փոխանցվում է բոլոր վիրահատություններին (idempotent շղթա)։
UX և ապրանքային ասպեկտներ
Ստեղնաշարի երկրորդ հարցումը պետք է վերադարձնի նույն արդյունքը (ներառյալ մարմինը/կարգավիճակը), կամ ակնհայտ «արդեն նշված»։
Օգտագործողին ցույց տվեք «վիրահատությունը զարգանում է/108» '«հաջողության» փորձերի փոխարեն։
Երկար վիրահատությունների համար 'բանալին («GET/oper.ru/+ op _ id _»)։
Դիտարկումը
Տրամաբանեք «op _ id», «event _ id», «trace _ id», արդյունքը ՝ «APIED »/« ALREADY _ APPIED»։
Մետրիկները 'խոհարարների մասնաբաժինը, դեդուպի աղյուսակների չափը, գործարքների ժամանակը, տարբերակների հակամարտությունները, DLQ-տոկոսադրույքը։
Թրեյս 'բանալին պետք է անցնի թիմի միջոցով ռուսական իրադարձության միջոցով ռուսական արտաքին մարտահրավեր։
Անվտանգություն և ընկերակցություն
Մի պահեք PII բաների մեջ։ բանալին է, ոչ payload։
Ծածկագրեք զգայուն դաշտերը դեդուպի ձայնագրություններում երկար TTL-ով։
Պահեստավորման քաղաքականությունը 'TTL և արխիվները։ մոռացման իրավունքը 'պատասխանների ծպտյալ լվացման միջոցով/մետատվյալներին (եթե դրանք պարունակում են PII)։
Թեստավորում
1. Դուբլիկատներ 'մեկ հաղորդագրություն/հարցում 2-5 անգամ, էֆեկտը հենց մեկ է։
2. Քայլերի միջև ընկնելը 'էֆեկտի ձայնագրումից առաջ/հետո, օֆսետի ամրագրումից առաջ/հետո։
3. Restart/rebalans սպառողների 'կրկնակի կիրառություն չկա։
4. Մրցակցություն 'զուգահեռ հարցումներ մեկ «op _ id» -ի հետ մեկ ազդեցություն, երկրորդը' «ALREADY _ APIED/409»։
5. Երկարատև բանալիներ. Վերականգնումից հետո TTL և կրկնօրինակների ստուգում։
Antipatterns
Պատահական նոր բանալին յուրաքանչյուր ռետրայի վրա, համակարգը չի ճանաչում կրկնությունները։
Երկու առանձին համայնքներ 'սկզբում էֆեկտը, հետո օֆսեթը, նրանց միջև անկումը կրկնապատկվում է։
Վստահությունը միայն բրոկերն է 'դիոդուպի բացակայությունը կապույտում/ագրեգատում։
Ագրեգատի տարբերակի բացակայությունը 'կրկնվող իրադարձությունը փոխում է վիճակը երկրորդ անգամ։
Fat keys: բանալին ներառում է բիզնես դաշտեր/PII արտահոսքի և բարդ ինդեքսների։
Կրկնվող պատասխանների բացակայությունը 'հաճախորդը չի կարող անվտանգ կտրել։
Օրինակներ
Ստացիոնար POST POST
Հաճախորդը ՝ «POST/POST/payments» + «Idempotency-Key: k-78»։
Սերվերը 'գործարքը ստեղծում է "payme" և ձայնագրությունը' idempotency _ keys "։
Խոհարար 'վերադարձնում է նույն «201 »/մարմինը։ invarium-ի հակամարտությունը '«409»։
Բոնուսի հաշվարկումը (sink)
sql insert into credits(user_id, op_id, amount, created_at)
values(:u,:op,:amt, now)
on conflict (user_id, op_id) do nothing;
Նախագծումը իրադարձություններից
Կոնսյումերը պահպանում է «seen (event _ id)» և «version» միավորումը։ խոհարարը ups.ru/idempotent ups.ru է։
Կարդալու առաջընթացը ամրագրված է նույն գործարքում, ինչպես նաև պրոյեկտիայի նորարարությունը։
Chek-Lister վաճառվել է
- Բոլոր անապահով գործողությունների համար նախատեսված է համապարփակ բանալին և նրա տեսանելի տարածքը։
- Ուտեք դեդուպի աղյուսակներ TTL և յուրահատուկ ինդեքսներով։
- Ընթերցանության էֆեկտը և առաջընթացը ատոմային են։
- Write-մոդելում ներառված է լավատեսական մրցակցություն (տարբերակը/sequence)։
- API պայմանագրերը գրանցում են «Idempotency-Key »/« operation _ id» և կրկնապատկիչների վարքագիծը։
- Մետրիկները և լոգները պարունակում են «op _ id »/« event _ id »/« trace _ id»։
- Կրկնօրինակների, անկման և մրցավազքի թեստերը CI-ում են։
- TTL/արխիվի և PII-ի անվտանգությունը պահպանված է։
FAQ
Ինչպե՞ ս է «Idempotency-Key» -ը տարբերվում «Request-Id» -ից։
"Request-Id '- ճանապարհը; այն կարող է փոխվել գետերի վրա: <
Հնարավո՞ ր է արդյոք կռապաշտություն անել առանց BD-ի։
Կարճ պատուհանի համար 'այո (Redis/international kash), բայց առանց միասին գործարքի, կրկնությունների ռիսկը մեծանում է։ Կրիտիկական մրցույթներում ավելի լավ է մեկ BD գործարքում։
Ի՞ նչ անել արտաքին գործընկերների հետ։
Կարդացեք բաների մասին և կրկնեք պատասխանները։ Եթե զուգընկերը չի աջակցում, զանգահարեք ձեր գաղափարական շերտին և պահեք «արդեն օգտագործվել»։
Ինչպե՞ ս ընտրել TTL-ն։
Հավաքեք առավելագույն ձգձգումները 'լոբի վերականգնումը + worst-cript ցանցը/rebalans + bufer։ Ավելացրեք պահեստը (552)։
Արդյունքը
Idempotenty-ը բանկային, գործարքների և տարբերակների կարգապահությունն է։ Վիրահատության կայուն ցուցանիշները + ատոմային ֆիքսումը և կարդալու առաջընթացը + idempotent sinks/պրոյեկտները տալիս են «ուղիղ մեկ ազդեցություն» առանց տրանսպորտային մակարդակի մոգության։ Դարձրեք բանալիներ դետերմինացված, TTL-ն իրատեսական է, իսկ թեստերը չարամիտ են։ Այդ ժամանակ ռեցատներն ու կրկնօրինակները կդառնան ռուտինա, ոչ թե միջադեպեր։