Pênc xwendekar û sê firotgehên key-nirxê belav kirin

An jî me çawa pirtûkxaneyek C++ ya xerîdar ji bo ZooKeeper, etcd û Konsul KV nivîsand

Di cîhana pergalên belavbûyî de, hejmarek peywirên tîpîk hene: hilanîna agahdariya li ser pêkhateya komê, birêvebirina veavakirina girêkan, tespîtkirina girêkên xelet, hilbijartina serokek. û din. Ji bo çareserkirina van pirsgirêkan, pergalên dabeşkirî yên taybetî hatine afirandin - karûbarên hevrêziyê. Naha em ê bi sê ji wan re eleqedar bibin: ZooKeeper, etcd û Konsul. Ji derveyî hemî fonksiyonên dewlemend ên Konsulê, em ê li ser Konsul KV bisekinin.

Pênc xwendekar û sê firotgehên key-nirxê belav kirin

Di eslê xwe de, van hemî pergal dikanên nirx-nirxa sereke yên xêzker-tehemûl in. Her çend modelên daneyên wan cûdahiyên girîng hene, ku em ê paşê nîqaş bikin, ew heman pirsgirêkên pratîkî çareser dikin. Eşkere ye, her serîlêdana ku karûbarê hevrêziyê bikar tîne bi yek ji wan ve girêdayî ye, ku dibe ku bibe sedema hewcedariya piştgirîkirina çend pergalên di yek navendek daneyê de ku heman pirsgirêkan ji bo serîlêdanên cihêreng çareser dike.

Fikra çareserkirina vê pirsgirêkê ji ajansek şêwirmendiyê ya Avusturalya derket holê, û ew ket destê me, tîmek piçûk a xwendekaran, ku em wê bicîh bikin, ya ku ez ê li ser biaxivim ev e.

Me karî pirtûkxaneyek biafirîne ku ji bo xebata bi ZooKeeper, etcd û Consul KV re navgînek hevpar peyda dike. Pirtûkxane bi C++ hatiye nivîsandin, lê plan hene ku wê bi zimanên din veguhezînin.

Modelên Daneyên

Ji bo pêşvebirina navgînek hevbeş ji bo sê pergalên cûda, hûn hewce ne ku hûn fêm bikin ka wan çi hevpar e û ew çawa cûda dibin. Werin em wê bihesibînin.

ZooKeeper

Pênc xwendekar û sê firotgehên key-nirxê belav kirin

Mift di nav darekê de têne organîze kirin û jê re girêk tê gotin. Li gorî vê yekê, ji bo nodek hûn dikarin navnîşek zarokên wê bistînin. Operasyonên afirandina znode (çêkirin) û guheztina nirxek (setData) têne veqetandin: tenê mifteyên heyî dikarin werin xwendin û guheztin. Saet dikare bi operasyonên kontrolkirina hebûna girêk, xwendina nirxek, û girtina zarokan ve were girêdan. Watch tetikek yek-car e ku dema ku guhertoya daneyên têkildar ên li ser serverê diguhezîne dişewite. Girêkên efemeral ji bo tespîtkirina têkçûnan têne bikar anîn. Ew bi rûniştina xerîdar a ku wan afirandiye ve girêdayî ne. Dema ku xerîdar danişînek digire an agahdarkirina ZooKeeper ji hebûna xwe rawestîne, ev nod bixweber têne jêbirin. Danûstandinên hêsan têne piştgirî kirin - komek operasyonan ku hemî biserkevin an jî têk biçin heke ev yek ji wan kêm nebe.

etcd

Pênc xwendekar û sê firotgehên key-nirxê belav kirin

Pêşdebirên vê pergalê bi eşkere ji ZooKeeper îlham girtin, û ji ber vê yekê her tişt cûda kirin. Hiyerarşiya kilîtan tune, lê ew komek rêzkirî ya ferhengî pêk tînin. Hûn dikarin hemî bişkokên ku di nav rêzek diyarkirî de ne bistînin an jêbirin. Dibe ku ev avahî xerîb xuya bike, lê ew bi rastî pir diyarker e, û nêrînek hiyerarşîk bi hêsanî dikare bi navgîniya wê ve were nimûne.

etcd ne xwedan operasyonek standard-berhevkirin û danîna ye, lê tiştek çêtir heye: danûstandin. Bê guman, ew di her sê pergalan de hene, lê danûstandinên etcd bi taybetî baş in. Ew ji sê blokan pêk tên: kontrol, serkeftin, têkçûn. Bloka yekem komek şertan vedihewîne, ya duyemîn û sêyemîn - operasyonan. Danûstandin bi atomî tê kirin. Heke hemî şert rast bin, wê hingê bloka serfiraziyê tête darve kirin, wekî din bloka têkçûnê tête darve kirin. Di API 3.3 de, blokên serketî û têkçûnê dikarin danûstendinên hêlîn hene. Ango, mimkun e ku bi atomî avahîyên şertî yên asta hêlînê hema hema kêfî werin darve kirin. Hûn dikarin bêtir fêr bibin ka ji kîjan kontrol û operasyonan hene belgekirin.

Saet li vir jî hene, her çend ew hinekî tevlihevtir in û ji nû ve têne bikar anîn. Ango, piştî sazkirina demjimêrek li ser rêzek sereke, hûn ê hemî nûvekirinên di vê rêzê de bistînin heya ku hûn demjimêrê betal bikin, ne tenê ya yekem. Wekî din, analoga danişînên xerîdar ên ZooKeeper kirê ne.

Konsolos K.V.

Li vir avahiyek hişk a hiyerarşîk jî tune, lê Konsul dikare xuyangê ku ew heye biafirîne: hûn dikarin hemî bişkojkên bi pêşgira diyarkirî bistînin û jêbirin, ango, bi "bindara" ya mifteyê re bixebitin. Ji pirsên weha rekursîv tê gotin. Digel vê yekê, Konsul dikare tenê bişkojkên ku karaktera diyarkirî li dû pêşgira ku bi wergirtina "zarokên" tavilê ve girêdayî ne hilbijêrin hilbijêrin. Lê hêjayî bibîrxistinê ye ku ev bi rastî xuyangiya avahiyek hiyerarşîk e: heke dêûbavê wê tune be meriv mifteyek çêbike an miftek ku zarok jê re heye jê bibe, dema ku zarok dê di pergalê de bêne hilanîn.

Pênc xwendekar û sê firotgehên key-nirxê belav kirin
Li şûna demjimêran, Konsul daxwazên HTTP-ê asteng dike. Di eslê xwe de, ev bangên asayî ne ji bo rêbaza xwendina daneyê, ji bo ku, digel pîvanên din, guhertoya paşîn a naskirî ya daneyê tê destnîşan kirin. Ger guhertoya heyî ya daneyên têkildar ên li ser serverê ji ya diyarkirî mezintir e, bersiv tavilê tê vegerandin, wekî din - gava ku nirx diguhezîne. Di heman demê de danişîn hene ku dikarin di her kêliyê de bi kilîtan ve werin girêdan. Hêjayî gotinê ye ku berevajî etcd û ZooKeeper, ku jêbirina danişînan dibe sedema jêbirina bişkokên têkildar, modek heye ku tê de danişîn bi tenê ji wan veqetandî ye. Berdeste muamele, bê şax, lê bi her cûre kontrol.

Hemî li hev xistin

ZooKeeper modela daneya herî hişk heye. Pirsên rêza diyarker ên ku di etcd de têne peyda kirin ne li ZooKeeper û ne jî li Consul bi bandor nayên nimûne kirin. Hewl didin ku em ji hemî karûbaran çêtirîn tevbigerin, me bi navgînek hema hema bi navbeynkariya ZooKeeper re digel îstîsnayên girîng ên jêrîn bi dawî bû:

  • rêzik, konteynir û girêkên TTL nayê piştgirî kirin
  • ACL nayên piştgirî kirin
  • rêbaza set heke ew tune be mifteyek diafirîne (di ZK de setData di vê rewşê de xeletiyek vedigerîne)
  • Rêbazên set û cas têne veqetandin (di ZK de ew di bingeh de heman tişt in)
  • rêbaza jêbirinê girêkekê ligel binerxeya wê jê dike (di ZK de delete xeletiyek vedigerîne ger girêk zarok hebin)
  • Ji bo her mifteyê tenê guhertoyek heye - guhertoya nirxê (di ZK sê ji wan hene)

Nepejirandina girêkên rêzdar ji ber vê yekê ye ku etcd û Konsul ji wan re piştgiriyek çêkirî tune ye, û ew dikarin bi hêsanî ji hêla bikarhêner ve li ser navbeynkariya pirtûkxaneyê ya encam de bêne bicîh kirin.

Pêkanîna tevgerê mîna ZooKeeper dema jêbirina verteksê pêdivî ye ku ji bo her keyek di etcd û konsulê de jimareyek zarokek cûda were domandin. Ji ber ku me hewl da ku ji hilanîna agahdariya meta dûr bixin, biryar hate girtin ku tevahiya binê darê jê bibe.

Zehfên pêkanîna

Werin em ji nêz ve li hin aliyên pêkanîna pêwendiya pirtûkxaneyê di pergalên cihêreng de binihêrin.

Hiyerarşî di etcd

Di etcd de parastina nêrînek hiyerarşîk yek ji karên herî balkêş derket holê. Pirsên rêzê hilanîna navnîşek mifteyên bi pêşgirek diyarkirî hêsan dike. Mînakî, heke hûn hewceyê her tiştê ku bi dest pê dike hewce bike "/foo", hûn rêzek dipirsin ["/foo", "/fop"). Lê ev ê tevahiya binê dara kilîtê vegerîne, ku heke bine dara mezin be dibe ku neyê pejirandin. Di destpêkê de me plan kir ku mekanîzmayek wergera sereke bikar bînin, di zetcd de pêk anîn. Ew di destpêka mifteyê de yek byte lê zêde dike, bi qasî kûrahiya girêka di darê de. Ez ji we re mînakek bidim.

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

Dûv re hemî zarokên yekser ji mifteyê bistînin "/foo" mimkun e bi daxwaza range ["u02/foo/", "u02/foo0"). Erê, di ASCII de "0" rast piştî radiweste "/".

Lê meriv çawa di vê rewşê de rakirina verteksê pêk tîne? Derket holê ku hûn hewce ne ku hemî rêzikên celebê jêbirin ["uXX/foo/", "uXX/foo0") ji bo XX ji 01 heta FF. Û paşê em ketin nav sînorê hejmara operasyonê di nav yek danûstandinê de.

Wekî encamek, pergalek guheztina mifteyê ya hêsan hate îcad kirin, ku ev gengaz kir ku hem jêbirina mifteyek û hem jî girtina navnîşek zarokan bi bandor were bicîh kirin. Bes e ku meriv berî nîşana paşîn karakterek taybetî lê zêde bike. Bo nimûne:

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

Paşê jêbirina mifteyê "/very" vediguhere jêbirinê "/u00very" û range ["/very/", "/very0"), û wergirtina hemî zarokan - di daxwazek bişkojkên ji rêzê de ["/very/u00", "/very/u01").

Rakirina mifteyek li ZooKeeper

Wekî ku min berê jî behs kir, di ZooKeeper de hûn nekarin girêkek ku zarokên wê hebin jêbirin. Em dixwazin mifteyê ligel binerdê jêbirin. Derewînê bedew û biçûk? Em vê yekê bi geşbînî dikin. Pêşî, em bi paşverû li binê darê digerînin, zarokên her verteksê bi pirsek cihêreng digirin. Dûv re em danûstendinek çêdikin ku hewl dide ku hemî girêkên binerdê bi rêza rast jê bibe. Bê guman, guhertin dikarin di navbera xwendina jêrdarek û jêbirina wê de çêbibin. Di vê rewşê de, danûstandin dê têk bibin. Digel vê yekê, dibe ku binê darê di pêvajoya xwendinê de biguhezîne. Daxwazek ji bo zarokên girêka din dibe ku xeletiyek vegere heke, mînakî, ev girêk berê hatibe jêbirin. Di her du rewşan de, em tevahiya pêvajoyê dîsa dubare dikin.

Ev nêzîkatî jêbirina miftekê pir bêbandor dike ger zarokên wê hebin, û hêj bêtir heke serîlêdan bi binerxetê re bixebite, jêbirin û çêkirina mifteyan berdewam bike. Lêbelê, vê yekê hişt ku em ji tevlihevkirina pêkanîna rêbazên din ên li etcd û konsulê dûr bisekinin.

li ZooKeeper hatî danîn

Di ZooKeeper de rêbazên cuda hene ku bi strukturên darê re dixebitin (çêkirin, jêbirin, getChildren) û ku bi daneyan di girêkan de dixebitin (setData, getData). Wekî din, hemî rêbaz şertên hişk hene: çêbike dê xeletiyek vegere heke girêk berê hebe. hate afirandin, jêbirin an danasînData - heke ew jixwe tune be. Pêdiviya me bi rêbazek sazkirî hebû ku bêyî ku li ser hebûna mifteyê bifikire were gazî kirin.

Vebijarkek ev e ku meriv nêzîkatiyek xweşbîn e, mîna jêbirinê. Kontrol bikin ka nodek heye. Ger hebe, bangî setData bikin, wekî din biafirînin. Ger rêbaza paşîn xeletiyek vegerand, wê ji nû ve dubare bike. Ya yekem ku divê were zanîn ev e ku ceribandina hebûnê bêwate ye. Hûn dikarin tavilê banga afirandinê bikin. Temamkirina serketî tê wê wateyê ku girêk tunebû û ew hate afirandin. Wekî din, çêbikin dê xeletiya guncan vegere, piştî ku hûn hewce ne ku bangî setData bikin. Bê guman, di navbera bangan de, vertexek dikare ji hêla bangek hevrikî ve were jêbirin, û setData jî dê xeletiyek vegere. Di vê rewşê de, hûn dikarin her tiştî ji nû ve bikin, lê ew hêja ye?

Ger her du rêbaz xeletiyek vegerînin, wê hingê em bi guman dizanin ku jêbirinek hevrikî pêk hat. Ka em bifikirin ku ev jêbirin piştî banga set pêk hat. Wê demê çi wateya ku em hewl didin ava bikin, jixwe ji holê tê rakirin. Ev tê vê wateyê ku em dikarin texmîn bikin ku set bi serfirazî hate darve kirin, her çend di rastiyê de tiştek nehatibe nivîsandin.

Zêdetir hûrguliyên teknîkî

Di vê beşê de em ê ji pergalên belavkirî veqetînin û li ser kodkirinê biaxivin.
Yek ji daxwazên sereke yên xerîdar cross-platform bû: Bi kêmanî yek ji karûbaran divê li Linux, MacOS û Windows-ê were piştgirî kirin. Di destpêkê de, me tenê ji bo Linux-ê pêşve xist, û paşê dest bi ceribandina pergalên din kir. Ev bû sedema gelek pirsgirêkan, ku ji bo demekê bi tevahî ne diyar bû ka meriv çawa nêzîk dibe. Wekî encamek, her sê karûbarên hevrêziyê naha li ser Linux û MacOS têne piştgirî kirin, dema ku tenê Consul KV li ser Windows-ê tê piştgirî kirin.

Ji destpêkê ve, me hewl da ku ji bo gihîştina karûbaran pirtûkxaneyên amade bikar bînin. Di doza ZooKeeper de, bijarte li ser ket ZooKeeper C++, ku di dawiyê de li ser Windows-ê berhev nekir. Lêbelê, ev ne ecêb e: pirtûkxane wekî linux-tenê cih digire. Ji bo Konsul tenê vebijêrk bû ppconsul. Diviyabû piştgirî lê zêde biba danişînan и muamele. Ji bo etcd, pirtûkxaneyek bêkêmasî ya ku guhertoya herî dawî ya protokolê piştgirî dike nehat dîtin, ji ber vê yekê em bi hêsanî muwekîlê grpc hatî çêkirin.

Bi îlhama pêwendiya asynkron a pirtûkxaneya ZooKeeper C++, me biryar da ku em navbeynek asynkron jî bicîh bikin. ZooKeeper C++ ji bo vê yekê pêşerojên pêşeroj / soz bikar tîne. Di STL de, mixabin, ew pir bi nermî têne bicîh kirin. Mînak, na paşê rêbaz, ya ku fonksiyona derbasbûyî li ser encama pêşerojê dema ku ew peyda dibe bicîh tîne. Di rewşa me de, rêbazek weha hewce ye ku encamê veguherîne forma pirtûkxaneya me. Ji bo ku em li dora vê pirsgirêkê derbikevin, me neçar ma ku hewza xweya xweya hêsan bicîh bikin, ji ber ku li ser daxwaza xerîdar me nekarî pirtûkxaneyên sêyemîn ên giran ên wekî Boost bikar bînin.

Pêkanîna me ya wê demê bi vî rengî dixebite. Dema ku tê gotin, cotek soz / pêşeroj tê afirandin. Pêşeroja nû tê vegerandin, û ya derbasbûyî digel fonksiyona têkildar û sozek zêde di rêzê de tê danîn. Mijarek ji hewzê çend dahatûyan ji rêzê hildibijêre û wan bi karanîna wait_for anket dike. Dema ku encamek peyda dibe, fonksiyona têkildar tê gazî kirin û nirxa vegera wê ji sozê re derbas dibe.

Me heman hewza têlê bikar anî da ku pirsan ji etcd û konsul re bicîh bîne. Ev tê vê wateyê ku pirtûkxaneyên bingehîn ji hêla gelek mijarên cûda ve têne gihîştin. ppconsul ne ewledar e, ji ber vê yekê bangên wê ji hêla qefleyan ve têne parastin.
Hûn dikarin bi grpc-ê ji gelek mijaran re bixebitin, lê hûrgulî hene. Di etcd de demjimêr bi rêyên grpc têne bicîh kirin. Ev kanalên dualî ne ji bo peyamên cûreyek diyarkirî. Pirtûkxane ji bo hemî temaşeyan yek mijarek diafirîne û mijarek yekane ku peyamên hatinî pêvajoyê dike. Ji ber vê yekê grpc nivîsandina paralel ji bo stream qedexe dike. Ev tê wê wateyê ku dema destpêkirina an jêbirina demjimêrek, divê hûn li bendê bimînin heya ku daxwaza berê şandina xwe temam bike berî ku ya din bişîne. Em ji bo hevdemkirinê bikar tînin guherbarên şertî.

Encam

Ji xwe re bibînin: liboffkv.

Tîma me: Raed Romanov, Ivan Glushenkov, Dmitry Kamaldinov, Victor Krapivensky, Vitaly Ivanin.

Source: www.habr.com

Add a comment