Dosbarthodd pum myfyriwr a thri siop gwerth allweddol

Neu sut y gwnaethom ysgrifennu llyfrgell cleient C++ ar gyfer ZooKeeper, ac ati a Consul KV

Ym myd systemau gwasgaredig, mae yna nifer o dasgau nodweddiadol: storio gwybodaeth am gyfansoddiad y clwstwr, rheoli cyfluniad nodau, canfod nodau diffygiol, dewis arweinydd. ac eraill. Er mwyn datrys y problemau hyn, mae systemau dosbarthedig arbennig wedi'u creu - gwasanaethau cydlynu. Nawr bydd gennym ddiddordeb mewn tri ohonynt: ZooKeeper, etcd a Conswl. O holl ymarferoldeb cyfoethog Conswl, byddwn yn canolbwyntio ar Conswl KV.

Dosbarthodd pum myfyriwr a thri siop gwerth allweddol

Yn y bôn, mae'r systemau hyn i gyd yn storfeydd gwerth allweddol llinol sy'n gallu goddef diffygion. Er bod gan eu modelau data wahaniaethau sylweddol, y byddwn yn eu trafod yn ddiweddarach, maent yn datrys yr un problemau ymarferol. Yn amlwg, mae pob cais sy'n defnyddio'r gwasanaeth cydlynu yn gysylltiedig ag un ohonynt, a allai arwain at yr angen i gefnogi sawl system mewn un ganolfan ddata sy'n datrys yr un problemau ar gyfer gwahanol gymwysiadau.

Deilliodd y syniad i ddatrys y broblem hon mewn asiantaeth ymgynghori yn Awstralia, a mater i ni, tîm bach o fyfyrwyr, oedd ei weithredu, a dyna beth rydw i'n mynd i siarad amdano.

Llwyddom i greu llyfrgell sy'n darparu rhyngwyneb cyffredin ar gyfer gweithio gyda ZooKeeper, etcd a Consul KV. Mae'r llyfrgell wedi'i hysgrifennu yn C++, ond mae cynlluniau i'w throsglwyddo i ieithoedd eraill.

Modelau Data

I ddatblygu rhyngwyneb cyffredin ar gyfer tair system wahanol, mae angen i chi ddeall beth sydd ganddynt yn gyffredin a sut maent yn wahanol. Gadewch i ni chyfrif i maes.

SwCeidwad

Dosbarthodd pum myfyriwr a thri siop gwerth allweddol

Mae'r allweddi wedi'u trefnu'n goeden ac fe'u gelwir yn nodau. Yn unol â hynny, ar gyfer nod gallwch gael rhestr o'i blant. Mae gweithrediadau creu znode (creu) a newid gwerth (setData) wedi'u gwahanu: dim ond allweddi presennol y gellir eu darllen a'u newid. Gellir cysylltu oriawr i'r gweithrediadau o wirio bodolaeth nod, darllen gwerth, a chael plant. Mae gwylio yn sbardun un-amser sy'n tanio pan fydd y fersiwn o'r data cyfatebol ar y gweinydd yn newid. Defnyddir nodau byrhoedlog i ganfod methiannau. Maent yn gysylltiedig â sesiwn y cleient a'u creodd. Pan fydd cleient yn cau sesiwn neu'n peidio â hysbysu ZooKeeper o'i fodolaeth, mae'r nodau hyn yn cael eu dileu'n awtomatig. Cefnogir trafodion syml - set o weithrediadau sydd naill ai i gyd yn llwyddo neu'n methu os nad yw hyn yn bosibl ar gyfer o leiaf un ohonynt.

etcd

Dosbarthodd pum myfyriwr a thri siop gwerth allweddol

Roedd datblygwyr y system hon yn amlwg wedi'u hysbrydoli gan ZooKeeper, ac felly gwnaethant bopeth yn wahanol. Nid oes hierarchaeth o allweddi, ond maent yn ffurfio set a drefnwyd yn eiriadurol. Gallwch gael neu ddileu pob allwedd sy'n perthyn i ystod benodol. Gall y strwythur hwn ymddangos yn rhyfedd, ond mewn gwirionedd mae'n fynegiannol iawn, a gellir efelychu safbwynt hierarchaidd yn hawdd drwyddo.

ac ati nid oes gan weithrediad cymharu-a-set safonol, ond mae ganddo rywbeth gwell: trafodion. Wrth gwrs, maent yn bodoli ym mhob un o'r tair system, ond mae trafodion ac ati yn arbennig o dda. Maent yn cynnwys tri bloc: gwirio, llwyddiant, methiant. Mae'r bloc cyntaf yn cynnwys set o amodau, yr ail a'r trydydd - gweithrediadau. Mae'r trafodiad yn cael ei weithredu'n atomig. Os yw'r holl amodau'n wir, yna gweithredir y bloc llwyddiant, fel arall gweithredir y bloc methiant. Yn API 3.3, gall blociau llwyddiant a methiant gynnwys trafodion nythu. Hynny yw, mae'n bosibl gweithredu lluniadau amodol o lefel nythu bron yn fympwyol yn atomig. Gallwch ddysgu mwy am ba wiriadau a gweithrediadau sy'n bodoli dogfennaeth.

Mae oriawr yn bodoli yma hefyd, er eu bod ychydig yn fwy cymhleth a gellir eu hailddefnyddio. Hynny yw, ar ôl gosod oriawr ar ystod allweddol, byddwch yn derbyn yr holl ddiweddariadau yn yr ystod hon nes i chi ganslo'r oriawr, ac nid yr un cyntaf yn unig. Mewn ac ati, prydlesi yw analog sesiynau cleient ZooKeeper.

Conswl K.V.

Nid oes strwythur hierarchaidd llym yma ychwaith, ond gall Conswl greu'r ymddangosiad ei fod yn bodoli: gallwch gael a dileu'r holl allweddi gyda'r rhagddodiad penodedig, hynny yw, gweithio gydag “is-goeden” yr allwedd. Gelwir ymholiadau o'r fath yn ailadroddus. Yn ogystal, gall Conswl ddewis dim ond allweddi nad ydynt yn cynnwys y nod penodedig ar ôl y rhagddodiad, sy'n cyfateb i gael "plant" ar unwaith. Ond mae'n werth cofio mai dyma'n union ymddangosiad strwythur hierarchaidd: mae'n eithaf posibl creu allwedd os nad yw ei riant yn bodoli neu ddileu allwedd sydd â phlant, tra bydd y plant yn parhau i gael eu storio yn y system.

Dosbarthodd pum myfyriwr a thri siop gwerth allweddol
Yn lle gwylio, mae Conswl wedi rhwystro ceisiadau HTTP. Yn y bôn, mae'r rhain yn alwadau cyffredin i'r dull darllen data, y mae'r fersiwn hysbys olaf o'r data wedi'i nodi ar eu cyfer, ynghyd â pharamedrau eraill. Os yw'r fersiwn gyfredol o'r data cyfatebol ar y gweinydd yn fwy na'r un penodedig, dychwelir yr ymateb ar unwaith, fel arall - pan fydd y gwerth yn newid. Mae yna hefyd sesiynau y gellir eu cysylltu ag allweddi unrhyw bryd. Mae'n werth nodi, yn wahanol i etcd a ZooKeeper, lle mae dileu sesiynau yn arwain at ddileu allweddi cysylltiedig, mae yna fodd y mae'r sesiwn yn syml wedi'i datgysylltu oddi wrthynt. Ar gael trafodion, heb ganghennau, ond gyda phob math o wiriadau.

Rhoi'r cyfan at ei gilydd

Mae gan ZooKeeper y model data mwyaf trwyadl. Ni ellir efelychu'r ymholiadau amrediad mynegiannol sydd ar gael mewn ac ati yn effeithiol naill ai yn ZooKeeper neu Consul. Gan geisio ymgorffori'r gorau o'r holl wasanaethau, cawsom ryngwyneb bron yn cyfateb i'r rhyngwyneb ZooKeeper gyda'r eithriadau sylweddol canlynol:

  • dilyniant, cynhwysydd a nodau TTL heb ei gefnogi
  • Ni chefnogir ACLs
  • mae'r dull gosod yn creu allwedd os nad yw'n bodoli (yn ZK mae setData yn dychwelyd gwall yn yr achos hwn)
  • mae dulliau set a cas yn cael eu gwahanu (yn ZK maent yn ei hanfod yr un peth)
  • mae'r dull dileu yn dileu nod ynghyd â'i is-goeden (yn ZK mae dileu yn dychwelyd gwall os oes gan y nod blant)
  • Ar gyfer pob allwedd dim ond un fersiwn sydd - y fersiwn gwerth (yn ZK mae yna dri ohonyn nhw)

Mae gwrthod nodau dilyniannol oherwydd y ffaith nad oes gan etcd a Consul gefnogaeth adeiledig ar eu cyfer, a gall y defnyddiwr eu gweithredu'n hawdd ar ben y rhyngwyneb llyfrgell sy'n deillio o hynny.

Byddai gweithredu ymddygiad tebyg i ZooKeeper wrth ddileu fertig yn gofyn am gadw rhifydd plentyn ar wahân ar gyfer pob allwedd yn ac ati a Conswl. Ers i ni geisio osgoi storio gwybodaeth feta, penderfynwyd dileu'r is-goeden gyfan.

Cynnil y gweithredu

Gadewch i ni edrych yn agosach ar rai agweddau ar weithredu rhyngwyneb y llyfrgell mewn systemau gwahanol.

Hierarchaeth mewn etcd

Roedd cynnal golwg hierarchaidd mewn ac ati yn un o'r tasgau mwyaf diddorol. Mae ymholiadau ystod yn ei gwneud hi'n hawdd adalw rhestr o allweddi gyda rhagddodiad penodedig. Er enghraifft, os oes angen popeth sy'n dechrau "/foo", rydych chi'n gofyn am ystod ["/foo", "/fop"). Ond byddai hyn yn dychwelyd yr is-goeden gyfan o'r allwedd, a allai fod yn annerbyniol os yw'r is-goeden yn fawr. I ddechrau, roeddem yn bwriadu defnyddio mecanwaith cyfieithu allweddol, gweithredu yn zetcd. Mae'n golygu ychwanegu un beit ar ddechrau'r allwedd, sy'n hafal i ddyfnder y nod yn y goeden. Gadewch imi roi enghraifft ichi.

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

Yna cael pob plentyn ar unwaith o'r allwedd "/foo" bosibl trwy ofyn am ystod ["u02/foo/", "u02/foo0"). Ie, yn ASCII "0" yn sefyll yn union ar ôl "/".

Ond sut i weithredu tynnu fertig yn yr achos hwn? Mae'n troi allan bod angen i chi ddileu pob ystod o'r math ["uXX/foo/", "uXX/foo0") am XX o 01 i FF. Ac yna rydym yn rhedeg i mewn terfyn nifer gweithrediad o fewn un trafodiad.

O ganlyniad, dyfeisiwyd system trosi allwedd syml, a oedd yn ei gwneud hi'n bosibl gweithredu dileu allwedd a chael rhestr o blant yn effeithiol. Mae'n ddigon i ychwanegu cymeriad arbennig cyn y tocyn olaf. Er enghraifft:

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

Yna dileu'r allwedd "/very" yn troi yn ddileu "/u00very" ac ystod ["/very/", "/very0"), a chael pob plentyn - mewn cais am allweddi o'r ystod ["/very/u00", "/very/u01").

Tynnu allwedd yn ZooKeeper

Fel y soniais eisoes, yn ZooKeeper ni allwch ddileu nod os oes ganddo blant. Rydym am ddileu'r allwedd ynghyd â'r is-goeden. Beth ddylwn i ei wneud? Gwnawn hyn gydag optimistiaeth. Yn gyntaf, rydym yn croesi'r is-goeden dro ar ôl tro, gan gael plant pob fertig ag ymholiad ar wahân. Yna rydym yn adeiladu trafodiad sy'n ceisio dileu holl nodau'r is-goeden yn y drefn gywir. Wrth gwrs, gall newidiadau ddigwydd rhwng darllen is-goeden a'i dileu. Yn yr achos hwn, bydd y trafodiad yn methu. Ar ben hynny, gall yr is-goeden newid yn ystod y broses ddarllen. Gall cais ar gyfer plant y nod nesaf ddychwelyd gwall os, er enghraifft, mae'r nod hwn eisoes wedi'i ddileu. Yn y ddau achos, rydym yn ailadrodd y broses gyfan eto.

Mae'r dull hwn yn gwneud dileu allwedd yn aneffeithiol iawn os oes ganddo blant, a hyd yn oed yn fwy felly os yw'r cais yn parhau i weithio gyda'r is-goeden, gan ddileu a chreu allweddi. Fodd bynnag, roedd hyn yn ein galluogi i osgoi cymhlethu'r broses o roi dulliau eraill ar waith ym meysydd etcd a Consul.

gosod yn ZooKeeper

Yn ZooKeeper mae yna ddulliau ar wahân sy'n gweithio gyda strwythur y goeden (creu, dileu, getChildren) ac sy'n gweithio gyda data mewn nodau (setData, getData). Ar ben hynny, mae gan bob dull ragamodau llym: creu bydd yn dychwelyd gwall os yw'r nod eisoes wedi wedi'i greu, dileu neu setData - os nad yw'n bodoli eisoes. Roedd angen dull gosodedig y gellir ei alw heb feddwl am bresenoldeb allwedd.

Un opsiwn yw cymryd agwedd optimistaidd, fel gyda dileu. Gwiriwch a oes nod yn bodoli. Os yw'n bodoli, ffoniwch setData, fel arall crëwch. Os dychwelodd y dull olaf wall, ailadroddwch y cyfan eto. Y peth cyntaf i'w nodi yw bod y prawf bodolaeth yn ddibwrpas. Gallwch chi ffonio creu ar unwaith. Bydd cwblhau'n llwyddiannus yn golygu nad oedd y nod yn bodoli ac fe'i crëwyd. Fel arall, bydd creu yn dychwelyd y gwall priodol, ac ar ôl hynny mae angen i chi ffonio setData. Wrth gwrs, rhwng galwadau, gallai fertig gael ei ddileu gan alwad sy'n cystadlu, a byddai setData hefyd yn dychwelyd gwall. Yn yr achos hwn, gallwch chi ei wneud eto, ond a yw'n werth chweil?

Os bydd y ddau ddull yn dychwelyd gwall, yna fe wyddom yn sicr bod dilead cystadleuol wedi digwydd. Gadewch i ni ddychmygu bod y dileu hwn wedi digwydd ar ôl galw set. Yna mae pa bynnag ystyr yr ydym yn ceisio ei sefydlu eisoes wedi'i ddileu. Mae hyn yn golygu y gallwn gymryd yn ganiataol bod y set wedi'i gweithredu'n llwyddiannus, hyd yn oed os na chafodd unrhyw beth ei ysgrifennu mewn gwirionedd.

Mwy o fanylion technegol

Yn yr adran hon byddwn yn cymryd seibiant o systemau gwasgaredig ac yn siarad am godio.
Un o brif ofynion y cwsmer oedd traws-lwyfan: rhaid cefnogi o leiaf un o'r gwasanaethau ar Linux, MacOS a Windows. I ddechrau, fe wnaethom ddatblygu ar gyfer Linux yn unig, a dechrau profi ar systemau eraill yn ddiweddarach. Achosodd hyn lawer o broblemau, a oedd am beth amser yn gwbl aneglur sut i fynd ati. O ganlyniad, mae'r tri gwasanaeth cydlynu bellach yn cael eu cefnogi ar Linux a MacOS, tra mai dim ond Consul KV sy'n cael ei gefnogi ar Windows.

O'r cychwyn cyntaf, fe wnaethom geisio defnyddio llyfrgelloedd parod i gael mynediad at wasanaethau. Yn achos ZooKeeper, disgynnodd y dewis Sŵ-geidwad C++, a fethodd yn y pen draw â llunio ar Windows. Nid yw hyn, fodd bynnag, yn syndod: mae'r llyfrgell wedi'i lleoli fel linux yn unig. Ar gyfer Conswl yr unig opsiwn oedd ppconswl. Roedd yn rhaid ychwanegu cefnogaeth ato sesiynau и trafodion. Ar gyfer ac ati, ni ddaethpwyd o hyd i lyfrgell lawn yn cefnogi'r fersiwn ddiweddaraf o'r protocol, felly yn syml iawn cleient grpc a gynhyrchir.

Wedi'n hysbrydoli gan ryngwyneb asyncronig llyfrgell ZooKeeper C ++, penderfynasom hefyd weithredu rhyngwyneb asyncronig. Yn ZooKeeper C++, defnyddir cyntefigau dyfodol/addewid ar gyfer hyn. Yn STL, yn anffodus, maent yn cael eu gweithredu'n gymedrol iawn. Er enghraifft, na yna dull, sy'n cymhwyso'r swyddogaeth a basiwyd i ganlyniad y dyfodol pan fydd ar gael. Yn ein hachos ni, mae angen dull o'r fath i drosi'r canlyniad yn fformat ein llyfrgell. I fynd o gwmpas y broblem hon, roedd yn rhaid i ni weithredu ein cronfa edau syml ein hunain, oherwydd ar gais y cwsmer ni allem ddefnyddio llyfrgelloedd trydydd parti trwm fel Boost.

Mae ein gweithrediad bryd hynny yn gweithio fel hyn. Pan gaiff ei alw, crëir addewid ychwanegol / pâr dyfodol. Dychwelir y dyfodol newydd, a gosodir yr un a basiwyd ynghyd â'r swyddogaeth gyfatebol ac addewid ychwanegol yn y ciw. Mae edefyn o'r pwll yn dewis sawl dyfodol o'r ciw ac yn eu pleidleisio gan ddefnyddio wait_for. Pan ddaw canlyniad ar gael, gelwir y swyddogaeth gyfatebol a chaiff ei werth dychwelyd ei drosglwyddo i'r addewid.

Fe wnaethom ddefnyddio'r un gronfa edau i weithredu ymholiadau i etcd a Conswl. Mae hyn yn golygu y gellir cyrchu'r llyfrgelloedd sylfaenol trwy sawl trywydd gwahanol. Nid yw ppconsul yn edau ddiogel, felly mae galwadau iddo yn cael eu diogelu gan gloeon.
Gallwch weithio gyda grpc o edafedd lluosog, ond mae yna gynildeb. Mewn oriawr ac ati yn cael eu gweithredu trwy ffrydiau grpc. Mae'r rhain yn sianeli deugyfeiriadol ar gyfer negeseuon o fath penodol. Mae'r llyfrgell yn creu un edefyn ar gyfer pob oriawr ac un edefyn sy'n prosesu negeseuon sy'n dod i mewn. Felly mae grpc yn gwahardd ysgrifennu cyfochrog i ffrwd. Mae hyn yn golygu, wrth gychwyn neu ddileu oriawr, bod yn rhaid i chi aros nes bod y cais blaenorol wedi'i gwblhau cyn anfon yr un nesaf. Rydym yn defnyddio ar gyfer cydamseru newidynnau amodol.

Cyfanswm

Gweler drosoch eich hun: liboffkv.

Ein tîm: Raed Romanov, Ivan Glushenkov, Dmitry Kamaldinov, Victor Krapivensky, Vitaly Ivanin.

Ffynhonnell: hab.com

Ychwanegu sylw