K: Üks teenuseserver, üks andmebaas, operatsioon: pärida kasutaja praegune saldo, lahutada 3% praegusest saldost käsitlemistasuna
sünkroniseeritud lukk DB lukk
K: Kaks teenusserverit, üks andmebaas, toiming: pärida kasutaja praegune saldo, lahutada 3% praegusest saldost käsitlemistasuna Jaotatud lukud
Millist hajutatud lukku meil vaja on? See võimaldab tagada, et hajutatud rakenduste klastris saab sama meetodit korraga käivitada ainult ühe lõime kaudu ühel masinal.
Kui see lukk on reentrant-lukk (väldi ummiklukke)
See lukk on parim blokeeriv lukk (mõtle, kas soovid seda vastavalt oma ettevõtte vajadustele).
See lukk on parim aus lukk (mõtle, kas soovid seda või mitte, vastavalt ärivajadustele).
On olemas väga kättesaadavad lukustus- ja avamisfunktsioonid
Omandamis- ja vabastamislukkude jõudlus on parem
1. Jaotatud lukud andmebaaside põhjal
Tabelipõhiste rakenduste põhjal jaotatud lukud
Kui soovime meetodit lukustada, käivitame järgmise SQL: sisesta methodLock(method_name,desc) väärtused ('method_name','desc')
Kuna oleme kehtestanud method_name unikaalsuspiirangu, siis kui andmebaasi esitatakse korraga mitu päringut, tagab andmebaas, et õnnestub ainult üks operatsioon, siis võime eeldada, et lõim, mis edukalt meetodi sai, lukustub ja suudab käivitada meetodi keha sisu.
Kui meetod on käivitatud, kui soovid lukku vabastada, pead käivitama järgmise SQL-i: kustuta methodLockist, kus method_name ='method_name'
Sellel lihtsal rakendusel on järgmised probleemid:
- See lukk sõltub andmebaasi kättesaadavusest, mis on üks punkt ja põhjustab ärisüsteemi kättesaadavuse, kui andmebaas on kinni pandud.
- Sellel lukustusel puudub aegumisaeg ning kui avamistoiming ebaõnnestub, jääb lukustuskirje andmebaasi ning teised lõimed ei saa enam lukku kätte.
- See lukk saab olla ainult mitteblokeeriv, sest andmete sisestamise operatsioon teatab veast otse, kui sisestus ebaõnnestub. Lõimed, mis lukke ei omanda, ei sisene järjekorda ning peavad luku omandamise operatsiooni uuesti käivitama, et lukk uuesti kätte saada.
- Lukk ei ole reentrant ning sama niit ei saa lukku uuesti kätte enne, kui see vabastatakse. Sest andmed andmetes juba eksisteerivad.
- See lukk on ebaõiglane lukk ja kõik luku ootavad niidid võistlevad selle pärast õnne tõttu.
Loomulikult saame ülaltoodud probleeme lahendada ka muul viisil.
- Kas andmebaas on üks punkt? Ehita kaks andmebaasi ja andmed sünkroniseeritakse mõlemas suunas. Kui kõne on lõpetatud, lülitu kiiresti varukoopiateeki.
- Aegumistähtaega pole? Tee lihtsalt ajastatud ülesanne, et puhastada andmebaasis ajapiirangu andmed regulaarsete intervallidega.
- Blokeerimata? Tee aeg-tsükkel, kuni sisestus õnnestub, ja siis tagastab edu.
- Mitte uuesti sisse astunud? Lisa andmebaasi tabelisse väli, et salvestada masina hostinfo ja lõimeinfo, mis hetkel lukustust saab, ning järgmisel korral, kui luku saad, küsi esmalt andmebaasist; kui praeguse masina hostinfo ja lõime info on andmebaasist leitud, saad luku otse talle määrata.
- Ebaõiglane? Loo teine vahepealne tabel, kuhu salvestatakse kõik luku ootavad lõimed ja sorteerida need vastavalt loomise ajale, ning ainult esimene loodud lõime saab luku kätte
Levitatud lukud, mis põhinevad eksklusiivsetel lukkudel
Lisaks andmetabeli kirjete lisamisele ja kustutamisele saab rakendada hajutatud lukke ka andmetega kaasas olevate lukude abil.
Kasutame ka äsja loodud andmebaasitabelit. Hajutatud lukustusi saab rakendada eksklusiivsete andmebaaside lukustustega. MySQL-põhine InnoDB mootor saab kasutada järgmisi meetodeid lukustusoperatsioonide rakendamiseks:
Kui lisad uuenduseks pärast päringulauset, lisab andmebaas eksklusiivse luku andmebaasi tabelisse päringuprotsessi käigus. Kui kirjele lisatakse eksklusiivne lukk, ei saa teised lõimed enam lisada eksklusiivset lukku sellel real.
Võime mõelda, et lõim, mis saab eksklusiivse luku, võib saada hajutatud luku ning kui lukk on saadud, saab meetodi äriloogika käivitada ja seejärel avada järgmiste meetodite kaudu:
public void unlock(){ connection.commit(); }
via connection.commit(); Operatsioon luku vabastamiseks.
See meetod suudab tõhusalt lahendada ülalmainitud probleemid, mis puudutavad lukku vabastamise ja blokeerimise võimetuse kohta.
Lukkude blokeerimine? For update lause naaseb kohe pärast edukat täitmist ja jääb blokeerituks kuni õnnestumiseni.
Teenindus on pärast lukustust maas, ei saa vabastada? Nii vabastab andmebaas luku iseseisvalt pärast teenuse katkemist.
Siiski ei lahenda see otseselt andmebaasi ühe punkti, reentsentsuse ja ausa lukustamise probleemi.
Kokkuvõtteks, kuidas kasutada andmebaasi jaotatud lukkude rakendamiseks, mis mõlemad tuginevad andmebaasi tabelile: üks on tuvastada lukustus kirjete olemasolu põhjal ja teine on jaotatud lukustuste rakendamine andmebaasi eksklusiivse luku kaudu.
Hajutatud lukustamise eelised andmebaasides
Otse andmebaasi abil on seda lihtne mõista.
Hajutatud lukkude rakendamise puudused andmebaasides
Tekib erinevaid probleeme ning kogu lahendus muutub probleemi lahendamise protsessis järjest keerukamaks.
Andmebaasi haldamine nõuab teatud üldkulusid ning tuleb arvestada jõudlusprobleemidega.
2. Hajutatud lukud vahemälu põhjal
Võrreldes andmebaasipõhise hajutatud lukustuslahendusega toimib vahemälupõhine rakendus jõudluse poolest paremini.
Praegu on palju küpseid vahemälutooteid, sealhulgas Redis, memcached jne. Siin võtame Redise näiteks, et analüüsida vahemälu skeemi hajutatud lukustuste rakendamiseks.
Internetis on palju seotud artikleid hajutatud lukkude rakendamisest Redis-põhiste süsteemide kohta ning peamine rakendusmeetod on kasutada Jedis.setNX meetodit.
Ülaltoodud rakendusega on ka mitmeid probleeme:
1. Ühe punkti probleem.
2. Sellel lukustusel puudub aegumisaeg, kui avamistoiming ebaõnnestub, jääb lukustuskirje pidevalt redis ja teised lõimed ei saa enam lukku kätte.
3. See lukk võib olla ainult mitteblokeeriv ja naaseb otse sõltumata edu või ebaõnnestumisest.
4. See lukk on mitte-reentrant-, pärast seda, kui lõim on luku saanud, ei saa ta lukku enne luku vabastamist uuesti kätte, sest kasutatud võti on juba redis'is olemas. setNX operatsioone ei saa enam täita.
5. See lukk on ebaõiglane, kõik ootelõimed alustavad setNX operatsioone samaaegselt ja õnnelikud lõimed saavad luku.
Loomulikult on ka lahendusi.
- Tänapäeval toetavad peavoolu vahemäluteenused klastrite juurutamist, et lahendada ühe punkti probleeme klasterdamise kaudu.
- Aegumistähtaega pole? Redis setExpire meetod toetab saabuvat aegumisaega ning andmed kustutatakse automaatselt pärast selle aja täitumist.
- Blokeerimata? samal ajal korduvalt hukatud.
- Kas pole võimalik uuesti siseneda? Pärast seda, kui lõim on luku saanud, salvesta praegune hosti info ja lõime info ning kontrolli, kas oled praeguse luku omanik, enne kui selle järgmine kord saad.
- Ebaõiglane? Pane kõik ootel olevad lõimed järjekorda enne, kui lõim saab luku, ja seejärel hangi lukk esimesena sisse, esimesena välja.
Redis-klastri sünkroniseerimispoliitika võtab aega ning on võimalik, et lõim A saab lukku pärast NX edukat seadistamist, kuid seda väärtust pole uuendatud serverisse, kus lõim B käivitab setNX, mis põhjustab paralleelsuse probleeme.
Redis'i autor Salvatore Sanfilippo pakkus välja Redlocki algoritmi, mis rakendab hajutatud lukuhaldust (DLM), mis on turvalisem ja usaldusväärsem kui üksik sõlm.
Redlocki algoritm eeldab, et on N Redis sõlme, mis on üksteisest sõltumatud, tavaliselt seatud N=5-le, ning need N sõlme töötavad erinevatel masinatel, et säilitada füüsiline sõltumatus.
Algoritmi sammud on järgmised:
1. Klient saab praeguse aja millisekundites. 2. Klient püüab saada N sõlme luku (iga sõlm saab luku samamoodi nagu eelnevalt mainitud vahemälulukk), ja N sõlme saavad luku sama võtme ja väärtusega. Klient peab seadistama liidese ligipääsu ajapiirangu ning liidese ajapiirangu aeg peab olema palju lühem kui lukustuse aeg, näiteks luku automaatse vabastamise aeg on 10 sekundit, seejärel on liidese ajapiirang seatud umbes 5-50 ms-le. See võimaldab sul redis-sõlme avamisel võimalikult kiiresti aega maha võtta ja vähendab luku tavapärast kasutust. 3. Klient arvutab, kui kaua luku saamine aega võtab, lahutades esimese sammu jooksul saadud aja praeguse ajaga, ainult siis, kui klient saab lukust rohkem kui 3 sõlme ja luku omandamise aeg on väiksem kui luku ajapiirangu aeg, saab klient jaotatud luku. 4. Kliendi aeg luku omandamiseks on määratud luku ajapiirangu aeg miinus aeg, mis kulub luku saamisele, arvutatud sammus 3. 5. Kui klient ei suuda lukku saada, kustutab klient kõik lukud kordamööda. Redlocki algoritmi abil saab garanteerida, et hajutatud lukuteenus töötab ka siis, kui ühendatakse kuni 2 sõlme, mis parandab oluliselt kättesaadavust võrreldes varasema andmebaasiluku ja vahemälu lukustusega.
Kuid üks hajutatud ekspert kirjutas artikli "Kuidas teha hajutatud lukustust", milles kahtlustas Redlocki korrektsust.
Ekspert mainis, et hajutatud lukkude kaalumisel tuleb arvestada kahte aspekti: jõudlust ja korrektsust.
Kui kasutad kõrge jõudlusega hajutatud lukku ja korrektsust ei nõuta, siis on vahemälulukk piisav.
Kui kasutad väga usaldusväärset hajutatud lukku, pead arvestama rangete töökindluse küsimustega. Redlock seevastu ei vasta sellele korrektsusele. Miks mitte? Eksperdid loetlevad mitmeid aspekte.
Tänapäeval kasutavad paljud programmeerimiskeeled virtuaalmasinaid koos GC funktsioonidega, Full GC puhul lõpetab programm GC töötlemise, mõnikord võtab Full GC kaua aega ja isegi programmil on paar minutit viivitust, artiklis tuuakse näiteks HBase, mõnikord GC mõneks minutiks, mis põhjustab rendiperioodi aegumise. Näiteks alloleval joonisel saab klient 1 lukku ja hakkab jagatud ressurssi töötlema, ning kui ta hakkab jagatud ressurssi töötlema, toimub täielik GC kuni lukk aegub. Nii saab klient 2 taas lukku ja hakkab töötama jagatud ressursiga. Kui klient 2 töötleb, lõpetab klient 1 täieliku GC ja hakkab jagatud ressursse töötlema, nii et mõlemad kliendid töötlevad jagatud ressursse.
Eksperdid pakkusid lahenduse, nagu alloleval joonisel näidatud: see näeb välja nagu MVCC, vii token lukku, token on versiooni kontseptsioon, iga kord, kui operatsioonilukk on lõpetatud, lisatakse token 1, tooge token jagatud ressursside töötlemisel, ainult määratud tokeni versioon suudab jagatud ressurssi hallata.
Seejärel ütles ekspert ka, et algoritm tugineb kohalikule ajale ning Redis kasutab võtme aegumise ajal aega saamiseks määrava meetodi getTimeOfDay asemel, mitte monotoonset kella, mis samuti põhjustab ajatäpsusi. Näiteks stsenaariumis on kahel kliendil 1 ja kliendil 2 5 redis-sõlme (A, B, C, D ja E).
1. Klient 1 omandab luku A, B ja C pealt ning saab lukuvõrgu timeouti D-lt ja E-lt. 2. Sõlme C kell on ebatäpne, põhjustades lukustuse ajapiirangu. 3. klient 2 omandab luku edukalt C-st, D-st ja E-st ning saab lukuvõrgu ajapiirangu A-st ja B-st. 4. Nii saavad nii klient 1 kui ka klient 2 lukku. Kokkuvõtteks kaks punkti, mida eksperdid Redlocki kättesaamatuse kohta ütlevad:
1. GC ja muud stsenaariumid võivad tekkida igal ajal, põhjustades kliendil lukustuse, ning töötlemise aegne aeg paneb teise kliendi luku kätte saama. Eksperdid pakkusid ka lahenduse isekasvavate tokenite kasutamiseks. 2. Algoritm tugineb kohalikule ajale ning kell on ebatäpne, mistõttu lukustuvad korraga kaks klienti. Seetõttu on ekspertide järeldus, et Redlock suudab normaalselt töötada ainult piiratud võrgu viivituse, programmi katkestamise ja piiratud kella vea vahemikus, kuid nende kolme stsenaariumi piire ei saa kinnitada, seega eksperdid ei soovita Redlocki kasutamist. Kõrgete täpsusnõuete korral soovitavad eksperdid Zookeeperit, millest räägitakse hiljem Zookeeper'i kasutamisest hajutatud lukuna.
Redis'i autori vastus
Redis'i autor vastas, kirjutades blogi pärast eksperdi artikli nägemist. Autor tänas eksperti viisakalt ja väljendas seejärel oma eriarvamust eksperdi seisukohaga.
REDIS-i autori arutelu tokenite kasutamisest lukustuse ajapiirangu probleemi lahendamiseks võib kokku võtta järgmiste viie punktiga:
Punkt 1, hajutatud lukkude kasutamine on üldiselt seotud sellega, et sul pole muud võimalust jagatud ressursside kontrollimiseks, eksperdid kasutavad tokeneid jagatud ressursside töötlemise tagamiseks ning siis pole hajutatud lukke vaja. Punkt 2: Tokenite genereerimise puhul, et tagada erinevate klientide poolt saadud tokenite usaldusväärsus, vajab tokenite genereeriv teenus siiski hajutatud lukke, et tagada teenuse usaldusväärsus. Punkt 3, kuidas eksperdid ütlevad, et isekasvavad tokenid, usub Redis autor, et see on täiesti tarbetu, iga klient saab genereerida unikaalse uuid-i tokenina ja seada jagatud ressursi seisundisse, mida suudab hallata ainult uuid-ga klient, nii et teised kliendid ei saa jagatud ressurssi töödelda enne, kui lukku saanud klient luku vabastab. Nagu ülaltoodud joonisel näidatud, kui token 34 klient saadab kirjutamisprotsessi ajal GC ja põhjustab lukustuse aegumise, võib teine klient saada tokeni 35 luku ja hakata uuesti kirjutama, mis põhjustab lukukonflikti. Seetõttu ei saa tokenite järjekorda kombineerida jagatud ressurssidega. Punkt 5, redis'i autor usub, et enamikus stsenaariumites kasutatakse hajutatud lukke uuendusprobleemide lahendamiseks mitte-tehingulistes olukordades. Autor peaks mõtlema, et on olukordi, kus tokenite kombineerimine jagatud ressursside haldamiseks on keeruline, seega tuleb ressursside lukustamiseks ja töötlemiseks loota lukkudele. Teine kellaprobleem, millest eksperdid räägivad, on see, et Redis autorid annavad samuti selgituse. Kui luku omandamiseks kuluv aeg on liiga pikk ja ületab luku vaikimisi ajapiirangu aja, siis klient ei saa lukku praegu kätte ning eksperdid ei paku ühtegi näidet.
Isiklikud tunded
Esimene probleem, mille kokku võtan, on see, et pärast seda, kui klient on saanud hajutatud luku, võib lukk vabastada pärast kliendi töötlemise ajal ajapiirangut. Varem, kui rääkida andmebaasi lukustuse poolt määratud 2-minutilisest ajapiirangust, siis kui ülesanne on tellimuslukus kauem kui 2 minutit, saab teine kauplemiskeskus selle orderiluku, nii et mõlemad kauplemiskeskused saavad sama tellimust samaaegselt töödelda. Tavapärastes tingimustes töödeldakse ülesannet sekunditega, kuid mõnikord, kui RPC päringuga liitumisega määratud aeg on liiga pikk ja ülesandes on mitu sellist ajapiirangu taotlust, siis on tõenäoline, et automaatse avamise aeg ületatakse. Kui kirjutame Java-s, võib keskel olla Full GC, nii et pärast luku avamist ei suuda klient seda tajuda, mis on väga tõsine asi. Ma ei arva, et see on probleem lukuga endaga, kui iga ülalmainitud hajutatud lukk omab ajapiirangu omadusi, siis selline probleem tekib. Kui kasutad lukustamise ajapiirangu funktsiooni, peab klient seadistama luku ajapiirangu ja tegutsema vastavalt, selle asemel et jätkata jagatud ressursi töötlemist. Redlocki algoritm tagastab luku aja, mida klient saab pärast luku omandamist hõivata, ning klient peab selle aja töötlema, et ülesanne pärast seda aega peatada.
Teine probleem on see, et hajutatud eksperdid ei mõista Redlocki. Redlocki oluline omadus on see, et luku hankimise aeg on kogu aeg, mille lukustus vaikimisi ajapiirangule viib, miinus luku hankimiseks kuluv aeg, nii et kliendi töötlemiseks kuluv aeg on suhteline aeg, sõltumata kohalikust ajast.
Sellest vaatepunktist võib Redlocki korrektsust kindlalt garanteerida. Redlocki hoolikas analüüs, võrreldes sõlme Redis'iga on Redlocki peamine omadus kõrgem töökindlus, mis on mõnes olukorras oluline. Aga ma arvan, et Redlock on kulutanud liiga palju raha, et saavutada usaldusväärsus.
- Esiteks tuleb Redlocki töökindlamaks muutmiseks paigaldada 5 sõlme.
- Seejärel tuleb taotleda 5 sõlme, et lukustus saada, ja Future meetodi abil saad esmalt samaaegselt pärida 5 sõlmele ning seejärel saada vastuse tulemuse kokku, mis võib lühendada reageerimisaega, kuid võtab ikkagi rohkem aega kui ühe sõlme redis-lukustus.
- Kuna viiest sõlmest tuleb saada rohkem kui 3, võib tekkida lukukonflikt, st kõik on saanud 1-2 lukku, mille tulemusena keegi lukku ei saa, selle probleemi puhul laenab Redis autor parve algoritmi olemuse, juhusliku kokkupõrke kaudu saab konfliktiaega oluliselt vähendada, kuid seda probleemi ei saa väga hästi vältida, eriti kui lukk on esmakordselt omandatud, mistõttu luku omandamise ajakulu suureneb.
- Kui 2 viiest sõlmest on maas, väheneb lukustuse kättesaadavus oluliselt, kõigepealt pead ootama, kuni nende kahe sõlme tulemused aeguvad, enne kui tagasi tuled, ja sõlme on ainult 3, ning klient peab saama kõigi kolme sõlme lukud, et lukustus saada, mis on samuti keerulisem.
- Kui on olemas võrgupartitsioon, võib tekkida olukord, kus klient ei saa kunagi lukku kätte.
Pärast paljude põhjuste analüüsimist arvan, et Redlocki probleemi kõige kriitilisem punkt on see, et Redlock nõuab klientidelt kirjutiste järjepidevuse tagamist ning backend 5 sõlme on täiesti sõltumatud ja kõik kliendid peavad neid 5 sõlme haldama. Kui viie sõlme vahel on juht, saab klient sünkroniseerida juhi andmeid, kui klient saab luku juhilt, nii et ei teki probleeme nagu partitsioneerimine, ajapiirangud ega konfliktid. Seetõttu arvan, et hajutatud lukkude korrektsuse tagamiseks võib tugeva järjepidevusega hajutatud koordineerimisteenuse kasutamine probleemi paremini lahendada.
Küsimus kerkib taas, kui pikk peaksin aegumisaega määrama? Kuidas seadistada tühistamise aeg on liiga lühike ja lukk vabastatakse automaatselt enne meetodi käivitamist, siis tekivad paralleelsuse probleemid. Kui see võtab liiga kaua aega, võivad teised lukustunud lõimed kaua oodata.
See probleem esineb ka andmebaaside kasutamisel hajutatud lukkude rakendamiseks.
Praegune peavoolu lähenemine sellele probleemile on seada iga saadud luku jaoks lühike ajapiirangu aeg ja alustada lõime, mis värskendab luku ajapiirangu aega iga kord, kui see on peagi ajapiirangu saavutamisel. Lõpeta see teema samal ajal, kui vabastad luku. Näiteks redisson, redis'i ametlik hajutatud lukukomponent, kasutab seda lahendust.
Vahemällu salvestamise eelised hajutatud lukkude rakendamiseks Hea etteaste.
Vahemällu salvestamise puudused hajutatud lukkude rakendamiseks Rakendamine on liiga vastutustundlik, on liiga palju tegureid, mida arvestada.
Jaotatud lukud Zookeeperi rakenduse põhjal
Jaotatud lukud, mis põhinevad Zookeeperi ajutiste tellitud sõlmede alusel.
Üldine idee on, et kui iga klient lukustab meetodi, genereeritakse määratud sõlme kataloogis unikaalne hetkeline järjestatud sõlm, mis vastab Zookeeperi meetodile. Luku saamiseks on lihtne viis – piisab ainult sellest, millel on kõige väiksem seerianumber järjestatud sõlmes. Kui lukk on vabastatud, kustuta lihtsalt hetkeline sõlm. Samal ajal saab see vältida teenuse seisakute tõttu tekkinud ummikseisu, mida ei saa vabastada.
Vaatame, kas Zookeeper suudab lahendada eelnevalt mainitud probleemid.
- Lukk ei vabane? Zookeeperi kasutamine võib tõhusalt lahendada probleemi, et lukke ei vabastata, sest lukku luues loob klient ZK-s ajutise sõlme, ja kui klient luku kätte saab ning järsku selle kinni paneb (sessiooniühendus katkeb), kustutatakse ajutine sõlm automaatselt. Teised kliendid saavad luku uuesti.
- Mitteblokeerivad lukud? Kui sõlm muutub, teavitab Zookeeper klienti ning klient saab kontrollida, kas loodud sõlm on kõigi sõlmede seas väikseim ordinaalnumber.
- Ei saa uuesti sisse tulla? Kui klient loob sõlme, kirjutab ta otse praeguse kliendi hosti- ja lõimeinfo sõlmele ning järgmine kord, kui soovid lukku saada, saad seda võrrelda praeguse väikseima sõlme andmetega. Kui info on sama mis sinu oma, saad luku otse kätte ja kui see on erinev, luua ajutise järjestikuse sõlme, mis osaleb järjekorras.
Küsimus kerkib taas: me teame, et Zookeeper tuleb rakendada klastrites, kas tekivad andmete sünkroniseerimise probleemid nagu Redis klastrites?
Zookeeper on hajutatud komponent, mis tagab nõrga järjepidevuse, st lõpliku järjepidevuse.
Zookeeper kasutab andmete sünkroniseerimisprotokolli nimega Quorum Based Protocol. Kui Zookeeperi klastris on N Zookeeperi serverit (N on tavaliselt paaritu, 3 suudab tagada andmete usaldusväärsuse ja kõrge lugemis- ja kirjutamisjõudluse ning 5 on parim tasakaal andmete usaldusväärsuse ja lugemis- ning kirjutamisjõudluse vahel), siis kasutaja kirjutamisoperatsioon sünkroniseeritakse esmalt N/2 + 1 serveritega ja seejärel tagastatakse kasutajale, paludes kasutajal edukalt kirjutada. Andmete sünkroniseerimisprotokoll, mis põhineb Quorum-põhisel protokollil, määrab Zookeeperi toetatud tugevuse järjepidevuse.
Hajutatud keskkonnas puudub andmesalvestus, mis vastab tugevale järjepidevusele, ning see nõuab, et kõik sõlmed oleksid sünkroonselt uuendatud ühe sõlme andmete uuendamisel. See sünkroniseerimisstrateegia ilmub master-slave sünkroonse replikatsiooni andmebaasis. Kuid see sünkroniseerimisstrateegia mõjutab kirjutamisjõudlust liiga palju ja seda näeb praktikas harva. Kuna Zookeeper kirjutab N/2+1 sõlme sünkroonselt ja N/2 sõlmi ei uuendata sünkroonselt, ei ole Zookeeper tugevalt järjepidev.
Kasutaja andmete uuendamise operatsioon ei taga, et järgnevad lugemised loevad uuendatud väärtuse, kuid näitab lõpuks järjepidevust. Järjepidevuse ohverdamine ei tähenda andmete järjepidevuse täielikku ignoreerimist, vastasel juhul on andmed kaootilised, nii et ükskõik kui kõrge on süsteemi kättesaadavus või hea jaotus, pole sellel mingit väärtust. Järjepidevuse ohverdamine tähendab lihtsalt seda, et tugevat järjepidevust relatsioonilistes andmebaasides enam ei vajata, vaid seni, kuni süsteem suudab lõpuks saavutada järjepidevuse.
Ühepunktiline küsimus? Zookeeperi kasutamine suudab tõhusalt lahendada ühe punkti probleemi, ZK on kasutusel klastrites, kui üle poole klastri masinatest säilib, saab teenust pakkuda ka välismaailmale.
Õiglusprobleemid? Zookeeperi kasutamine võib lahendada õiglaste lukustuste probleemi, kliendi poolt ZK-s loodud ajutised sõlmed on korrastatud ning iga kord, kui lukk vabastatakse, saab ZK teavitada väikseimat sõlme, et lukustus saada, tagades õigluse.
Küsimus kerkib taas: me teame, et Zookeeper tuleb rakendada klastrites, kas tekivad andmete sünkroniseerimise probleemid nagu Redis klastrites?
Zookeeper on hajutatud komponent, mis tagab nõrga järjepidevuse, st lõpliku järjepidevuse.
Zookeeper kasutab andmete sünkroniseerimisprotokolli nimega Quorum Based Protocol. Kui Zookeeperi klastris on N Zookeeperi serverit (N on tavaliselt paaritu, 3 suudab tagada andmete usaldusväärsuse ja kõrge lugemis- ja kirjutamisjõudluse ning 5 on parim tasakaal andmete usaldusväärsuse ja lugemis- ning kirjutamisjõudluse vahel), siis kasutaja kirjutamisoperatsioon sünkroniseeritakse esmalt N/2 + 1 serveritega ja seejärel tagastatakse kasutajale, paludes kasutajal edukalt kirjutada. Andmete sünkroniseerimisprotokoll, mis põhineb Quorum-põhisel protokollil, määrab Zookeeperi toetatud tugevuse järjepidevuse.
Hajutatud keskkonnas puudub andmesalvestus, mis vastab tugevale järjepidevusele, ning see nõuab, et kõik sõlmed oleksid sünkroonselt uuendatud ühe sõlme andmete uuendamisel. See sünkroniseerimisstrateegia ilmub master-slave sünkroonse replikatsiooni andmebaasis. Kuid see sünkroniseerimisstrateegia mõjutab kirjutamisjõudlust liiga palju ja seda näeb praktikas harva. Kuna Zookeeper kirjutab N/2+1 sõlme sünkroonselt ja N/2 sõlmi ei uuendata sünkroonselt, ei ole Zookeeper tugevalt järjepidev.
Kasutaja andmete uuendamise operatsioon ei taga, et järgnevad lugemised loevad uuendatud väärtuse, kuid näitab lõpuks järjepidevust. Järjepidevuse ohverdamine ei tähenda andmete järjepidevuse täielikku ignoreerimist, vastasel juhul on andmed kaootilised, nii et ükskõik kui kõrge on süsteemi kättesaadavus või hea jaotus, pole sellel mingit väärtust. Järjepidevuse ohverdamine tähendab lihtsalt seda, et tugevat järjepidevust relatsioonilistes andmebaasides enam ei vajata, vaid seni, kuni süsteem suudab lõpuks saavutada järjepidevuse.
Kas Zookeeper vastab põhjuslikule järjepidevusele, sõltub sellest, kuidas klient on programmeeritud.
Praktikad, mis ei rahulda põhjuslikku järjepidevust
- Protsess A kirjutab andmetüki loomaaiahoidja /z-le ja tagastab edukalt
- Protsess A teavitab protsessi B, et A on muutnud /z andmeid
- B loeb loomaaia hoidja /z andmeid
- Kuna Zookeeperi server, mis on ühendatud B-ga, ei pruugi olla uuendatud A kirjalike andmetega, siis B ei saa lugeda A kirjutatud andmeid
Praktikad, mis vastavad põhjuslikule järjepidevusele
- Protsess B kuulab Zookeeperis /z andmemuutusi
- Protsess A kirjutab andmetüki loomaaiahoidja /z-le ja enne kui see edukalt tagasi tuleb, peab loomaaiahoidja helistama /z-le registreeritud kuulajale, kes teavitab B-d andmete muutusest
- Pärast protsessi B sündmuse vastuse meetodi vastamist võtab see muudetud andmed, nii et B saab kindlasti muudetud väärtuse
- Põhjuslik järjepidevus viitab siin juhi ja B vahelisele põhjuslikule järjepidevusele, st juht teavitab andmeid muutusest
Teine sündmuste kuulamise mehhanism on ka meetod, mida tuleks kasutada Zookeeperi korrektseks programmeerimiseks, nii et Zookeeper peaks vastama põhjuslikule järjepidevusele
Seetõttu, kui rakendame Zookeeperi põhjal hajutatud lukke, peaksime kasutama põhjusliku järjepidevuse rahuldamise praktikat, st luku ootavad lõimed kuulavad Zookeeperi luku muutusi ning kui lukk vabastatakse, teavitab Zookeeper ootavat lõime, mis vastab ausate lukutingimuste tingimustele.
Saad kasutada otse Zookeeperi kolmanda osapoole raamatukogu klienti, mis kapseldab reentrant-luku teenust.
ZK-ga teostatud hajutatud lukud tunduvad sobivat täpselt sellega, mida me selle artikli alguses hajutatud lukult ootasime. Kuid see ei ole nii, ja Zookeeperi poolt rakendatud hajutatud lukustusel on tegelikult puudus, nimelt ei pruugi jõudlus olla nii kõrge kui vahemällu salvestamise teenusel. Sest iga luku loomise ja vabastamise protsessis tuleb hetkelised sõlmed dünaamiliselt luua ja hävitada, et lukufunktsioon realiseerida. Sõlmede loomine ja kustutamine ZK-s saab toimuda ainult juhtserveri kaudu ning seejärel jagatakse andmeid kõigi järgnevate masinatega.
Zookeeperi kasutamise eelised hajutatud lukkude rakendamiseks Lahenda tõhusalt ühe punkti probleemid, mitte-sisenemise probleemid, mitteblokeerimisprobleemid ja luku lahtilaskmise ebaõnnestumine. Seda on suhteliselt lihtne rakendada.
Zookeeperi kasutamise puudused hajutatud lukkude rakendamiseks Jõudlus ei ole nii hea kui vahemälu kasutamine hajutatud lukkude rakendamiseks. ZK põhimõtete mõistmine on vajalik.
Kolme variandi võrdlus
Lihtsa mõistmise vaatenurgast (madalalt kõrgeni) Andmebaas > vahemälu > Zookeeper
Rakenduse keerukuse vaatepunktist (madalast kõrgeni) Zookeeper > vahemälu > andmebaasid
Soorituse vaatenurgast (kõrgest madalani) Vahemällu salvestamine > Zookeeper >= andmebaas
Töökindluse seisukohast (kõrgest madalani) Zookeeper > vahemälu > andmebaasid
|