Ինչո՞ւ կարող է ձեզ անհրաժեշտ լինել կիսասինխրոն կրկնօրինակում:

Բարեւ բոլորին. Վլադիսլավ Ռոդենը կապի մեջ է. Ներկայումս ես դասավանդում եմ ծրագրային ճարտարապետության և բարձր սթրեսային ծրագրային ապահովման ճարտարապետության դասընթացներ OTUS-ում: Նոր կուրսի հոսքի մեկնարկի ակնկալիքով «Բարձր բեռի ճարտարապետ» Ես որոշեցի գրել օրիգինալ նյութի մի կարճ հատված, որը ցանկանում եմ կիսվել ձեզ հետ:

Ինչո՞ւ կարող է ձեզ անհրաժեշտ լինել կիսասինխրոն կրկնօրինակում:

Ներածություն

Հաշվի առնելով այն հանգամանքը, որ HDD-ն կարող է վայրկյանում կատարել միայն մոտ 400-700 գործողություն (ինչն անհամեմատելի է բարձր բեռնվածության համակարգում բնորոշ rps-ի հետ), դասական սկավառակի տվյալների բազան ճարտարապետության խոչընդոտն է: Ուստի անհրաժեշտ է հատուկ ուշադրություն դարձնել այս պահեստի մասշտաբային օրինաչափություններին։

Ներկայումս տվյալների բազայի մասշտաբավորման 2 օրինաչափություն կա՝ կրկնօրինակում և մասնատում: Sharding-ը թույլ է տալիս մասշտաբավորել գրելու գործողությունը և, որպես հետեւանք, նվազեցնել ձեր կլաստերի մեկ սերվերի մեկ գրման rps-ը: Replication-ը թույլ է տալիս անել նույն բանը, բայց կարդալու գործողություններով: Հենց այս օրինակին է նվիրված այս հոդվածը:

Վերօրինակման

Եթե ​​վերարտադրումը նայեք շատ բարձր մակարդակով, ապա դա պարզ բան է. դուք ունեիք մեկ սերվեր, դրա վրա կային տվյալներ, և այնուհետև այս սերվերն այլևս չէր կարող հաղթահարել այս տվյալները կարդալու ծանրաբեռնվածությունը: Դուք ավելացնում եք ևս մի քանի սերվեր, համաժամացնում եք տվյալները բոլոր սերվերների միջև, և օգտատերը կարող է կարդալ ձեր կլաստերի ցանկացած սերվերից:

Չնայած իր ակնհայտ պարզությանը, այս սխեմայի տարբեր իրականացումները դասակարգելու մի քանի տարբերակ կա.

  • Ըստ կլաստերի դերերի (տեր-տեր կամ վարպետ-ստրուկ)
  • Ըստ ուղարկված օբյեկտների (շարքի վրա հիմնված, քաղվածքի վրա հիմնված կամ խառը)
  • Ըստ հանգույցի համաժամացման մեխանիզմի

Այսօր մենք կզբաղվենք 3-րդ կետով.

Ինչպե՞ս է տեղի ունենում գործարքի կատարումը:

Այս թեման ուղղակիորեն կապված չէ կրկնօրինակման հետ, դրա վրա կարելի է գրել առանձին հոդված, բայց քանի որ հետագա ընթերցումն անօգուտ է առանց գործարքների կատարման մեխանիզմը հասկանալու, թույլ տվեք հիշեցնել ձեզ ամենահիմնական բաները: Գործարքի հանձնումը տեղի է ունենում 3 փուլով.

  1. Գործարքի գրանցում տվյալների բազայի գրանցամատյանում:
  2. Գործարքի օգտագործումը տվյալների բազայի շարժիչում:
  3. Հաճախորդին վերադարձվում է հաստատում, որ գործարքը հաջողությամբ կիրառվել է:

Տարբեր տվյալների բազաներում այս ալգորիթմը կարող է ունենալ նրբերանգներ. օրինակ, MySQL տվյալների բազայի InnoDB շարժիչում կա 2 տեղեկամատյան՝ մեկը վերարտադրելու համար (երկուական տեղեկամատյան), իսկ մյուսը՝ ACID-ի պահպանման համար (չեղարկել/վերափոխել տեղեկամատյանը), մինչդեռ PostgreSQL-ում է: կա մեկ մատյան, որն իրականացնում է երկու գործառույթները (գրել առաջ գրանցամատյան = WAL): Բայց վերը ներկայացվածը հենց ընդհանուր հայեցակարգն է, որը թույլ է տալիս հաշվի չառնել նման նրբերանգները։

Սինխրոն (համաժամեցում) կրկնօրինակում

Եկեք տրամաբանություն ավելացնենք՝ ստացված փոփոխությունները գործարքի կատարման ալգորիթմում կրկնելու համար.

  1. Գործարքի գրանցում տվյալների բազայի գրանցամատյանում:
  2. Գործարքի օգտագործումը տվյալների բազայի շարժիչում:
  3. Տվյալների ուղարկում բոլոր կրկնօրինակներին:
  4. Ստանալով հաստատում բոլոր կրկնօրինակներից, որ գործարքը կատարվել է դրանց վրա:
  5. Հաճախորդին վերադարձվում է հաստատում, որ գործարքը հաջողությամբ կիրառվել է:

Այս մոտեցմամբ մենք ստանում ենք մի շարք թերություններ.

  • հաճախորդը սպասում է, որ փոփոխությունները կիրառվեն բոլոր կրկնօրինակների վրա:
  • քանի որ կլաստերի հանգույցների թիվը մեծանում է, մենք նվազեցնում ենք հավանականությունը, որ գրելու գործողությունը հաջող կլինի:

Եթե ​​1-ին կետով ամեն ինչ քիչ թե շատ պարզ է, ապա արժե բացատրել 2-րդ կետի պատճառները։ Եթե ​​սինխրոն կրկնօրինակման ժամանակ մենք պատասխան չենք ստանում առնվազն մեկ հանգույցից, մենք հետ ենք գլորում գործարքը: Այսպիսով, ավելացնելով հանգույցների թիվը կլաստերի մեջ, դուք մեծացնում եք գրելու գործողության ձախողման հավանականությունը:

Կարո՞ղ ենք սպասել հաստատման միայն հանգույցների որոշակի տոկոսից, օրինակ՝ 51%-ից (քվորում): Այո, մենք կարող ենք, բայց դասական տարբերակում բոլոր հանգույցներից հաստատում է պահանջվում, քանի որ այս կերպ մենք կարող ենք ապահովել տվյալների ամբողջական հետևողականություն կլաստերում, ինչը այս տեսակի կրկնօրինակման անկասկած առավելությունն է։

Ասինխրոն (ասինխրոն) կրկնօրինակում

Եկեք փոփոխենք նախորդ ալգորիթմը։ Մենք տվյալները կուղարկենք կրկնօրինակներին «որոշ ժամանակ անց», իսկ «որոշ ժամանակ անց» փոփոխությունները կկիրառվեն կրկնօրինակների վրա.

  1. Գործարքի գրանցում տվյալների բազայի գրանցամատյանում:
  2. Գործարքի օգտագործումը տվյալների բազայի շարժիչում:
  3. Հաճախորդին վերադարձվում է հաստատում, որ գործարքը հաջողությամբ կիրառվել է:
  4. Տվյալների ուղարկում կրկնօրինակներին և դրանցում փոփոխություններ կիրառելը:

Այս մոտեցումը հանգեցնում է նրան, որ կլաստերը արագ է աշխատում, քանի որ մենք չենք պահում հաճախորդին սպասել, որ տվյալները հասնեն կրկնօրինակներին և նույնիսկ կատարվեն:

Բայց «որևէ ուշ» կրկնօրինակների վրա տվյալների նետման պայմանը կարող է հանգեցնել գործարքի կորստի և օգտագործողի կողմից հաստատված գործարքի կորստի, քանի որ եթե տվյալները ժամանակ չունենան կրկնօրինակելու, ապա հաստատում հաճախորդին: Գործողության հաջողության մասին ուղարկվել է, և հանգույցը, որին հասել են փոփոխությունները, խափանվել է HDD-ն, մենք կորցնում ենք գործարքը, ինչը կարող է հանգեցնել շատ տհաճ հետևանքների:

Կիսահամաժամացման կրկնօրինակում

Վերջապես մենք հասնում ենք կիսասինխրոն կրկնօրինակմանը: Կրկնօրինակման այս տեսակը այնքան էլ հայտնի չէ կամ շատ տարածված է, սակայն այն զգալի հետաքրքրություն է ներկայացնում, քանի որ այն կարող է համատեղել ինչպես համաժամանակյա, այնպես էլ ասինխրոն վերարտադրության առավելությունները:

Փորձենք համատեղել նախորդ 2 մոտեցումները։ Մենք հաճախորդին երկար չենք պահի, բայց կպահանջենք, որ տվյալները կրկնօրինակվեն.

  1. Գործարքի գրանցում տվյալների բազայի գրանցամատյանում:
  2. Գործարքի օգտագործումը տվյալների բազայի շարժիչում:
  3. Տվյալների ուղարկում կրկնօրինակներին:
  4. Ստանալով հաստատում կրկնօրինակից, որ փոփոխությունները ստացվել են (դրանք կկիրառվեն «որոշ ժամանակ անց»):
  5. Հաճախորդին վերադարձվում է հաստատում, որ գործարքը հաջողությամբ կիրառվել է:

Խնդրում ենք նկատի ունենալ, որ այս ալգորիթմի դեպքում գործարքի կորուստը տեղի է ունենում միայն այն դեպքում, երբ և՛ փոփոխությունները ստացող հանգույցը, և՛ կրկնօրինակ հանգույցը ձախողվում են: Նման ձախողման հավանականությունը համարվում է ցածր, և այդ ռիսկերն ընդունված են։

Բայց այս մոտեցմամբ հնարավոր է ֆանտոմային ընթերցումների վտանգ: Եկեք պատկերացնենք հետևյալ սցենարը՝ 4-րդ քայլում մենք ոչ մի կրկնօրինակից հաստատում չենք ստացել։ Մենք պետք է հետ դարձնենք այս գործարքը և չվերադարձնենք հաստատումը հաճախորդին: Քանի որ տվյալները կիրառվել են 2-րդ քայլում, 2-րդ քայլի ավարտի և գործարքի վերադարձի միջև կա ժամանակային բաց, որի ընթացքում զուգահեռ գործարքները կարող են տեսնել փոփոխություններ, որոնք չպետք է լինեն տվյալների բազայում:

Կիսահամաժամ կրկնօրինակում առանց կորստի

Եթե ​​մի փոքր մտածեք, կարող եք պարզապես հակադարձել ալգորիթմի քայլերը և շտկել ֆանտոմային ընթերցումների խնդիրը այս սցենարում.

  1. Գործարքի գրանցում տվյալների բազայի գրանցամատյանում:
  2. Կրկնօրինակ տվյալների ուղարկում:
  3. Ստանալով հաստատում կրկնօրինակից, որ փոփոխությունները ստացվել են (դրանք կկիրառվեն «որոշ ժամանակ անց»):
  4. Գործարքի օգտագործումը տվյալների բազայի շարժիչում:
  5. Հաճախորդին վերադարձվում է հաստատում, որ գործարքը հաջողությամբ կիրառվել է:

Այժմ մենք փոփոխություններ ենք կատարում միայն այն դեպքում, եթե դրանք կրկնվել են:

Արտադրողականություն

Ինչպես միշտ, չկան իդեալական լուծումներ, կա լուծումների մի շարք, որոնցից յուրաքանչյուրն ունի իր առավելություններն ու թերությունները և հարմար է տարբեր դասերի խնդիրներ լուծելու համար: Սա բացարձակապես ճիշտ է կրկնօրինակված տվյալների բազայում տվյալների համաժամացման մեխանիզմ ընտրելու համար: Կիսասինխրոն կրկնօրինակման առավելությունների շարքը բավականաչափ ամուր և հետաքրքիր է, որ կարող է ուշադրության արժանի համարվել՝ չնայած ցածր տարածվածությանը:

Այսքանը: Կհանդիպենք ժ դասընթաց!

Source: www.habr.com

Добавить комментарий