Панҷ донишҷӯ ва се мағозаи калидӣ тақсим карданд

Ё чӣ гуна мо китобхонаи муштарии C++ барои ZooKeeper, etcd ва Consul KV навиштем

Дар ҷаҳони системаҳои тақсимшуда як қатор вазифаҳои маъмулӣ мавҷуданд: нигоҳ доштани маълумот дар бораи таркиби кластер, идоракунии конфигуратсияи гиреҳҳо, ошкор кардани гиреҳҳои хато, интихоби роҳбар ва дигарон. Барои халли ин проблемахо системахои махсуси таксимшуда — хизматхои координационй ташкил карда шудаанд. Ҳоло мо ба се нафари онҳо таваҷҷӯҳ хоҳем кард: ZooKeeper, etcd ва Consul. Аз тамоми функсияҳои ғании консул, мо ба Консул К.В.

Панҷ донишҷӯ ва се мағозаи калидӣ тақсим карданд

Аслан, ҳамаи ин системаҳо мағозаҳои калидӣ-арзишҳои ба хатоҳо тобовар ва хаттӣ мебошанд. Гарчанде ки моделҳои додаҳои онҳо фарқиятҳои назаррас доранд, ки мо баъдтар муҳокима хоҳем кард, онҳо ҳамон як мушкилоти амалиро ҳал мекунанд. Аён аст, ки ҳар як замима, ки хидмати ҳамоҳангсозиро истифода мебарад, ба яке аз онҳо алоқаманд аст, ки метавонад ба зарурати дастгирии якчанд система дар як маркази додаҳо оварда расонад, ки мушкилоти якхеларо барои барномаҳои гуногун ҳал мекунанд.

Идеяи ҳалли ин мушкилот дар як агентии машваратии Австралия пайдо шуд ва амалӣ кардани он ба зиммаи мо, як гурӯҳи хурди донишҷӯён афтод, ки ман дар бораи он чизеро, ки ман дар бораи он сӯҳбат мекунам.

Мо тавонистем китобхонаеро созем, ки интерфейси умумиро барои кор бо ZooKeeper, etcd ва Consul KV таъмин намояд. Китобхона дар C++ навишта шудааст, аммо нақшаи интиқоли он ба забонҳои дигар вуҷуд дорад.

Моделҳои маълумот

Барои таҳияи интерфейси умумӣ барои се системаи гуногун, шумо бояд фаҳмед, ки онҳо чӣ чизи умумӣ доранд ва чӣ гуна онҳо фарқ мекунанд. Биёед инро фаҳмем.

Боғи ҳайвонот

Панҷ донишҷӯ ва се мағозаи калидӣ тақсим карданд

Калидҳо дар дарахт ташкил карда шудаанд ва гиреҳҳо номида мешаванд. Мувофиқи он, барои гиреҳ шумо метавонед рӯйхати фарзандони онро гиред. Амалиётҳои эҷоди znode (эҷод) ва тағир додани арзиш (setData) ҷудо карда мешаванд: танҳо калидҳои мавҷударо хондан ва тағир додан мумкин аст. Соатҳоро метавон ба амалиёти тафтиши мавҷудияти гиреҳ, хондани арзиш ва гирифтани кӯдакон пайваст кард. Watch як триггери якдафъаинаест, ки ҳангоми тағир додани версияи маълумоти мувофиқ дар сервер оташ мегирад. Гиреҳҳои эфемерӣ барои ошкор кардани нокомиҳо истифода мешаванд. Онҳо ба сессияи муштарӣ, ки онҳоро офаридааст, алоқаманданд. Вақте ки муштарӣ сессияро мепӯшад ё огоҳии ZooKeeperро дар бораи мавҷудияти он қатъ мекунад, ин гиреҳҳо ба таври худкор нест карда мешаванд. Амалиётҳои оддӣ дастгирӣ мешаванд - маҷмӯи амалиётҳое, ки ҳамаашон муваффақ мешаванд ё ноком мешаванд, агар ин барои ақаллан яке аз онҳо имконнопазир бошад.

ва ғайра

Панҷ донишҷӯ ва се мағозаи калидӣ тақсим карданд

Таҳиягарони ин система аз ZooKeeper ба таври возеҳ илҳом гирифтаанд ва аз ин рӯ ҳама чизро ба таври дигар карданд. Иерархияи калидҳо вуҷуд надорад, аммо онҳо маҷмӯи аз ҷиҳати лексикографӣ тартибёфтаро ташкил медиҳанд. Шумо метавонед ҳамаи калидҳоро, ки ба доираи муайян тааллуқ доранд, гиред ё нест кунед. Ин сохтор метавонад аҷиб ба назар расад, аммо он воқеан хеле ифодакунанда аст ва назари иерархӣ метавонад тавассути он ба осонӣ тақлид карда шавад.

etcd амалиёти муқоиса ва танзими стандартӣ надорад, аммо он чизи беҳтаре дорад: транзаксияҳо. Албатта, онҳо дар ҳар се система вуҷуд доранд, аммо транзаксияҳои ғайра махсусан хубанд. Онҳо аз се блок иборатанд: тафтиш, муваффақият, нокомӣ. Дар блоки якум маҷмӯи шартҳо, дуюм ва сеюм - амалиётҳо мавҷуданд. Муомилот ба таври атомӣ иҷро карда мешавад. Агар ҳамаи шартҳо дуруст бошанд, пас блоки муваффақият иҷро карда мешавад, вагарна блоки нокомӣ иҷро карда мешавад. Дар API 3.3, блокҳои муваффақият ва нокомӣ метавонанд транзаксияҳои лонаро дар бар гиранд. Яъне, ба таври атомӣ иҷро кардани конструксияҳои шартии сатҳи қариб худсарона имконпазир аст. Шумо метавонед маълумоти бештарро дар бораи кадом чекҳо ва амалиётҳо омӯзед хуччатхо.

Дар ин ҷо соатҳо низ мавҷуданд, гарчанде ки онҳо каме мураккабтаранд ва дубора истифода мешаванд. Яъне, пас аз насб кардани соат дар диапазони калидӣ, шумо ҳама навсозиҳои ин диапазонро мегиред, то даме ки соатро бекор кунед, на танҳо аввалин. Дар ва ғайра, аналоги сессияҳои муштарии ZooKeeper иҷора мебошанд.

Консул К.В.

Дар ин ҷо сохтори қатъии иерархӣ низ вуҷуд надорад, аммо Консул метавонад намуди зоҳирии мавҷударо эҷод кунад: шумо метавонед ҳамаи калидҳоро бо префикси муайяншуда дастрас ва нест кунед, яъне бо "зери дарахт" -и калид кор кунед. Чунин дархостҳо рекурсивӣ номида мешаванд. Илова бар ин, Консул метавонад танҳо калидҳоеро интихоб кунад, ки пас аз префикс аломати зикршударо дар бар намегирад, ки ба гирифтани фаврии "кӯдакон" мувофиқат мекунад. Аммо бояд дар хотир дошт, ки ин маҳз намуди сохтори иерархӣ аст: комилан имконпазир аст, ки калидро эҷод кунед, агар волидайни он вуҷуд надошта бошад ё калиди дорои кӯдаконро нест кунед, дар ҳоле ки кӯдакон дар система нигоҳ дошта мешаванд.

Панҷ донишҷӯ ва се мағозаи калидӣ тақсим карданд
Ба ҷои соатҳо, консул дархостҳои HTTP-ро манъ мекунад. Дар асл, инҳо зангҳои оддӣ ба усули хондани маълумот мебошанд, ки барои онҳо дар баробари дигар параметрҳо версияи охирини маълуми додаҳо нишон дода шудааст. Агар версияи ҷории маълумоти мувофиқ дар сервер аз версияи муқарраршуда зиёдтар бошад, ҷавоб фавран баргардонида мешавад, дар акси ҳол - вақте ки арзиш тағир меёбад. Инчунин сеансҳо мавҷуданд, ки метавонанд ба калидҳо дар вақти дилхоҳ замима шаванд. Бояд қайд кард, ки бар хилофи etcd ва ZooKeeper, ки дар он нест кардани сессияҳо ба нест кардани калидҳои алоқаманд оварда мерасонад, режиме мавҷуд аст, ки дар он сессия танҳо аз онҳо ҷудо карда мешавад. дастрас муомилот, бе шохахо, балки бо хар гуна чекхо.

Ҳама чизро якҷоя кардан

ZooKeeper дорои модели дақиқтарини маълумот мебошад. Дархостҳои диапазони экспрессивӣ, ки дар etcd мавҷуданд, наметавонанд дар ZooKeeper ё Консул ба таври муассир тақлид карда шаванд. Бо кӯшиши ворид кардани беҳтарин хидматҳо, мо интерфейси тақрибан ба интерфейси ZooKeeper бо истисноҳои муҳими зеринро ба даст овардем:

  • пайдарпай, контейнер ва гиреҳҳои TTL дастгирӣ намешавад
  • ACL дастгирӣ намешавад
  • усули муқаррар калидро эҷод мекунад, агар он вуҷуд надошта бошад (дар ZK setData дар ин ҳолат хатогиро бармегардонад)
  • усулҳои set ва cas ҷудо карда шудаанд (дар ZK онҳо аслан як чиз мебошанд)
  • усули тозакунӣ гиреҳро бо зердарахти он нест мекунад (дар ZK нест кардан хатогиро бармегардонад, агар гиреҳ кӯдакон дошта бошад)
  • Барои ҳар як калид танҳо як версия мавҷуд аст - версияи арзиш (дар ZK се нафари онҳо ҳастанд)

Рад кардани гиреҳҳои пайдарпай аз он сабаб аст, ки etcd ва Consul барои онҳо дастгирии дарунсохт надоранд ва онҳо метавонанд аз ҷониби корбар дар болои интерфейси китобхона ба осонӣ амалӣ карда шаванд.

Татбиқи рафтори монанд ба ZooKeeper ҳангоми нест кардани қулла нигоҳ доштани ҳисобкунаки алоҳидаи кӯдаконро барои ҳар як калид дар etcd ва Consul талаб мекунад. Азбаски мо кӯшиш кардем, ки аз нигоҳ доштани иттилооти мета худдорӣ кунем, қарор шуд, ки тамоми зер дарахтро нест кунем.

Нозукиҳои татбиқ

Биёед баъзе ҷанбаҳои татбиқи интерфейси китобхонаро дар системаҳои гуногун дида бароем.

Иерархия дар ва ғайра

Нигоҳ доштани назари иерархӣ дар etcd яке аз вазифаҳои ҷолибтарин гардид. Дархостҳои диапазон дарёфти рӯйхати калидҳоро бо префикси муайян осон мекунанд. Масалан, агар ба шумо ҳама чизе, ки бо оғоз лозим аст "/foo", шумо барои диапазон дархост мекунед ["/foo", "/fop"). Аммо ин тамоми зердарахти калидро бармегардонад, ки агар зердарахт калон бошад, қобили қабул нест. Дар аввал мо нақша доштем, ки механизми асосии тарҷумаро истифода барем, дар zetcd амалӣ карда мешавад. Он илова кардани як байтро дар аввали калид дар бар мегирад, ки ба умқи гиреҳ дар дарахт баробар аст. Ичозат дихед ба шумо як мисол оварам.

"/foo" -> "u01/foo"
"/foo/bar" -> "u02/foo/bar"

Сипас ҳамаи фарзандони фаврии калидро гиред "/foo" бо дархости диапазон имконпазир аст ["u02/foo/", "u02/foo0"). Бале, дар ASCII "0" рост баъд аз он меистад "/".

Аммо дар ин ҳолат бартараф кардани вертексро чӣ гуна бояд амалӣ кард? Маълум мешавад, ки шумо бояд ҳамаи диапазонҳои намудро нест кунед ["uXX/foo/", "uXX/foo0") барои XX аз 01 то FF. Ва он гоҳ мо дучор омадем маҳдудияти рақами амалиёт дар як транзаксия.

Дар натиҷа, системаи оддии табдилдиҳии калидҳо ихтироъ карда шуд, ки он имкон дод, ки ҳам нест кардани калид ва ҳам гирифтани рӯйхати кӯдакон самаранок амалӣ карда шавад. Пеш аз нишонаи охирин илова кардани аломати махсус кифоя аст. Барои намуна:

"/very" -> "/u00very"
"/very/long" -> "/very/u00long"
"/very/long/path" -> "/very/long/u00path"

Сипас калидро нест кунед "/very" ба нестшавӣ табдил меёбад "/u00very" ва диапазон ["/very/", "/very0"), ва гирифтани ҳамаи кӯдакон - дар дархост барои калидҳо аз диапазон ["/very/u00", "/very/u01").

Хориҷ кардани калид дар ZooKeeper

Тавре ки ман аллакай зикр кардам, шумо дар ZooKeeper гиреҳро нест карда наметавонед, агар он кӯдакон дошта бошад. Мо мехоҳем калидро дар якҷоягӣ бо зердарахт нест кунем. Ман бояд чӣ кунам? Мо ин корро бо некбинона мекунем. Аввалан, мо зердарахтро рекурсивӣ мегузарем ва фарзандони ҳар як қулларо бо дархости алоҳида мегирем. Сипас, мо транзаксия месозем, ки кӯшиш мекунад, ки ҳама гиреҳҳои зердарахтро бо тартиби дуруст нест кунад. Албатта, байни хондани зердарахт ва нест кардани он тағирот ба амал омада метавонад. Дар ин ҳолат, транзаксия ноком мешавад. Илова бар ин, зердарахт дар ҷараёни хониш метавонад тағир ёбад. Дархост барои кӯдакони гиреҳи навбатӣ метавонад хато баргардонад, агар масалан, ин гиреҳ аллакай нест карда шуда бошад. Дар ҳарду ҳолат, мо тамоми равандро дубора такрор мекунем.

Ин равиш нест кардани калидро, агар он фарзанд дошта бошад, хеле бесамар мегардонад ва ҳатто бештар аз он, агар барнома кор бо зердарахтро идома диҳад, нест кардан ва сохтани калидҳо. Аммо, ин ба мо имкон дод, ки ба мушкилии татбиқи усулҳои дигар дар etcd ва Consul роҳ надиҳем.

дар ZooKeeper насб карда шудааст

Дар ZooKeeper усулҳои алоҳидае мавҷуданд, ки бо сохтори дарахт кор мекунанд (эҷод кардан, нест кардан, getChildren) ва бо додаҳо дар гиреҳҳо кор мекунанд (setData, getData) Гузашта аз ин, ҳамаи усулҳо шартҳои қатъӣ доранд: эҷод хаторо бармегардонад, агар гиреҳ аллакай мавҷуд бошад. сохта шудааст, нест кунед ё setData - агар он аллакай вуҷуд надошта бошад. Ба мо як усули муқарраршуда лозим буд, ки онро бидуни фикр дар бораи мавҷудияти калид даъват кардан мумкин аст.

Як вариант ин аст, ки муносибати некбинона ба мисли ҳазф. Санҷед, ки оё гиреҳ вуҷуд дорад. Агар мавҷуд бошад, setData-ро даъват кунед, дар акси ҳол эҷод кунед. Агар усули охирин хатогиро баргардонад, онро дубора такрор кунед. Аввалин чизе, ки бояд қайд кард, ин аст, ки санҷиши мавҷудият бемаънӣ аст. Шумо метавонед фавран ба эҷод занг занед. Анҷоми бомуваффақият маънои онро дорад, ки гиреҳ вуҷуд надошт ва он офарида шудааст. Дар акси ҳол, эҷод хатои мувофиқро бармегардонад, ки пас аз он шумо бояд setData-ро даъват кунед. Албатта, дар байни зангҳо, қулларо тавассути занги рақобаткунанда нест кардан мумкин аст ва setData инчунин хатогиро бармегардонад. Дар ин ҳолат, шумо метавонед онро дубора иҷро кунед, аммо оё ин меарзад?

Агар ҳарду усул хатогиро баргардонанд, мо аниқ медонем, ки ҳазфи рақобаткунанда сурат гирифтааст. Тасаввур кунем, ки ин ҳазф пас аз даъвати set ба амал омад. Он гоҳ ҳар маъное, ки мо барои таъсис додани он кӯшиш мекунем, аллакай нест карда мешавад. Ин маънои онро дорад, ки мо метавонем тахмин кунем, ки маҷмӯа бомуваффақият иҷро шудааст, ҳатто агар дар асл чизе навишта нашуда бошад.

Тафсилоти бештари техникӣ

Дар ин бахш мо аз системаҳои тақсимшуда танаффус мегирем ва дар бораи рамзгузорӣ сӯҳбат мекунем.
Яке аз талаботи асосии муштарӣ кросс-платформа буд: ҳадди аққал яке аз хидматҳо бояд дар Linux, MacOS ва Windows дастгирӣ карда шаванд. Дар аввал, мо танҳо барои Linux таҳия кардем ва баъдтар озмоишро дар дигар системаҳо оғоз кардем. Ин боиси мушкилоти зиёде гардид, ки чанд вақт ба онҳо чӣ гуна муносибат кардан комилан норавшан буд. Дар натиҷа, ҳама се хадамоти ҳамоҳангсозӣ ҳоло дар Linux ва MacOS дастгирӣ мешаванд, дар ҳоле ки танҳо Consul KV дар Windows дастгирӣ карда мешавад.

Мо аз аввал кӯшиш мекардем, ки барои дастрасӣ ба хидматрасонӣ аз китобхонаҳои омода истифода барем. Дар мавриди ZooKeeper, интихоб афтод ZooKeeper C++, ки дар ниҳоят дар Windows тартиб дода натавонист. Аммо, ин тааҷҷубовар нест: китобхона ҳамчун Linux танҳо ҷойгир аст. Барои консул ягона вариант буд консул. Дастгириро ба он илова кардан лозим буд ҷаласаҳои и муомилот. Барои etcd, китобхонаи мукаммале, ки версияи охирини протоколро дастгирӣ мекунад, ёфт нашуд, бинобар ин мо танҳо муштарии grpc тавлидшуда.

Аз интерфейси асинхронии китобхонаи ZooKeeper C++ илҳом гирифта, мо тасмим гирифтем, ки интерфейси асинхронӣ низ татбиқ кунем. ZooKeeper C++ барои ин примитивҳои оянда/ваъдаро истифода мебарад. Дар STL, мутаассифона, онҳо хеле хоксорона амалӣ карда мешаванд. Масалан, не пас усул, ки функсияи додашударо ба натиҷаи оянда ҳангоми дастрас шудани он татбиқ мекунад. Дар мо чунин усул барои табдил додани натиҷа ба формати китобхонаи мо зарур аст. Барои бартараф кардани ин мушкилот, мо маҷбур шудем, ки ҳавзи риштаи оддии худро амалӣ кунем, зеро бо дархости муштарӣ мо наметавонистем китобхонаҳои вазнини тарафи сеюмро ба мисли Boost истифода барем.

Татбиқи он вақт мо чунин кор мекунад. Вақте ки даъват карда мешавад, ваъдаи иловагӣ / ҷуфти оянда сохта мешавад. Ояндаи нав баргардонида мешавад ва ояндаи гузашта дар якҷоягӣ бо функсияи мувофиқ ва ваъдаи иловагӣ дар навбат ҷойгир карда мешавад. Ришта аз ҳавз якчанд фьючерсро аз навбат интихоб мекунад ва онҳоро бо истифода аз wait_for пурсиш мекунад. Вақте ки натиҷа дастрас мешавад, функсияи мувофиқ даъват карда мешавад ва арзиши бозгашти он ба ваъда дода мешавад.

Мо ҳамон ҳавзи риштаро барои иҷро кардани дархостҳо ба etcd ва Consul истифода бурдем. Ин маънои онро дорад, ки ба китобхонаҳои асосӣ метавонанд тавассути якчанд риштаҳои гуногун дастрасӣ пайдо кунанд. ppconsul ришта бехатар нест, бинобар ин зангҳо ба он бо қулфҳо ҳифз карда мешаванд.
Шумо метавонед бо grpc аз риштаҳои гуногун кор кунед, аммо нозукиҳо вуҷуд доранд. Дар etcd соатҳо тавассути ҷараёнҳои grpc амалӣ карда мешаванд. Инҳо каналҳои дуҷониба барои паёмҳои як намуди муайян мебошанд. Китобхона як риштаи ягона барои ҳама соатҳо ва як риштаи ягонаеро, ки паёмҳои воридотӣ коркард мекунад, эҷод мекунад. Ҳамин тавр, grpc навиштани параллелро барои ҷараён манъ мекунад. Ин маънои онро дорад, ки ҳангоми оғоз кардан ё нест кардани соат, шумо бояд интизор шавед, ки дархости қаблӣ фиристодани дархости дигарро ба анҷом расонад. Мо барои ҳамоҳангсозӣ истифода мебарем тағирёбандаҳои шартӣ.

Натиҷа

Ба худатон нигаред: liboffkv.

Гурӯҳи мо: Раед Романов, Иван Глушенков, Дмитрий Камалдинов, Виктор Крапивенский, Виталий Иванин.

Манбаъ: will.com

Илова Эзоҳ