Wanafunzi watano na watatu walisambaza duka za thamani kuu

Au jinsi tulivyoandika maktaba ya mteja C++ ya ZooKeeper, etcd na Consul KV

Katika ulimwengu wa mifumo iliyosambazwa, kuna idadi ya kazi za kawaida: kuhifadhi habari juu ya muundo wa nguzo, kudhibiti usanidi wa nodi, kugundua nodi mbaya, kuchagua kiongozi. na wengine. Ili kutatua matatizo haya, mifumo maalum ya kusambazwa imeundwa - huduma za uratibu. Sasa tutavutiwa na watatu kati yao: ZooKeeper, etcd na Consul. Kati ya utendaji mzuri wa Balozi, tutazingatia Balozi wa KV.

Wanafunzi watano na watatu walisambaza duka za thamani kuu

Kwa asili, mifumo hii yote ni duka za thamani kuu zinazostahimili makosa. Ingawa mifano yao ya data ina tofauti kubwa, ambayo tutajadili baadaye, wao hutatua matatizo sawa ya vitendo. Kwa wazi, kila programu inayotumia huduma ya uratibu imefungwa kwa mmoja wao, ambayo inaweza kusababisha haja ya kuunga mkono mifumo kadhaa katika kituo kimoja cha data ambacho hutatua matatizo sawa kwa programu tofauti.

Wazo la kutatua tatizo hili lilitokana na wakala wa ushauri wa Australia, na ilituangukia sisi, timu ndogo ya wanafunzi, kulitekeleza, ambalo ndilo nitakalozungumzia.

Tuliweza kuunda maktaba ambayo hutoa kiolesura cha kawaida cha kufanya kazi na ZooKeeper, etcd na Consul KV. Maktaba imeandikwa kwa C ++, lakini kuna mipango ya kuipeleka kwa lugha zingine.

Data Models

Kuendeleza kiolesura cha kawaida kwa mifumo mitatu tofauti, unahitaji kuelewa wanachofanana na jinsi wanavyotofautiana. Hebu tufikirie.

Mtunza Zoo

Wanafunzi watano na watatu walisambaza duka za thamani kuu

Funguo hupangwa kwenye mti na huitwa nodes. Ipasavyo, kwa node unaweza kupata orodha ya watoto wake. Shughuli za kuunda znode (kuunda) na kubadilisha thamani (setData) zimetenganishwa: funguo zilizopo tu zinaweza kusoma na kubadilishwa. Saa zinaweza kushikamana na shughuli za kuangalia uwepo wa nodi, kusoma thamani, na kupata watoto. Saa ni kichochezi cha mara moja ambacho huwaka wakati toleo la data inayolingana kwenye seva inabadilika. Node za ephemeral hutumiwa kuchunguza kushindwa. Wamefungwa kwenye kikao cha mteja aliyewaumba. Wakati mteja anafunga kipindi au anaacha kuarifu ZooKeeper kuhusu kuwepo kwake, nodi hizi hufutwa kiotomatiki. Shughuli rahisi zinaauniwa - seti ya shughuli ambazo zote hufaulu au kutofaulu ikiwa hii haiwezekani kwa angalau moja yao.

nk

Wanafunzi watano na watatu walisambaza duka za thamani kuu

Waendelezaji wa mfumo huu waliongozwa wazi na ZooKeeper, na kwa hiyo walifanya kila kitu tofauti. Hakuna daraja la funguo, lakini huunda seti iliyoagizwa kwa leksikografia. Unaweza kupata au kufuta funguo zote za masafa fulani. Muundo huu unaweza kuonekana kuwa wa kushangaza, lakini kwa kweli unaelezea sana, na mtazamo wa kihierarkia unaweza kuigwa kwa urahisi kupitia hilo.

etcd haina operesheni ya kawaida ya kulinganisha-na-seti, lakini ina kitu bora zaidi: shughuli. Kwa kweli, zipo katika mifumo yote mitatu, lakini shughuli za etcd ni nzuri sana. Wao hujumuisha vitalu vitatu: kuangalia, mafanikio, kushindwa. Kizuizi cha kwanza kina seti ya masharti, ya pili na ya tatu - shughuli. Muamala unatekelezwa kwa atomi. Ikiwa hali zote ni kweli, basi kizuizi cha mafanikio kinatekelezwa, vinginevyo kizuizi cha kushindwa kinatekelezwa. Katika API 3.3, vizuizi vya mafanikio na kutofaulu vinaweza kuwa na shughuli zilizowekwa. Hiyo ni, inawezekana kutekeleza kwa atomi miundo ya masharti ya kiwango cha karibu kiholela cha kutagia. Unaweza kujifunza zaidi kuhusu hundi na uendeshaji zipo nyaraka.

Saa zipo hapa pia, ingawa ni ngumu zaidi na zinaweza kutumika tena. Hiyo ni, baada ya kusakinisha saa kwenye safu muhimu, utapokea sasisho zote kwenye safu hii hadi ughairi saa, na sio ya kwanza tu. Katika etcd, analog ya vikao vya mteja vya ZooKeeper ni kukodisha.

Balozi K.V.

Pia hakuna muundo madhubuti wa hali ya juu hapa, lakini Balozi anaweza kuunda mwonekano uliopo: unaweza kupata na kufuta funguo zote na kiambishi awali kilichoainishwa, ambayo ni, fanya kazi na "mti mdogo" wa ufunguo. Maswali kama haya huitwa kujirudia. Kwa kuongezea, Balozi anaweza kuchagua funguo tu ambazo hazina herufi maalum baada ya kiambishi awali, ambacho kinalingana na kupata "watoto" wa karibu. Lakini inafaa kukumbuka kuwa hii ndio muonekano wa muundo wa hali ya juu: inawezekana kabisa kuunda ufunguo ikiwa mzazi wake haipo au kufuta ufunguo ambao una watoto, wakati watoto wataendelea kuhifadhiwa kwenye mfumo.

Wanafunzi watano na watatu walisambaza duka za thamani kuu
Badala ya saa, Balozi anazuia maombi ya HTTP. Kwa asili, hizi ni simu za kawaida kwa njia ya kusoma data, ambayo, pamoja na vigezo vingine, toleo la mwisho linalojulikana la data linaonyeshwa. Ikiwa toleo la sasa la data inayolingana kwenye seva ni kubwa zaidi kuliko ile iliyoainishwa, jibu linarejeshwa mara moja, vinginevyo - wakati thamani inabadilika. Pia kuna vipindi ambavyo vinaweza kuunganishwa kwa funguo wakati wowote. Inafaa kumbuka kuwa tofauti na etcd na ZooKeeper, ambapo kufuta vikao husababisha kufutwa kwa funguo zinazohusiana, kuna hali ambayo kikao hakijaunganishwa kutoka kwao. Inapatikana shughuli, bila matawi, lakini kwa kila aina ya hundi.

Kuweka yote pamoja

ZooKeeper ina modeli ya data kali zaidi. Hoja za masafa ya kueleweka zinazopatikana katika etcd haziwezi kuigwa vyema katika ZooKeeper au Consul. Kujaribu kujumuisha bora zaidi kutoka kwa huduma zote, tuliishia na kiolesura karibu sawa na kiolesura cha ZooKeeper isipokuwa vifuatavyo muhimu vifuatavyo:

  • mlolongo, kontena na nodi za TTL haijaungwa mkono
  • ACL hazitumiki
  • njia iliyowekwa huunda ufunguo ikiwa haipo (katika ZK setData inarudisha kosa katika kesi hii)
  • kuweka na njia za cas zimetenganishwa (katika ZK kimsingi ni kitu kimoja)
  • njia ya kufuta hufuta nodi pamoja na subtree yake (katika ZK kufuta inarudisha kosa ikiwa nodi ina watoto)
  • Kwa kila ufunguo kuna toleo moja tu - toleo la thamani (katika ZK wapo watatu)

Kukataliwa kwa nodi zinazofuatana ni kutokana na ukweli kwamba etcd na Consul hawana usaidizi wa ndani kwao, na zinaweza kutekelezwa kwa urahisi na mtumiaji juu ya kiolesura cha maktaba kinachotokana.

Utekelezaji wa tabia sawa na ZooKeeper wakati wa kufuta kipeo kutahitaji kudumisha kihesabu tofauti cha watoto kwa kila funguo katika etcd na Consul. Kwa kuwa tulijaribu kuepuka kuhifadhi maelezo ya meta, iliamuliwa kufuta mti mdogo wote.

Fichika za utekelezaji

Hebu tuchunguze kwa undani baadhi ya vipengele vya kutekeleza kiolesura cha maktaba katika mifumo tofauti.

Hierarkia katika nk

Kudumisha mtazamo wa daraja katika etcd kuligeuka kuwa mojawapo ya kazi zinazovutia zaidi. Hoji za masafa hurahisisha kupata orodha ya funguo zilizo na kiambishi awali maalum. Kwa mfano, ikiwa unahitaji kila kitu kinachoanza "/foo", unaomba masafa ["/foo", "/fop"). Lakini hii inaweza kurudisha mti mdogo wa ufunguo, ambao hauwezi kukubalika ikiwa mti mdogo ni mkubwa. Mwanzoni tulipanga kutumia utaratibu muhimu wa kutafsiri, kutekelezwa katika zetcd. Inajumuisha kuongeza byte moja mwanzoni mwa ufunguo, sawa na kina cha node kwenye mti. Ngoja nikupe mfano.

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

Kisha pata watoto wote wa haraka wa ufunguo "/foo" iwezekanavyo kwa kuomba masafa ["u02/foo/", "u02/foo0"). Ndiyo, katika ASCII "0" inasimama baada ya hapo "/".

Lakini jinsi ya kutekeleza kuondolewa kwa vertex katika kesi hii? Inatokea kwamba unahitaji kufuta safu zote za aina ["uXX/foo/", "uXX/foo0") kwa XX kutoka 01 hadi FF. Na kisha tukakimbilia kikomo cha nambari ya operesheni ndani ya muamala mmoja.

Matokeo yake, mfumo rahisi wa uongofu wa ufunguo ulipatikana, ambao ulifanya iwezekanavyo kutekeleza kwa ufanisi wote kufuta ufunguo na kupata orodha ya watoto. Inatosha kuongeza tabia maalum kabla ya ishara ya mwisho. Kwa mfano:

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

Kisha kufuta ufunguo "/very" inageuka kuwa kufuta "/u00very" na mbalimbali ["/very/", "/very0"), na kupata watoto wote - kwa ombi la funguo kutoka kwa safu ["/very/u00", "/very/u01").

Kuondoa ufunguo katika ZooKeeper

Kama nilivyosema tayari, katika ZooKeeper huwezi kufuta nodi ikiwa ina watoto. Tunataka kufuta ufunguo pamoja na mti mdogo. Nifanye nini? Tunafanya hivi kwa matumaini. Kwanza, tunapitia tena mti mdogo, tukipata watoto wa kila vertex na swala tofauti. Kisha tunaunda shughuli ambayo inajaribu kufuta nodes zote za subtree kwa utaratibu sahihi. Bila shaka, mabadiliko yanaweza kutokea kati ya kusoma mti mdogo na kuifuta. Katika kesi hii, shughuli itashindwa. Aidha, subtree inaweza kubadilika wakati wa mchakato wa kusoma. Ombi kwa watoto wa node inayofuata inaweza kurudisha kosa ikiwa, kwa mfano, node hii tayari imefutwa. Katika visa vyote viwili, tunarudia mchakato mzima tena.

Mbinu hii hufanya kufuta ufunguo kutofaulu sana ikiwa ina watoto, na hata zaidi ikiwa programu itaendelea kufanya kazi na mti mdogo, kufuta na kuunda funguo. Hata hivyo, hii ilituruhusu kuepuka kutatiza utekelezaji wa mbinu nyingine katika etcd na Consul.

kuweka katika ZooKeeper

Katika ZooKeeper kuna mbinu tofauti zinazofanya kazi na muundo wa mti (tengeneza, kufuta, getChildren) na zinazofanya kazi na data katika nodi (setData, getData) Zaidi ya hayo, mbinu zote zina masharti magumu: kuunda kutarudisha kosa ikiwa nodi tayari imeundwa, kufuta au kuwekaData - ikiwa haipo tayari. Tulihitaji njia iliyowekwa ambayo inaweza kuitwa bila kufikiria juu ya uwepo wa ufunguo.

Chaguo moja ni kuchukua njia ya matumaini, kama vile kufuta. Angalia ikiwa nodi ipo. Ikiwa ipo, piga simu setData, vinginevyo unda. Ikiwa njia ya mwisho ilileta hitilafu, irudie tena. Jambo la kwanza kukumbuka ni kwamba mtihani wa kuwepo hauna maana. Unaweza kupiga simu kuunda mara moja. Kukamilika kwa mafanikio kutamaanisha kuwa node haikuwepo na iliundwa. Vinginevyo, kuunda itarudisha kosa linalofaa, baada ya hapo unahitaji kupiga simu setData. Kwa kweli, kati ya simu, vertex inaweza kufutwa na simu inayoshindana, na setData pia itarudisha kosa. Katika kesi hii, unaweza kufanya hivyo tena, lakini ni thamani yake?

Ikiwa njia zote mbili zitarudisha kosa, basi tunajua kwa hakika kuwa ufutaji unaoshindana ulifanyika. Wacha tufikirie kuwa ufutaji huu ulitokea baada ya kuweka simu. Kisha maana yoyote tunayojaribu kuanzisha tayari imefutwa. Hii inamaanisha kuwa tunaweza kudhani kuwa seti ilitekelezwa kwa mafanikio, hata ikiwa hakuna chochote kilichoandikwa.

Maelezo zaidi ya kiufundi

Katika sehemu hii tutapumzika kutoka kwa mifumo iliyosambazwa na kuzungumza juu ya kuweka msimbo.
Moja ya mahitaji kuu ya mteja ilikuwa jukwaa la msalaba: angalau moja ya huduma lazima ziungwe mkono kwenye Linux, MacOS na Windows. Hapo awali, tulitengeneza Linux pekee, na tukaanza kujaribu kwenye mifumo mingine baadaye. Hii ilisababisha shida nyingi, ambazo kwa muda hazikuwa wazi kabisa jinsi ya kukaribia. Kwa hivyo, huduma zote tatu za uratibu sasa zinatumika kwenye Linux na MacOS, wakati Mshauri wa KV pekee ndiye anayetumika kwenye Windows.

Tangu mwanzo kabisa, tulijaribu kutumia maktaba zilizotengenezwa tayari kupata huduma. Kwa upande wa ZooKeeper, chaguo lilianguka ZooKeeper C++, ambayo hatimaye ilishindwa kujumuisha kwenye Windows. Hii, hata hivyo, haishangazi: maktaba imewekwa kama linux-pekee. Kwa Balozi chaguo pekee lilikuwa ppconsul. Usaidizi ulipaswa kuongezwa kwake vipindi и shughuli. Kwa etcd, maktaba kamili inayotumia toleo la hivi punde la itifaki haikupatikana, kwa hivyo sisi kwa urahisi mteja wa grpc inayozalishwa.

Kwa kuhamasishwa na kiolesura kisicholingana cha maktaba ya ZooKeeper C++, tuliamua pia kutekeleza kiolesura kisicholingana. ZooKeeper C++ hutumia primitives za baadaye/ahadi kwa hili. Katika STL, kwa bahati mbaya, zinatekelezwa kwa unyenyekevu sana. Kwa mfano, hapana kisha mbinu, ambayo inatumika kazi iliyopitishwa kwa matokeo ya siku zijazo wakati inapatikana. Kwa upande wetu, njia kama hiyo ni muhimu kubadilisha matokeo kuwa muundo wa maktaba yetu. Ili kukabiliana na tatizo hili, ilitubidi kutekeleza mazungumzo yetu rahisi, kwa kuwa kwa ombi la mteja hatukuweza kutumia maktaba nzito za wahusika wengine kama vile Boost.

Utekelezaji wetu basi hufanya kazi kama hii. Inapoitwa, ahadi ya ziada/jozi ya baadaye huundwa. Wakati ujao mpya unarejeshwa, na iliyopitishwa imewekwa pamoja na kazi inayofanana na ahadi ya ziada kwenye foleni. Mazungumzo kutoka kwenye bwawa huchagua mustakabali kadhaa kutoka kwa foleni na kuyapigia kura kwa kutumia wait_for. Wakati matokeo yanapatikana, kazi inayolingana inaitwa na thamani yake ya kurudi inapitishwa kwa ahadi.

Tulitumia uzi huo huo kutekeleza maswali kwa etcd na Consul. Hii inamaanisha kuwa maktaba za msingi zinaweza kufikiwa na nyuzi nyingi tofauti. ppconsul sio salama kwa uzi, kwa hivyo simu kwake zinalindwa na kufuli.
Unaweza kufanya kazi na grpc kutoka kwa nyuzi nyingi, lakini kuna hila. Katika etcd saa hutekelezwa kupitia mitiririko ya grpc. Hizi ni njia mbili za ujumbe wa aina fulani. Maktaba huunda thread moja kwa saa zote na thread moja ambayo huchakata ujumbe unaoingia. Kwa hivyo grpc inakataza uandikaji sambamba kutiririsha. Hii ina maana kwamba unapoanzisha au kufuta saa, lazima usubiri hadi ombi la awali likamilishe kutuma kabla ya kutuma nyingine. Tunatumia kwa maingiliano vigezo vya masharti.

Jumla ya

Kuona mwenyewe: liboffkv.

Timu yetu: Raed Romanov, Ivan Glushenkov, Dmitry Kamaldinov, Victor Krapivensky, Vitaly Ivanin.

Chanzo: mapenzi.com

Kuongeza maoni