K: Yksi palvelupalvelin, yksi tietokanta, operaatio: kysy käyttäjän nykyinen saldo, vähennetään 3 % nykyisestä saldosta käsittelymaksuna
Synkronoitu lukko DB-lukko
K: Kaksi palvelupalvelinta, yksi tietokanta, operaatio: kysy käyttäjän nykyinen saldo, vähennetään 3 % nykyisestä saldosta käsittelymaksuna Jaetut lukot
Minkälaista hajautettua lukkoa tarvitsemme? Se voi varmistaa, että hajautetussa sovellusklusterissa sama menetelmä voidaan suorittaa vain yhdellä säikeellä yhdellä koneella samanaikaisesti.
Jos tämä lukko on reentrant-lukko (vältä kuolleita lukkoja)
Tämä lukko on paras lukko (harkitse, haluatko tämän yrityksesi tarpeiden mukaan)
Tämä lukko on paras olla reilu lukko (harkitse, haluatko tämän yrityksen tarpeiden mukaan)
Saatavilla on runsaasti hankinta- ja vapautuslukkotoimintoja
Hankinta- ja vapautuslukkojen suorituskyky on parempi
1. Jaetut lukot tietokantojen pohjalta
Jaetut lukot taulukkopohjaisten toteutusten pohjalta
Kun haluamme lukita metodin, suoritamme seuraavan SQL:n: insert in methodLock(method_name,desc) arvot ('method_name','desc')
Koska olemme asettaneet ainutlaatuisuusrajoitteen method_name:lle, jos tietokantaan lähetetään useita pyyntöjä samanaikaisesti, tietokanta varmistaa, että vain yksi operaatio onnistuu, voimme olettaa, että säie, joka onnistuneesti sai metodin, lukitsee ja pystyy suorittamaan metodin rungon sisällön.
Kun metodi suoritetaan, jos haluat vapauttaa lukon, sinun täytyy suorittaa seuraava Sql: poista methodLockista, missä method_name ='method_name'
Tämä yksinkertainen toteutus yllä aiheuttaa seuraavat ongelmat:
- Tämä lukko riippuu tietokannan saatavuudesta, joka on yksi piste ja aiheuttaa liiketoimintajärjestelmän pois käytöstä, kun tietokanta on jumistettu.
- Tällä lukolla ei ole vanhenemisaikaa, ja kun avaustoiminto epäonnistuu, lukitustietue jää tietokantaan eikä muut säikeet enää pysty saamaan lukkoa.
- Tämä lukko voi olla vain ei-estävä, koska datan insert-toiminto raportoi suoraan virheen, kun lisäys epäonnistuu. Säikeet, jotka eivät saa lukkoja, eivät siirry jonoon, ja niiden täytyy käynnistää lukon hankintaoperaatio uudelleen, jotta lukko saadaan uudelleen.
- Lukko on ei-uudelleenkäynnistys, eikä sama säie voi saada lukkoa uudelleen ennen kuin se vapautetaan. Koska datan sisältö on jo olemassa.
- Tämä lukko on epäreilu lukko, ja kaikki lukkoa odottavat langat kilpailevat lukosta tuurin kautta.
Tietenkin voimme ratkaista edellä mainitut ongelmat myös muilla tavoilla.
- Onko tietokanta vain yksi piste? Rakenna kaksi tietokantaa, ja data synkronoidaan molempiin suuntiin. Kun puhelu on katkaistu, vaihda nopeasti varmuuskopiokirjastoon.
- Ei viimeistä käyttöaikaa? Tee vain aikataulutettu tehtävä siivotaksesi tietokannan aikakatkaisutiedot säännöllisin väliajoin.
- Ei-estäminen? Tee while-silmukka, kunnes insertti onnistuu ja sitten onnistuu.
- Ei-palaaminen? Lisää kenttä tietokantatauluun tallentaaksesi koneen isäntä- ja säietiedot, joka tällä hetkellä saa lukon, ja seuraavan kerran kun saat lukon, kysy ensin tietokannasta, jos nykyisen koneen isäntä- ja säietiedot löytyvät tietokannasta, voit suoraan liittää lukon hänelle.
- Epäreilua? Luo toinen välitaulukko tallentamaan kaikki lukkoa odottavat säikeet ja lajittele ne luomisajan mukaan, ja vain ensimmäinen luotu saa lukon
Jaetut lukot, jotka perustuvat eksklusiivisiin lukkoihin
Tietojen lisäämisen ja poistamisen lisäksi hajautettuja lukkoja voidaan toteuttaa myös datan mukana tulevien lukkojen avulla.
Käytämme myös juuri luomaamme tietokantataulukkoa. Hajautettuja lukkoja voidaan toteuttaa yksinoikeudella tietokannoissa. MySQL-pohjainen InnoDB-moottori voi käyttää seuraavia menetelmiä lukitustoimintojen toteuttamiseen:
Jos lisäät päivitystä varten kyselylauseen jälkeen, tietokanta lisää eksklusiivisen lukituksen tietokantatauluun kyselyprosessin aikana. Kun tietueeseen lisätään yksinoikeudellinen lukko, muut säikeet eivät enää voi lisätä yksinoikeutta kyseiselle linjalle.
Voimme ajatella, että säie, joka saa eksklusiivisen lukon, voi saada hajautetun lukon, ja kun lukko on saatu, metodin liiketoimintalogiikka voidaan suorittaa ja avata seuraavilla menetelmillä:
public void unlock(){ connection.commit(); }
via connection.commit(); Operaatio lukon vapauttamiseksi.
Tämä menetelmä voi tehokkaasti ratkaista edellä mainitut ongelmat, jotka liittyvät lukon irrottamisen ja lukon estämisen kyvyttömyyteen.
Lukkojen estäminen? Päivityslauseke palautuu heti onnistuneen suorituksen jälkeen ja pysyy estettynä, kunnes se onnistuu.
Palvelu poikki lukituksen jälkeen, eikö sitä voi vapauttaa? Näin tietokanta vapauttaa lukon itsestään palvelun kaatumisen jälkeen.
Se ei kuitenkaan ratkaise suoraan tietokannan yksittäispisteen, reentranssin ja reilun lukituksen ongelmaa.
Yhteenvetona, miten tietokantaa käytetään hajautettujen lukkojen toteuttamiseen, jotka molemmat perustuvat tietokannan tauluun: toinen on selvittää, onko lukko olemassa tietueiden perusteella taulussa, ja toinen on toteuttaa hajautetut lukot tietokannan eksklusiivisen lukituksen kautta.
Hajautetun lukituksen edut tietokannoissa
Suoraan tietokannan avulla se on helppo ymmärtää.
Haitat hajautettujen lukkojen toteuttamisessa tietokannoissa
Ongelmia tulee olemaan erilaisia, ja koko ratkaisu muuttuu yhä monimutkaisemmaksi ongelman ratkaisuprosessin aikana.
Tietokannan ylläpito vaatii tiettyjä ylikuormituksia, ja suorituskykyyn liittyvät haasteet on otettava huomioon.
2. Jaetut lukot välimuistin perusteella
Verrattuna tietokantapohjaiseen hajautettuun lukitusratkaisuun, välimuistipohjainen toteutus suoriutuu suorituskyvyltään paremmin.
Tällä hetkellä on olemassa monia kypsiä välimuistituotteita, kuten Redis, memcached jne. Tässä otamme Redisin esimerkkinä analysoidessamme välimuistin käyttöä hajautettujen lukkojen toteuttamiseen.
Internetissä on monia aiheeseen liittyviä artikkeleita hajautettujen lukkojen toteuttamisesta Redisin pohjalta, ja pääasiallinen toteutustapa on käyttää Jedis.setNX-menetelmää.
Yllä mainitussa toteutuksessa on myös useita ongelmia:
1. Yhden pisteen ongelma.
2. Tällä lukolla ei ole vanhenemisaikaa, kun lukituksen avaus epäonnistuu, lukitustietue pysyy jatkuvasti redis-tilassa, eikä muut säikeet enää saa lukkoa.
3. Tämä lukko voi olla vain ei-estävä, ja se palaa suoraan riippumatta onnistumisesta vai epäonnistumisesta.
4. Tämä lukko ei ole reenterantti, sillä sen jälkeen kun säie saa lukon, se ei voi saada lukkoa uudelleen ennen lukon vapauttamista, koska käytetty avain on jo olemassa redisissä. setNX-operaatioita ei voi enää suorittaa.
5. Tämä lukko on epäreilu, kaikki odottavat säikeet aloittavat setNX-toiminnot samanaikaisesti, ja onnekkaat säikeet voivat saada lukon.
Tietenkin on myös tapoja ratkaista se.
- Nykyään valtavirran välimuistipalvelut tukevat klusterien käyttöönottoa yksittäispisteongelmien ratkaisemiseksi klusteroinnin avulla.
- Ei viimeistä käyttöaikaa? Redisin setExpire-menetelmä tukee saapuvaa vanhenemisaikaa, ja data poistetaan automaattisesti ajan päätyttyä.
- Ei-estäminen? vaikka hänet teloitettiin toistuvasti.
- Eikö ole mahdollista palata sisään? Kun säie saa lukon, tallenna nykyinen isäntä- ja säietieto, ja tarkista, oletko nykyisen lukon omistaja ennen kuin saat sen seuraavalla kerralla.
- Epäreilua? Laita kaikki odottavat säikeet jonoon ennen kuin säie saa lukon, ja hanki lukko ensimmäisenä sisään, ensimmäisenä ulos -periaatteella.
Redis-klusterin synkronointipolitiikka vie aikaa, ja on mahdollista, että säie A saa lukon NX:n onnistuneen asetuksen jälkeen, mutta tätä arvoa ei ole päivitetty palvelimelle, jossa säie B suorittaa setNX:n, mikä aiheuttaa samanaikaisuusongelmia.
Redisin tekijä Salvatore Sanfilippo ehdotti Redlock-algoritmia, joka toteuttaa hajautetun lukkohallinnan (DLM), joka on turvallisempi ja luotettavampi kuin yksittäinen solmu.
Redlock-algoritmi olettaa, että on olemassa N Redis-solmua, jotka ovat toisistaan riippumattomia, yleensä asetettuna N=5:een, ja nämä N solmua toimivat eri koneilla säilyttääkseen fyysisen riippumattomuuden.
Algoritmin vaiheet ovat seuraavat:
1. Asiakas saa nykyisen ajan millisekunneissa. 2. Asiakas yrittää saada lukon N solmusta (jokainen solmu saa lukon samalla tavalla kuin aiemmin mainittu välimuistilukko), ja N solmua saa lukon samalla avaimella ja arvolla. Asiakkaan täytyy asettaa rajapinnan käyttöaikakatkaisu, ja sen tulee olla paljon lyhyempi kuin lukituksen aikakatkaisu, esimerkiksi lukituksen automaattinen vapautusaika on 10 sekuntia, jolloin rajapinnan aikakatkaisu asetetaan noin 5–50 ms:iin. Tämä mahdollistaa aikakatkaisun mahdollisimman pian, kun pääset redis-solmuun, kun se on mennyt alas, ja vähentää lukituksen normaalia käyttöä. 3. Asiakas laskee, kuinka kauan lukon saaminen kestää, vähentämällä vaiheessa 1 saavutettu aika nykyisestä ajasta, vasta kun asiakas saa lukosta yli 3 solmua ja lukon hankintaaika on lyhyempi kuin lukon aikakatkaisuaika, asiakas saa jakautuneen lukon. 4. Asiakkaan aika lukon hankintaan on asetettu lukon aikakatkaisuaika miinus lukon hankintaan käytetty aika, joka lasketaan vaiheessa 3. 5. Jos asiakas ei saa lukkoa, asiakas poistaa kaikki lukot vuorollaan. Redlock-algoritmin avulla voidaan taata, että hajautettu lukituspalvelu toimii edelleen, kun käytössä on enintään kaksi solmua, mikä parantaa huomattavasti saatavuutta verrattuna aiempaan tietokanta- ja välimuistilukkoon.
Kuitenkin eräs jakautunut asiantuntija kirjoitti artikkelin "How to do distributed locking" kyseenalaistaen Redlockin oikeellisuuden.
Asiantuntija mainitsi, että hajautettuja lukkoja harkitessa on kaksi näkökulmaa: suorituskyky ja oikeellisuus.
Jos käytät suorituskykyistä hajautettua lukkoa eikä oikeellisuutta vaadita, välimuistilukon käyttö riittää.
Jos käytät erittäin luotettavaa hajautettua lukkoa, sinun tulee ottaa huomioon tiukat luotettavuuskysymykset. Redlock puolestaan ei täytä tätä oikeellisuutta. Miksi ei? Asiantuntijat listaavat useita osa-alueita.
Nykyään monet ohjelmointikielet käyttävät virtuaalikoneita, joissa on GC-funktioita; Full GC:ssä ohjelma lakkaa käsittelemästä GC:tä, joskus Full GC kestää kauan, ja jopa ohjelmassa on muutaman minuutin viive. Artikkelissa mainitaan esimerkki HBasesta, joskus GC:stä muutamaksi minuutiksi, mikä aiheuttaa vuokrasopimuksen päättymisen. Esimerkiksi alla olevassa kuvassa asiakas 1 saa lukon ja on käsittelemässä jaettua resurssia, ja kun se on käsittelemässä jaettua resurssia, Full GC jatkuu siihen asti, kunnes lukko vanhenee. Näin asiakas 2 saa lukon uudelleen ja alkaa työskennellä jaetun resurssin parissa. Kun asiakas 2 käsittelee, asiakas 1 suorittaa täyden GC:n ja alkaa käsitellä jaettuja resursseja, jolloin molemmat asiakkaat käsittelevät jaettuja resursseja.
Asiantuntijat antoivat ratkaisun, kuten alla olevassa kuvassa näkyy, näyttää MVCC:ltä, tuo token lukkoon, token on version käsite, joka kerta kun operaatiolukko on valmis, token lisätään 1, tuo token jaettuja resursseja käsitellessä, vain määritelty tokenin versio voi käsitellä jaettua resurssia.
Sitten asiantuntija sanoi myös, että algoritmi perustuu paikalliseen aikaan, ja että Redis käyttää getTimeOfDay -menetelmää saadakseen ajan monotonisen kellon sijaan avaimen vanhenemisen yhteydessä, mikä johtaa myös aikavirheisiin. Esimerkiksi skenaariossa kahdella asiakkaalla 1 ja asiakas 2:lla on 5 redis-solmua (A, B, C, D ja E).
1. Asiakas 1 onnistuu saamaan lukon A:lta, B:ltä ja C:ltä ja saa lukkoverkon aikakatkaisun D:ltä ja E:ltä. 2. Solmun C kello on epätarkka, mikä aiheuttaa lukituksen aikakatkaisun. 3. asiakas 2 onnistuu hankkimaan lukon C:ltä, D:ltä ja E:ltä ja saa lukkoverkon aikakatkaisun A:lta ja B:ltä. 4. Näin sekä asiakas 1 että asiakas 2 saavat lukon. Yhteenvetona kahdesta asiasta, joita asiantuntijat sanovat Redlockin poissaolosta:
1. GC ja muut skenaariot voivat tapahtua milloin tahansa, jolloin asiakas saa lukon ja käsittelyaikakatkaisu saa toisen asiakkaan lukituksen. Asiantuntijat antoivat myös ratkaisun itsestään kasvavien tokenien käyttöön. 2. Algoritmi perustuu paikalliseen aikaan, ja kello on epätarkka, jolloin kaksi asiakasta saa lukot samanaikaisesti. Asiantuntijoiden johtopäätös on, että Redlock voi toimia normaalisti vain rajoitetussa verkkoviiveessä, rajoitetussa ohjelmakatkoksessa ja rajoitetussa kellon virhealueella, mutta näiden kolmen skenaarion rajoja ei voida vahvistaa, joten asiantuntijat eivät suosittele Redlockin käyttöä. Skenaarioissa, joissa vaaditaan korkeat oikeellisuudet, asiantuntijat suosittelevat Zookeeperia, josta myöhemmin keskustellaan Zookeeperin käytöstä hajautettuna lukkona.
Redis-kirjan kirjoittajan vastaus
Redisin kirjoittaja vastasi kirjoittamalla blogin nähtyään asiantuntijan artikkelin. Kirjoittaja kiitti asiantuntijaa kohteliaasti ja ilmaisi sitten erimielisyytensä asiantuntijan näkemyksestä.
Pyysin analyysiä alkuperäisestä Redlock-spesifikaatiosta tässä:http://redis.io/topics/distlock.Joten kiitos Martin. En kuitenkaan ole samaa mieltä analyysin kanssa.
REDISin kirjoittajan keskustelu tokenien käytöstä lukitusaikakatkaisuongelman ratkaisemiseksi voidaan tiivistää seuraaviin viiteen kohtaan:
Kohta 1, hajautettujen lukkojen käyttö johtuu yleensä siitä, ettei ole muuta tapaa hallita jaettuja resursseja, asiantuntijat käyttävät tokeneita varmistaakseen jaettujen resurssien käsittelyn, jolloin hajautettuja lukkoja ei tarvita. Kohta 2: Tokenien luomisessa, eri asiakkaiden saamien tokenien luotettavuuden varmistamiseksi palvelu, joka tuottaa tokeneita, tarvitsee edelleen hajautettuja lukkoja palvelun luotettavuuden varmistamiseksi. Kohta 3, asiantuntijat sanovat, että itsestään kasvavat tokenit, Redisin kirjoittaja katsoo, että se on täysin tarpeetonta, jokainen asiakas voi luoda ainutlaatuisen uuid:n tokeniksi ja asettaa jaetun resurssin tilaan, jonka vain uuid-asiakas voi käsitellä, jotta muut asiakkaat eivät voi käsitellä jaettua resurssia ennen kuin lukon saanut asiakas vapauttaa lukon. Kuten yllä olevassa kuvassa on esitetty, jos token 34:n asiakas lähettää GC:n kirjoitusprosessin aikana ja aiheuttaa lukituksen aikakatkaisun, toinen asiakas voi saada tokenin 35 lukituksen ja alkaa kirjoittaa uudelleen, mikä johtaa lukituskonfliktiin. Siksi tokenien järjestystä ei voi yhdistää yhteisiin resursseihin. Kohta 5, Redisin kirjoittaja uskoo, että useimmissa tilanteissa hajautettuja lukkoja käytetään päivitysongelmien käsittelemiseen ei-transaktiotilanteissa. Kirjoittajan pitäisi tarkoittaa, että on tilanteita, joissa tokenien yhdistäminen jaettujen resurssien hallintaan on vaikeaa, joten sinun täytyy luottaa lukkoihin resurssien lukitsemiseksi ja käsittelyyn. Toinen kelloongelma, josta asiantuntijat puhuvat, on se, että Redisin kirjoittajat antavat myös selityksen. Jos lukon hankintaan kuluva aika on liian pitkä ja ylittää lukon oletusaikakatkaisun, asiakas ei voi saada lukkoa tällä hetkellä, eikä asiantuntijat ehdota esimerkkejä.
Henkilökohtaiset tunteet
Ensimmäinen ongelma, jonka tiivistän, on se, että kun asiakas saa hajautetun lukon, lukko voidaan vapauttaa aikakatkaisun jälkeen asiakkaan käsittelyn aikana. Aiemmin, kun puhuttiin tietokantalukon asettamasta 2 minuutin aikakatkaisesta, jos tehtävä on varassa tilauslukossa yli 2 minuuttia, toinen kauppakeskus voi saada tämän tilauslukon, jolloin molemmat kauppakeskukset voivat käsitellä saman tilauksen samanaikaisesti. Normaaleissa olosuhteissa tehtävä käsitellään sekunneissa, mutta joskus RPC-pyyntöön liittymisen aikakatkaisu on liian pitkä ja tehtävässä on useita tällaisia aikakatkaisupyyntöjä, jolloin automaattinen avausaika todennäköisesti ylittyy. Jos kirjoitamme Javalla, keskellä voi olla Full GC, jolloin lukituksen avauduttua lukituksen aikakatkaisun jälkeen asiakas ei pysty havaitsemaan sitä, mikä on hyvin vakava asia. En usko, että tämä on ongelma lukossa itsessään, kunhan yllä mainituilla hajautuneilla lukkoilla on aikakatkaisun ominaisuudet, tällainen ongelma ilmenee. Jos käytät lukitusaikakatkaisutoimintoa, asiakkaan täytyy asettaa lukitusaikakatkaisu ja toimia sen mukaisesti sen sijaan, että jatkettaisiin jaetun resurssin käsittelyä. Redlockin algoritmi palauttaa lukitusajan, jonka asiakas voi käyttää sen jälkeen, kun asiakas on saanut lukon, ja asiakkaan täytyy käsitellä tämä aika pysäyttääkseen tehtävän tuon ajan jälkeen.
Toinen ongelma on, että hajautetut asiantuntijat eivät ymmärrä Redlockia. Redlockin keskeinen ominaisuus on, että lukon hankintaan kuluva aika on kokonaisaika, jonka lukko oletuksena on aikakatkaisu miinus lukon hankintaan kuluva aika, jolloin asiakkaan käsittelyaika on suhteellinen aika, riippumatta paikallisesta ajasta.
Tästä näkökulmasta Redlockin oikeellisuus on täysin taattu. Huolellinen analyysi Redlockista, verrattuna solmun Redisiin, Redlockin tärkein ominaisuus on korkeampi luotettavuus, joka on tärkeä ominaisuus joissakin tilanteissa. Mutta mielestäni Redlock on käyttänyt liikaa rahaa luotettavuuden saavuttamiseksi.
- Ensiksi on otettava käyttöön viisi solmua, jotta Redlock olisi luotettavampi.
- Sitten sinun täytyy pyytää 5 solmua saadaksesi lukituksen, ja Future-menetelmällä voit ensin pyytää viideltä solmulta samanaikaisesti ja saada vastaustuloksen yhteen, mikä voi lyhentää vasteaikaa, mutta se vie silti enemmän aikaa kuin yksittäisen solmun redis-lukko.
- Koska yli 3 viidestä solmusta täytyy hankkia, voi syntyä lukkokonflikti, eli kaikki ovat saaneet 1–2 lukkoa, eikä kukaan saa lukkoa. Tämän ongelman Redisin kirjoittaja lainaa lautaalgoritmin ydintä, satunnaisen törmäyksen kautta konfliktiaikaa voidaan merkittävästi lyhentää, mutta tätä ongelmaa ei voi välttää kovin hyvin, varsinkaan kun lukko hankitaan ensimmäistä kertaa, jolloin lukon hankinta aikakulu kasvaa.
- Jos 2 viidestä solmusta on alhaalla, lukon saatavuus vähenee huomattavasti, ensinnäkin sinun täytyy odottaa näiden kahden kaatuneen solmun tulosten aikakatkaisua ennen paluuta, ja solmuja on vain kolme, ja asiakkaan täytyy saada kaikkien kolmen solmun lukot saadakseen lukon, mikä on myös vaikeampaa.
- Jos verkkoosio on olemassa, voi olla tilanne, jossa asiakas ei koskaan saa lukkoa.
Monien syiden analysoinnin jälkeen mielestäni Redlockin ongelman kriittisin kohta on, että Redlock vaatii asiakkaita varmistamaan kirjoitusten johdonmukaisuuden, ja backend-viisi solmua ovat täysin itsenäisiä, ja kaikkien asiakkaiden täytyy käyttää näitä viittä solmua. Jos johtaja on viiden solmun joukossa, asiakas voi synkronoida johtajan tiedot niin kauan kuin asiakas saa lukon johtajalta, jolloin ei ole ongelmia kuten osiointia, aikakatkaisuja tai ristiriitoja. Siksi hajautetun lukkojen oikeellisuuden varmistamiseksi uskon, että hajautetun koordinointipalvelun käyttö, jolla on vahva johdonmukaisuus, voi ratkaista ongelman paremmin.
Kysymys nousee taas esiin: kuinka pitkäksi aikaa minun pitäisi asettaa viimeinen käyttöaika? Invalidointiajan asettaminen on liian lyhyt, ja lukko vapautetaan automaattisesti ennen metodin suorittamista, jolloin rinnakkaiskytkentäongelmia ilmenee. Jos se kestää liian kauan, muut kierteet, jotka saavat lukon, saattavat joutua odottamaan pitkään.
Tämä ongelma esiintyy myös tietokantojen käytössä hajautettujen lukkojen toteuttamisessa.
Nykyinen yleinen lähestymistapa tähän ongelmaan on asettaa lyhyt aikakatkaisuaika jokaiselle saatulle lukkolle ja aloittaa ketju, jolla lukon aikakatkaisuaika päivitetään aina, kun lukko on juuri saavuttamassa aikakatkaisun. Lopeta tämä ketju samaan aikaan kun avaat lukon. Esimerkiksi redisson, redison virallinen hajautettu lukituskomponentti, käyttää tätä ratkaisua.
Välimuistin käytön edut hajautettujen lukkojen toteuttamisessa Hyvä suoritus.
Välimuistin käytön haitat hajautettujen lukkojen toteuttamisessa Toteutus on liian vastuullista, huomioon otettava liikaa tekijöitä.
Hajautetut lukot Zookeeper-toteutuksen pohjalta
Jaetut lukot perustuen Zookeeperin tilapäisiin solmuihin.
Yleinen ajatus on, että kun jokainen asiakas lukitsee metodin, yksilöllinen hetkellinen järjestetty solmu generoidaan kyseisen solmun hakemistoon, joka vastaa zookeeperin metodia. Lukon saaminen on yksinkertaista, sinun tarvitsee vain määrittää se, jolla on pienin sarjanumero järjestetyssä solmussa. Kun lukko vapautetaan, poista vain välitön solmu. Samaan aikaan se voi välttää palvelun käyttökatkojen aiheuttamat umpikuolleet, joita ei voida vapauttaa.
Katsotaan, pystyykö Zookeeper ratkaisemaan aiemmin mainitut ongelmat.
- Lukko ei aukea? Zookeeperin käyttö ratkaisee tehokkaasti ongelman, että lukkoja ei vapauteta, koska lukkoa luodessa asiakas luo väliaikaisen solmun ZK:ssa, ja kun asiakas saa lukon ja yhtäkkiä irrottaa sen (istuntoyhteys katkeaa), väliaikainen solmu poistetaan automaattisesti. Muut asiakkaat voivat saada lukon uudelleen.
- Ei-tukkeavat lukot? Kun solmu muuttuu, Zookeeper ilmoittaa asiasta asiakkaalle, ja asiakas voi tarkistaa, onko luomansa solmu pienin järjestysnumero kaikista solmuista.
- Et voi palata sisään? Kun asiakas luo solmun, se kirjoittaa suoraan nykyisen asiakkaan isäntä- ja säietiedot solmuun, ja seuraavan kerran kun haluat saada lukon, voit verrata sitä nykyisen pienimmän solmun tietoihin. Jos tiedot ovat samat kuin omasi, voit suoraan hankkia lukon, ja jos se on erilainen, luo väliaikaisen peräkkäisen solmun osallistuaksesi jonoon.
Kysymys nousee jälleen esiin: tiedämme, että Zookeeper täytyy ottaa käyttöön klustereissa, tuleeko datan synkronointiongelmia kuten Redis-klustereita?
Zookeeper on hajautettu komponentti, joka takaa heikon johdonmukaisuuden, eli lopullisen johdonmukaisuuden.
Zookeeper käyttää datan synkronointiprotokollaa nimeltä Quorum Based Protocol. Jos Zookeeper-klusterissa on N Zookeeper-palvelinta (N on yleensä pariton, 3 täyttää datan luotettavuuden ja niillä on korkea luku- ja kirjoitussuorituskyky, ja 5:llä on paras tasapaino datan luotettavuuden ja luku- ja kirjoitussuorituskyvyn välillä), käyttäjän kirjoitustoiminto synkronoidaan ensin N/2 + 1 palvelimelle ja palautetaan käyttäjälle, jolloin käyttäjä kirjoittaa onnistuneesti. Quorum Based Protocoliin perustuva datan synkronointiprotokolla määrittää, kuinka johdonmukaista voimakkuutta Zookeeper voi tukea.
Hajautetussa ympäristössä datan tallennus, joka täyttää vahvan johdonmukaisuuden, on käytännössä olematon, ja se edellyttää, että kaikki solmut päivitetään synkronisesti, kun yhden solmun data päivitetään. Tämä synkronointistrategia esiintyy master-slave-synkronisessa replikaatiotietokannassa. Kuitenkin tällä synkronointistrategialla on liikaa vaikutusta kirjoitussuorituskykyyn ja sitä nähdään harvoin käytännössä. Koska Zookeeper kirjoittaa N/2+1 solmuja synkronisesti, eikä N/2 solmua päivity synkronisesti, Zookeeper ei ole vahvasti johdonmukainen.
Käyttäjän tietojen päivitystoiminto ei takaa, että seuraavat lukemiset lukevat päivitetyn arvon, mutta lopulta se osoittaa johdonmukaisuutta. Johdonmukaisuuden uhraaminen ei tarkoita datan johdonmukaisuuden täydellistä sivuuttamista, muuten data on kaoottista, joten järjestelmän saatavuus tai jakauma olisi kuinka hyvä tahansa, sillä ei ole arvoa. Johdonmukaisuuden uhraaminen tarkoittaa vain sitä, että vahvaa johdonmukaisuutta relaatiotietokannoissa ei enää tarvita, mutta kunhan järjestelmä pystyy lopulta saavuttamaan johdonmukaisuuden.
Yhden pisteen kysymys? Zookeeperin käyttö voi ratkaista tehokkaasti yhden pisteen ongelman, ZK otetaan käyttöön klustereissa, kunhan yli puolet klusterin koneista säilyy, palvelu voidaan tarjota myös ulkomaailmalle.
Oikeudenmukaisuusongelmia? Zookeeperin käyttö voi ratkaista reilujen lukkojen ongelman, sillä ZK:n asiakkaan luomat väliaikaiset solmut ovat järjestelmällisesti, ja aina kun lukko vapautetaan, ZK voi ilmoittaa pienimmälle solmulle, jotta lukko saadaan, varmistaen oikeudenmukaisuuden.
Kysymys nousee jälleen esiin: tiedämme, että Zookeeper täytyy ottaa käyttöön klustereissa, tuleeko datan synkronointiongelmia kuten Redis-klustereita?
Zookeeper on hajautettu komponentti, joka takaa heikon johdonmukaisuuden, eli lopullisen johdonmukaisuuden.
Zookeeper käyttää datan synkronointiprotokollaa nimeltä Quorum Based Protocol. Jos Zookeeper-klusterissa on N Zookeeper-palvelinta (N on yleensä pariton, 3 täyttää datan luotettavuuden ja niillä on korkea luku- ja kirjoitussuorituskyky, ja 5:llä on paras tasapaino datan luotettavuuden ja luku- ja kirjoitussuorituskyvyn välillä), käyttäjän kirjoitustoiminto synkronoidaan ensin N/2 + 1 palvelimelle ja palautetaan käyttäjälle, jolloin käyttäjä kirjoittaa onnistuneesti. Quorum Based Protocoliin perustuva datan synkronointiprotokolla määrittää, kuinka johdonmukaista voimakkuutta Zookeeper voi tukea.
Hajautetussa ympäristössä datan tallennus, joka täyttää vahvan johdonmukaisuuden, on käytännössä olematon, ja se edellyttää, että kaikki solmut päivitetään synkronisesti, kun yhden solmun data päivitetään. Tämä synkronointistrategia esiintyy master-slave-synkronisessa replikaatiotietokannassa. Kuitenkin tällä synkronointistrategialla on liikaa vaikutusta kirjoitussuorituskykyyn ja sitä nähdään harvoin käytännössä. Koska Zookeeper kirjoittaa N/2+1 solmuja synkronisesti, eikä N/2 solmua päivity synkronisesti, Zookeeper ei ole vahvasti johdonmukainen.
Käyttäjän tietojen päivitystoiminto ei takaa, että seuraavat lukemiset lukevat päivitetyn arvon, mutta lopulta se osoittaa johdonmukaisuutta. Johdonmukaisuuden uhraaminen ei tarkoita datan johdonmukaisuuden täydellistä sivuuttamista, muuten data on kaoottista, joten järjestelmän saatavuus tai jakauma olisi kuinka hyvä tahansa, sillä ei ole arvoa. Johdonmukaisuuden uhraaminen tarkoittaa vain sitä, että vahvaa johdonmukaisuutta relaatiotietokannoissa ei enää tarvita, mutta kunhan järjestelmä pystyy lopulta saavuttamaan johdonmukaisuuden.
Se, täyttääkö Zookeeper kausaalisen johdonmukaisuuden, riippuu siitä, miten asiakas on ohjelmoitu.
Käytännöt, jotka eivät täytä kausaalista johdonmukaisuutta
- Prosessi A kirjoittaa datan eläintarhanhoitajan /z-lomakkeeseen ja palauttaa sen onnistuneesti
- Prosessi A ilmoittaa prosessille B, että A on muokannut /z:n dataa
- B lukee eläintarhanhoitajan /z:n tiedot
- Koska eläintarhanhoitajan palvelin, joka on yhdistetty B:hen, ei välttämättä ole päivitetty A:n kirjoitetulla datalla, B ei pysty lukemaan A:n kirjoitettuja tietoja
Käytännöt, jotka vastaavat kausaalista johdonmukaisuutta
- Prosessi B kuuntelee datan muutoksia /z-muodossa Zookeeperissa
- Prosessi A kirjoittaa datan Zookeeperin /z:lle, ja ennen kuin se palautuu onnistuneesti, Zookeeperin täytyy soittaa /z:lle rekisteröityneelle kuuntelijalle, ja johtaja ilmoittaa B:lle datan muutoksesta
- Kun prosessi B:n tapahtumavastemenetelmä on vastattu, se ottaa muuttuneen datan, joten B pystyy varmasti saamaan muuttuneen arvon
- Kausaalinen johdonmukaisuus viittaa tässä johtajan ja B:n väliseen kausaaliseen johdonmukaisuuteen, eli johtaja ilmoittaa datalle muutoksesta
Toinen tapahtumakuuntelumekanismi on myös menetelmä, jota tulisi käyttää Zookeeperin oikeaan ohjelmointiin, jotta Zookeeperin tulisi täyttää kausaalinen johdonmukaisuus
Siksi, kun toteutamme hajautettuja lukkoja Zookeeperin pohjalta, meidän tulisi käyttää käytäntöä kausaalisen johdonmukaisuuden tyydyttämiseksi, eli lukkoa odottavat säikeet kuuntelevat Zookeeperin lukon muutoksia, ja kun lukko vapautetaan, Zookeeper ilmoittaa odottavalle säikeelle, joka täyttää reilut lukitusehdot.
Voit käyttää Zookeeperin kolmannen osapuolen kirjastoasiakasohjelmaa suoraan, joka sisältää reentrant-lukituspalvelun.
ZK:lla toteutetut hajautetut lukot sopivat juuri siihen, mitä odotimme hajautetulta lukolta tämän artikkelin alussa. Kuitenkin näin ei ole, ja Zookeeperin toteuttamalla hajautetun lukon haittapuolelta puuttuu se, että suorituskyky ei välttämättä ole yhtä korkea kuin välimuistipalvelulla. Koska joka kerta lukon luomisen ja vapauttamisen yhteydessä hetkelliset solmut täytyy dynaamisesti luoda ja tuhota, jotta lukkotoiminto toteutuu. Solmujen luominen ja poistaminen ZK:ssa voidaan suorittaa vain johtajapalvelimen kautta, minkä jälkeen data jaetaan kaikille seuraajakoneille.
Zookeeperin käytön edut hajautettujen lukkojen toteuttamiseen Ratkaise tehokkaasti yksittäisen pisteen ongelmat, ei-paluu-ongelmat, ei-estymisongelmat sekä lukon irrottamisen epäonnistumisen. Sen toteuttaminen on suhteellisen helppoa.
Zookeeperin haitat hajautettujen lukkojen toteuttamisessa Suorituskyky ei ole yhtä hyvä kuin välimuistin käyttö hajautettujen lukkojen toteuttamiseen. ZK:n periaatteiden ymmärtäminen on välttämätöntä.
Kolmen vaihtoehdon vertailu
Ymmärryksen helppouden näkökulmasta (matalasta korkeaan) Tietokanta > välimuisti > eläintarhanhoitaja
Toteutuksen monimutkaisuuden näkökulmasta (matalasta korkeaan) Zookeeper > välimuisti > tietokannat
Suorituskyvyn näkökulmasta (korkeasta matalaan) Välimuisti > Zookeeper >= tietokanta
Luotettavuuden näkökulmasta (korkeasta matalaan) Zookeeper > välimuisti > tietokannat
|