NewSQL = NoSQL+ACID

NewSQL = NoSQL+ACID
Duela gutxi arte, Odnoklassnikik denbora errealean prozesatutako 50 TB datu inguru gordetzen zituen SQL Server-en. Bolumen hori lortzeko, ia ezinezkoa da SQL DBMS erabiliz sarbide azkarra eta fidagarria, eta baita datu-zentroa hutsegitearekiko tolerantzia ere. Normalean, kasu horietan, NoSQL biltegietako bat erabiltzen da, baina dena ezin da NoSQLra transferitu: entitate batzuek ACID transakzio-bermeak behar dituzte.

Honek NewSQL biltegiratzea erabiltzera eraman gintuen, hau da, akatsen tolerantzia, eskalagarritasuna eta NoSQL sistemen errendimendua eskaintzen duen DBMS bat, baina aldi berean sistema klasikoek ezagutzen dituzten ACID bermeak mantenduz. Klase berri honetako industria-sistema gutxi funtzionatzen dute, beraz, sistema hori guk geuk inplementatu genuen eta merkataritza-funtzionamenduan jarri genuen.

Nola funtzionatzen duen eta zer gertatu den - irakurri ebakiaren azpian.

Gaur egun, Odnoklassnikiren hileroko audientzia 70 milioi bisitari bakar baino gehiagokoa da. Guk Lehen bosten artean gaude munduko sare sozial handienak, eta erabiltzaileek denbora gehien ematen duten hogei guneen artean. OK azpiegiturak karga oso altuak kudeatzen ditu: milioi bat HTTP eskaera/seg baino gehiago fronte bakoitzeko. 8000 pieza baino gehiagoko zerbitzari-flota baten zatiak elkarrengandik hurbil daude - Moskuko lau datu-zentrotan, eta horrek sarearen latentzia 1 ms baino gutxiagoko tartea ahalbidetzen du.

Cassandra 2010etik ari gara erabiltzen, 0.6 bertsiotik hasita. Gaur egun, hainbat dozena kluster daude martxan. Kluster azkarrenak 4 milioi eragiketa baino gehiago prozesatzen ditu segundoko, eta handienak 260 TB gordetzen ditu.

Hala ere, horiek guztiak biltegiratzeko erabiltzen diren NoSQL kluster arruntak dira ahul koordinatuta datuak. Biltegiratze koherente nagusia ordezkatu nahi genuen, Microsoft SQL Server, Odnoklassniki sortu zenetik erabiltzen dena. Biltegiratzea SQL Server Standard Edition 300 makina baino gehiagok osatzen zuten, 50 TB datu zituzten - negozio-entitateak. Datu hauek ACID transakzioen zati gisa aldatzen dira eta eskatzen du koherentzia handia.

Datuak SQL Server nodoetan banatzeko, bertikalak eta horizontalak erabili ditugu zatiketa (zatiketa). Historikoki, datuen zatiketa eskema sinple bat erabili dugu: entitate bakoitza token batekin lotuta zegoen, entitatearen IDaren funtzioa. Token bera zuten entitateak SQL zerbitzari berean jarri ziren. Maisu-xehetasun erlazioa inplementatu zen, erregistro nagusien eta seme-alaben tokenak beti bat etor zedin eta zerbitzari berean kokatu ziren. Sare sozial batean, ia erregistro guztiak erabiltzailearen izenean sortzen dira, hau da, azpisistema funtzional bateko erabiltzailearen datu guztiak zerbitzari batean gordetzen dira. Hau da, negozio-transakzio batek ia beti SQL zerbitzari bateko taulak hartzen zituen parte, eta horri esker datuen koherentzia bermatu ahal izan zen ACID tokiko transakzioak erabiliz, erabili beharrik gabe. motela eta fidagarria banatutako ACID transakzioak.

Partekatzeari eta SQL bizkortzeari esker:

  • Ez dugu atzerriko gakoen mugak erabiltzen, zatikatzean entitatearen IDa beste zerbitzari batean egon daitekeelako.
  • Ez ditugu gordetako prozedurak eta abiarazleak erabiltzen DBMS CPUaren karga gehigarria dela eta.
  • Ez dugu JOIN-ak erabiltzen aurreko guztiagatik eta diskotik ausazko irakurketa askogatik.
  • Transakzio batetik kanpo, Read Uncommitted isolamendu-maila erabiltzen dugu blokeoak murrizteko.
  • Transakzio laburrak baino ez ditugu egiten (batez beste 100 ms baino laburragoak).
  • Ez dugu errenkada anitzeko UPDATE eta DELETE erabiltzen blokeo kopuru handia dela eta - aldi berean erregistro bakarra eguneratzen dugu.
  • Kontsultak indizeetan bakarrik egiten ditugu beti - taula osoa aztertzeko plan bat duen kontsulta batek datu-basea gainkargatzea eta huts egitea dakar.

Urrats hauek SQL zerbitzarietatik ia errendimendu maximoa ateratzeko aukera eman ziguten. Hala ere, arazoak gero eta ugariagoak ziren. Ikus ditzagun.

SQLrekin arazoak

  • Norberak idatzitako zatiketa erabiltzen genuenez, zati berriak gehitzea eskuz egin zuten administratzaileek. Denbora honetan guztian, datu-erreplika eskalagarriak ez ziren eskaerak betetzen.
  • Taulan erregistro-kopurua hazi ahala, txertatzeko eta aldatzeko abiadura gutxitzen da; lehendik dagoen taula batean indizeak gehitzean, abiadura faktore bat jaisten da; indizeak sortzea eta birsortzea geldialdiarekin gertatzen da.
  • Produkzioan SQL Server-erako Windows kopuru txiki bat izateak azpiegituren kudeaketa zaila egiten du

Baina arazo nagusia da

akatsen tolerantzia

SQL zerbitzari klasikoak akatsen tolerantzia eskasa du. Demagun datu-base zerbitzari bakarra duzula eta hiru urtean behin huts egiten duela. Denbora horretan gunea 20 minutuz gelditzen da, eta hori onargarria da. 64 zerbitzari badituzu, gunea hiru astean behin gelditzen da. Eta 200 zerbitzari badituzu, webguneak ez du astero funtzionatzen. Hau arazoa da.

Zer egin daiteke SQL zerbitzari baten akatsen tolerantzia hobetzeko? Wikipediak eraikitzera gonbidatzen gaitu oso eskuragarri dagoen klusterra: osagairen batek huts egiten badu babeskopia bat dagoen.

Horretarako ekipamendu garestien flota bat behar da: bikoiztasun ugari, zuntz optikoa, biltegiratze partekatua eta erreserba bat sartzeak ez du funtzionatzen fidagarri: aldaketen % 10 inguru nodo nagusiaren atzean dagoen tren baten moduan amaitzen da segurtasun-nodoaren porrotarekin.

Baina eskuragarritasun handiko kluster horren desabantaila nagusia zero erabilgarritasuna da, kokatuta dagoen datu-zentroak huts egiten badu. Odnoklassnikik lau datu-zentro ditu, eta horietako batean erabateko hutsegiterik gertatuz gero funtzionamendua ziurtatu behar dugu.

Horretarako erabil genezake Multi-Master SQL zerbitzarian eraikitako erreplikazioa. Irtenbide hau askoz garestiagoa da softwarearen kostuagatik eta erreplikaren arazo ezagunak jasaten ditu: ezusteko transakzio-atzerapenak erreplikazio sinkronoarekin eta erreplikazioak aplikatzeko atzerapenak (eta, ondorioz, aldaketa galduak) erreplikazio asinkronoarekin. Inplizitua gatazken eskuzko ebazpena aukera hau guztiz aplikaezina egiten digu.

Arazo horiek guztiek erradikala konponbidea behar zuten, eta zehatz-mehatz aztertzen hasi ginen. Hemen SQL Server zerbitzariak batez ere zer egiten duen ezagutu behar dugu: transakzioak.

Transakzio sinplea

Har dezagun transakziorik errazena, aplikatutako SQL programatzaile baten ikuspuntutik: album bati argazki bat gehitzea. Albumak eta argazkiak plaka ezberdinetan gordetzen dira. Albumak argazkien kontagailu publikoa du. Ondoren, transakzio hori urrats hauetan banatzen da:

  1. Albuma teklaz blokeatzen dugu.
  2. Sortu sarrera bat argazki-taulan.
  3. Argazkiak egoera publikoa badu, gehitu argazki-kontagailu publiko bat albumean, eguneratu erregistroa eta egin transakzioa.

Edo pseudokodean:

TX.start("Albums", id);
Album album = albums.lock(id);
Photo photo = photos.create(…);

if (photo.status == PUBLIC ) {
    album.incPublicPhotosCount();
}
album.update();

TX.commit();

Ikusten dugu negozio-transakzio baterako agertokirik ohikoena datu-baseko datuak aplikazioen zerbitzariaren memorian irakurtzea, zerbait aldatzea eta balio berriak datu-basean gordetzea dela. Normalean, horrelako transakzio batean hainbat entitate, hainbat taula eguneratzen ditugu.

Transakzio bat exekutatzen denean, beste sistema bateko datu berdinen aldaketa aldi berean gerta daiteke. Adibidez, Antispam-ek erabaki dezake erabiltzailea nolabait susmagarria dela eta, beraz, erabiltzailearen argazki guztiak ez direla publikoak izan behar, moderaziorako bidali behar dira, hau da, photo.status beste balio batera aldatzea eta dagozkion kontagailuak itzaltzea. Jakina, eragiketa hau aplikazioaren atomizazioaren bermerik gabe eta aldaketa lehiakideen isolamendurik gabe gertatzen bada, adibidez. ACID, orduan emaitza ez da behar dena izango - argazki-kontagailuak balio okerra erakutsiko du edo argazki guztiak ez dira moderaziora bidaliko.

Antzeko kode asko, transakzio bakarrean hainbat negozio-entitate manipulatuz, idatzi dira Odnoklassnikiren existentzia osoan. NoSQL-ra migrazioen esperientzian oinarrituta Behin-behineko koherentzia Badakigu erronkarik handiena (eta denbora-inbertsioa) kodea garatzetik datorrela datuen koherentzia mantentzeko. Hori dela eta, biltegiratze berriaren baldintza nagusia ACID transakzio errealetarako hornikuntza izan behar dugu aplikazio logikarako.

Beste baldintza batzuk, ez hain garrantzitsuak, hauek izan ziren:

  • Datu-zentroak huts egiten badu, biltegiratze berrian irakurtzeko eta idazteko erabilgarri egon behar dira.
  • Gaur egungo garapen-abiadura mantentzea. Hau da, biltegi berri batekin lan egiten denean, kode kopurua gutxi gorabehera berdina izan behar da; ez da beharrezkoa izango biltegiari ezer gehitu, gatazkak konpontzeko algoritmoak garatu, bigarren indizeak mantentzea, etab.
  • Biltegiratze berriaren abiadura nahiko altua izan behar zen, bai datuak irakurtzerakoan, bai transakzioak prozesatzeko orduan, eta horrek eraginkortasunez esan nahi zuen irtenbide akademiko zorrotzak, unibertsalak, baina geldoak, adibidez, ez zirela aplikagarriak. bi faseko konpromisoak.
  • Alanean eskalatze automatikoa.
  • Ohiko zerbitzari merkeak erabiliz, hardware exotikoa erosi beharrik gabe.
  • Enpresa garatzaileek biltegiratzea garatzeko aukera. Beste era batera esanda, jabedun edo kode irekiko soluzioei eman zitzaien lehentasuna, hobe Javan.

Erabakiak, erabakiak

Irtenbide posibleak aztertuta, bi arkitektura aukeratara iritsi ginen:

Lehenengoa edozein SQL zerbitzaria hartu eta beharrezko akatsen tolerantzia, eskalatze mekanismoa, hutsegite-klusterra, gatazkak konpontzea eta ACID transakzio banatuak, fidagarriak eta azkarrak ezartzea da. Aukera hau oso ez-hutsala eta lan intentsiboa dela baloratu dugu.

Bigarren aukera prest dagoen NoSQL biltegiratze bat hartzea da inplementatutako eskalatzearekin, hutsegite-kluster batekin, gatazkak konpontzea eta transakzioak eta SQL zeure burua ezartzea. Lehen begiratuan, SQL ezartzeko zeregina ere, ACID transakzioak ahaztu gabe, urteak beharko dituen zeregina dirudi. Baina orduan konturatu ginen praktikan erabiltzen dugun SQL ezaugarri multzoa ANSI SQLtik bezain urrun dagoela Cassandra CQL ANSI SQLtik urrun. CQL are gehiago begiratuta, behar genuenetik nahiko gertu zegoela konturatu ginen.

Cassandra eta CQL

Beraz, zer da interesgarria Cassandrak, zer gaitasun ditu?

Lehenik eta behin, hemen hainbat datu mota onartzen dituzten taulak sor ditzakezu; SELECT edo UPDATE egin dezakezu gako nagusian.

CREATE TABLE photos (id bigint KEY, owner bigint,…);
SELECT * FROM photos WHERE id=?;
UPDATE photos SET … WHERE id=?;

Erreplika datuen koherentzia bermatzeko, Cassandra-k erabiltzen du quorum planteamendua. Kasurik errazenean, horrek esan nahi du errenkada bereko hiru erreplika klusterreko nodo ezberdinetan jartzen direnean, idazketa arrakastatsutzat jotzen dela, nodo gehienek (hau da, hirutik bik) idazketa-eragiketa honen arrakasta baieztatzen badute. . Errenkadako datuak koherentetzat jotzen dira, irakurtzerakoan, nodo gehienek galdeketa egin eta baieztatzen badute. Horrela, hiru erreplikekin, datuen koherentzia osoa eta berehalakoa bermatzen da nodo batek huts egiten badu. Planteamendu horri esker, are fidagarriagoa den eskema bat inplementatu genuen: beti eskaerak bidali hiru errepliketara, bi azkarrenen erantzunaren zain. Hirugarren erreplikaren erantzun berantiarra baztertu egiten da kasu honetan. Erantzuten berandu iristen den nodo batek arazo larriak izan ditzake: balaztak, zabor bilketa JVMn, memoria zuzena Linux nukleoan berreskuratzea, hardware-akatsa, saretik deskonektatzea. Hala ere, horrek ez die inola ere eragiten bezeroaren eragiketei edo datuei.

Hiru nodo harremanetan jartzen garenean eta biren erantzuna jasotzen dugunean planteamendua deitzen da espekulazioa: erreplika gehigarrien eskaera "erortu" baino lehen ere bidaltzen da.

Cassandra-ren beste abantaila bat Batchlog da, egiten dituzun aldaketa sorta bat guztiz aplikatzen dela edo batere aplikatzen ez dela ziurtatzen duen mekanismoa. Horri esker, A azidoan ebatzi dezakegu - atomitatea kutxatik kanpo.

Cassandra-ko transakzioetatik hurbilena " deiturikoak diratransakzio arinak". Baina "benetako" ACID transakzioetatik urrun daude: izan ere, hau egiteko aukera da CAS erregistro bakarreko datuetan, adostasuna erabiliz, pisu astuneko Paxos protokoloa erabiliz. Hori dela eta, transakzio horien abiadura baxua da.

Cassandran faltan geundena

Beraz, benetako ACID transakzioak ezarri behar izan genituen Cassandran. Hori erabiliz, erraz inplementa genitzake DBMS klasikoko beste bi ezaugarri eroso: indize azkarrak koherenteak, lehen gakoaren bidez ez ezik datu-hautaketak egiteko aukera emango ligukeena, eta auto-inkrementatzaile monotonikoen sorgailu arrunta.

C*Bat

Horrela DBMS berri bat sortu zen C*Bat, hiru zerbitzari-nodo motaz osatua:

  • Biltegiratzea - ​​(ia) Cassandra zerbitzari estandarrak tokiko diskoetan datuak gordetzeaz arduratzen direnak. Datuen karga eta bolumena hazi ahala, haien kantitatea erraz eskalatu daiteke hamarnaka eta ehunkaetara.
  • Transakzio-koordinatzaileak - transakzioen exekuzioa ziurtatzea.
  • Bezeroak negozio-eragiketak inplementatzen dituzten eta transakzioak hasten dituzten aplikazio-zerbitzariak dira. Horrelako milaka bezero egon daitezke.

NewSQL = NoSQL+ACID

Mota guztietako zerbitzariak kluster komun baten parte dira, Cassandra barneko mezuen protokoloa erabiltzen dute elkarren artean komunikatzeko eta esamesak kluster informazioa trukatzeko. Heartbeat-ekin, zerbitzariek elkarrekiko hutsegiteei buruz ikasten dute, datu-eskema bakarra mantentzen dute: taulak, haien egitura eta erreplikazioa; partizio-eskema, kluster topologia, etab.

Bezeroak

NewSQL = NoSQL+ACID

Gidari estandarren ordez, Fat Client modua erabiltzen da. Halako nodo batek ez ditu daturik gordetzen, baina eskaerak gauzatzeko koordinatzaile gisa jardun dezake, hau da, Bezeroak berak bere eskaeren koordinatzaile gisa jokatzen du: biltegiratze-erreplikak kontsultatzen ditu eta gatazkak konpontzen ditu. Hau ez da soilik kontrolatzaile estandarra baino fidagarriagoa eta azkarragoa, urruneko koordinatzaile batekin komunikatzea eskatzen duena, baina eskaeren transmisioa kontrolatzeko aukera ere ematen du. Bezeroari irekitako transakzio batetik kanpo, eskaerak biltegietara bidaltzen dira. Bezeroak transakzio bat ireki badu, transakzioko eskaera guztiak transakzio-koordinatzaileari bidaltzen zaizkio.
NewSQL = NoSQL+ACID

C*One Transakzio Koordinatzailea

Koordinatzailea C*One hutsetik inplementatu genuen zerbait da. Transakzioak, blokeoak eta transakzioak aplikatzen diren ordena kudeatzeaz arduratzen da.

Zerbitzua emandako transakzio bakoitzeko, koordinatzaileak denbora-zigilu bat sortzen du: ondorengo transakzio bakoitza aurreko transakzioa baino handiagoa da. Cassandraren gatazkak konpontzeko sistema denbora-zigiluetan oinarritzen denez (bi erregistro gatazkatsuetakoa, azken denbora-zigilua duena egungotzat hartzen da), gatazka beti konponduko da ondorengo transakzioaren alde. Horrela ezarri genuen Lampport erlojua - sistema banatu batean gatazkak konpontzeko modu merkea.

Sarrailak

Isolamendua bermatzeko, metodorik errazena erabiltzea erabaki dugu: erregistroaren lehen gakoan oinarritutako blokeo ezkor. Beste era batera esanda, transakzio batean, erregistro bat blokeatu behar da lehenik, gero irakurri, aldatu eta gorde. Konpromiso arrakastatsu baten ondoren bakarrik desblokeatu daiteke erregistro bat, lehiakide diren transakzioek erabil dezaten.

Blokeo hori ezartzea erraza da banatu gabeko ingurune batean. Banatutako sistema batean, bi aukera nagusi daude: edo blokeo banatua ezartzea klusterrean, edo transakzioak banatu, erregistro bera duten transakzioak beti koordinatzaile berberak artatu ditzan.

Gure kasuan datuak dagoeneko SQL-n tokiko transakzio taldeen artean banatzen direnez, tokiko transakzio-taldeak koordinatzaileei esleitzea erabaki zen: koordinatzaile batek 0tik 9rako tokenekin egiten ditu transakzio guztiak, bigarrenak 10etik 19rako tokenekin, eta abar. Ondorioz, koordinatzaile-instantzia bakoitza transakzio-taldearen maisu bihurtzen da.

Ondoren, blokeoak HashMap hutsal baten moduan inplementa daitezke koordinatzailearen memorian.

Koordinatzailearen hutsegiteak

Koordinatzaile batek esklusiboki transakzio talde bat zerbitzatzen duenez, oso garrantzitsua da porrotaren egia azkar zehaztea, transakzioa exekutatzeko bigarren saiakerak denbora iraun dezan. Hau azkarra eta fidagarria izan dadin, guztiz konektatutako quorum hearbeat protokoloa erabili dugu:

Datu-zentro bakoitzak gutxienez bi koordinatzaile-nodo ditu. Aldian-aldian, koordinatzaile bakoitzak beste koordinatzaileei bidaltzen die taupada-mezu bat eta bere funtzionamenduaren berri ematen die, baita azken aldiz klusterreko zein koordinatzailerengandik jaso dituen zein taupadetako mezuak ere.

NewSQL = NoSQL+ACID

Besteengandik antzeko informazioa jasoz euren taupadetako mezuen zati gisa, koordinatzaile bakoitzak bere kabuz erabakitzen du zein kluster-nodo funtzionatzen duten eta zein ez, quorum printzipioak gidatuta: X nodoak klusterreko nodo gehienetatik informazioa jaso badu normalari buruz. Y nodotik mezuak jasotzea, gero, Y funtzionatzen du. Eta alderantziz, gehiengoak Y nodoko mezuak falta direla jakinarazi bezain laster, orduan Y-k ezezkoa eman du. Bitxia da quorumak X nodoari jadanik ez duela bertatik mezurik jasotzen jakinarazten badio, X nodoak berak huts egin duela kontsideratuko duela.

Bihotz-taupadak maiztasun handiz bidaltzen dira, segundoko 20 bat aldiz, 50 ms-ko epearekin. Javan, zaila da aplikazioen erantzuna bermatzea 50 ms-ko epean, zabor-biltzaileak eragindako etenaldien luzera konparagarria dela eta. Erantzun-denbora hori G1 zabor-biltzailea erabiliz lortu ahal izan dugu, GC etenaldien iraupenerako helburu bat zehazteko aukera ematen diguna. Hala ere, batzuetan, oso gutxitan, kolektoreak etenaldiak 50 ms gainditzen ditu, eta horrek akats faltsuak hautematea ekar dezake. Hori gerta ez dadin, koordinatzaileak ez du urruneko nodoaren hutsegite baten berri ematen bertatik datorren lehen taupadaren mezua desagertzen denean, jarraian hainbat desagertu badira bakarrik.Horrela lortu dugu koordinatzailearen nodoaren hutsegitea detektatzea 200. urtean. anderea.

Baina ez da nahikoa zein nodo funtzionatzeari utzi dion azkar ulertzea. Honen aurrean zerbait egin behar dugu.

Erreserba

Eskema klasikoak, master hutsegite bat gertatuz gero, hauteskunde berri bat hastea dakar hauetako bat erabiliz modan unibertsala algoritmoak. Hala ere, halako algoritmoek arazo ezagunak dituzte denboraren konbergentziarekin eta hauteskunde prozesuaren beraren iraupenarekin. Atzerapen gehigarriak saihestu ahal izan ditugu guztiz konektatutako sare batean koordinatzaileen ordezko eskema bat erabiliz:

NewSQL = NoSQL+ACID

Demagun 50. taldeko transakzio bat exekutatu nahi dugula. Zehaztu dezagun aldez aurretik ordezkapen-eskema, hau da, zein nodok exekutuko dituzten 50 taldeko transakzioak koordinatzaile nagusiaren hutsegite kasuan. Gure helburua sistemaren funtzionaltasuna mantentzea da, datu-zentroko hutsegite bat gertatuz gero. Zehaz dezagun lehen erreserba beste datu-zentro bateko nodo bat izango dela eta bigarren erreserba hirugarren bateko nodo bat izango dela. Eskema hau behin hautatzen da eta ez da aldatzen klusterraren topologia aldatu arte, hau da, nodo berriak sartzen diren arte (oso gutxitan gertatzen da hori). Nagusi aktibo berria hautatzeko prozedura zaharrak huts egiten badu beti hau izango da: lehen erreserba maisu aktibo bihurtuko da, eta funtzionatzeari utzi badio, bigarren erreserba maisu aktibo bihurtuko da.

Eskema hau algoritmo unibertsala baino fidagarriagoa da, maisu berri bat aktibatzeko nahikoa baita zaharraren porrota zehaztea.

Baina nola ulertuko dute bezeroek zein maisu ari den lanean orain? Ezinezkoa da milaka bezerori informazioa bidaltzea 50 ms-tan. Egoera bat posible da bezero batek transakzio bat irekitzeko eskaera bidaltzen duenean, oraindik maisu honek funtzionatzen ez duela jakin gabe, eta eskaerak denbora-muga amaituko du. Hori gerta ez dadin, bezeroek espekulatiboki bidaltzen diote transakzio bat irekitzeko eskaera talde-maisuari eta bere bi erreserbei aldi berean, baina momentu honetan aktibo dagoen maisua denak bakarrik erantzungo dio eskaera horri. Bezeroak transakzioaren barruan ondorengo komunikazio guztiak egingo ditu maisu aktiboarekin soilik.

Babeskopia-maisuek eurenak ez diren transakzioen jasotako eskaerak jaio gabeko transakzioen ilaran jartzen dituzte, non denbora batez gordetzen diren. Maisu aktiboa hiltzen bada, maisu berriak transakzioak irekitzeko eskaerak prozesatzen ditu bere ilaratik eta bezeroari erantzuten dio. Bezeroak dagoeneko transakzio bat ireki badu maisu zaharrarekin, bigarren erantzuna ez da aintzat hartuko (eta, jakina, transakzio hori ez da amaituko eta bezeroak errepikatuko du).

Transakzioak nola funtzionatzen duen

Demagun bezero batek koordinatzaileari halako eta halako gako nagusi batekin transakzio bat irekitzeko eskaera bat igorri diola. Koordinatzaileak entitate hau blokeatzen du eta memoriako blokeo-taulan jartzen du. Beharrezkoa bada, koordinatzaileak entitate hau biltegitik irakurtzen du eta ondoriozko datuak transakzio egoera batean gordetzen ditu koordinatzailearen memorian.

NewSQL = NoSQL+ACID

Bezero batek transakzio batean datuak aldatu nahi dituenean, koordinatzaileari eskaera bat bidaltzen dio entitatea alda dezan, eta koordinatzaileak datu berriak transakzio-egoera taulan jartzen ditu memorian. Honek grabaketa amaitzen du; ez da grabaziorik egiten biltegian.

NewSQL = NoSQL+ACID

Bezero batek bere aldatutako datuak eskatzen dituenean transakzio aktibo baten barruan, koordinatzaileak honela jokatzen du:

  • IDa dagoeneko transakzioan badago, orduan datuak memoriatik hartzen dira;
  • IDa memorian ez badago, falta diren datuak biltegiratze-nodoetatik irakurtzen dira, dagoeneko memorian daudenekin konbinatuta, eta emaitza bezeroari ematen zaio.

Horrela, bezeroak bere aldaketak irakur ditzake, baina beste bezeroek ez dituzte aldaketa horiek ikusten, koordinatzailearen memorian soilik gordetzen direlako; oraindik ez daude Cassandra nodoetan.

NewSQL = NoSQL+ACID

Bezeroak konpromisoa bidaltzen duenean, zerbitzuaren memorian zegoen egoera koordinatzaileak erregistratutako lote batean gordetzen du, eta erregistratutako lote gisa bidaltzen du Cassandra biltegira. Dendak beharrezko guztia egiten dute pakete hau atomikoki (erabat) aplikatzen dela ziurtatzeko, eta erantzun bat itzultzen diote koordinatzaileari, hark blokeoak askatu eta transakzioaren arrakasta berresten dio bezeroari.

NewSQL = NoSQL+ACID

Eta atzera egiteko, koordinatzaileak transakzio-egoerak okupatutako memoria askatu besterik ez du behar.

Aurreko hobekuntzen ondorioz, ACID printzipioak ezarri ditugu:

  • Atomikotasuna. Hau bermea da sisteman ez dela transakzio partzialki erregistratuko; bere azpieragiketa guztiak burutuko dira, edo bat ere ez da burutuko. Printzipio honi atxikitzen diogu Cassandra-n erregistratutako lotearen bidez.
  • Koherentzia. Transakzio arrakastatsu bakoitzak, definizioz, baliozko emaitzak soilik erregistratzen ditu. Transakzio bat ireki eta eragiketen zati bat egin ondoren emaitza baliogabea dela antzematen bada, itzulera bat egiten da.
  • Isolatze. Transakzio bat exekutatzen denean, aldibereko transakzioek ez dute eraginik izan behar haren emaitza. Lehiakide diren transakzioak koordinatzailearen blokeo ezkorrak erabiliz isolatzen dira. Transakzio batetik kanpoko irakurketetarako, isolamendu-printzipioa Read Committed mailan betetzen da.
  • egonkortasuna. Beheko mailetan dauden arazoak (sistema itzaltzea, hardwarearen hutsegitea) gorabehera, arrakastaz burututako transakzio batek egindako aldaketak mantendu egin beharko lirateke eragiketak berriro hasten direnean.

Aurkibideen bidez irakurtzea

Har dezagun taula sinple bat:

CREATE TABLE photos (
id bigint primary key,
owner bigint,
modified timestamp,
…)

ID (gako nagusia), jabea eta aldaketa data ditu. Oso eskaera sinplea egin behar duzu - hautatu jabearen datuak "azken egunerako" aldaketa-datarekin.

SELECT *
WHERE owner=?
AND modified>?

Kontsulta hori azkar prozesatu ahal izateko, SQL DBMS klasiko batean zutabeen araberako indize bat eraiki behar duzu (jabea, aldatua). Hori nahiko erraz egin dezakegu, orain ACID bermeak ditugu eta!

Indizeak C*One-n

Iturburu-taula bat dago argazkiekin, non erregistroaren IDa gako nagusia den.

NewSQL = NoSQL+ACID

Indize baterako, C*One-k jatorrizkoaren kopia den taula berri bat sortzen du. Gakoa indizearen adierazpenaren berdina da, eta iturburu-taularen erregistroaren gako nagusia ere barne hartzen du:

NewSQL = NoSQL+ACID

Orain "azken eguneko jabea"-ren kontsulta beste taula bateko hautapen gisa berridatzi daiteke:

SELECT * FROM i1_test
WHERE owner=?
AND modified>?

Koordinatzaileak automatikoki mantentzen du iturburu-taularen argazkien eta indize-taularen i1 datuen koherentzia. Datu-eskeman soilik oinarrituta, aldaketa bat jasotzen denean, koordinatzaileak aldaketa bat sortu eta gordetzen du taula nagusian ez ezik, kopietan ere. Ez da ekintza gehigarririk egiten indize-taulan, ez dira erregistroak irakurtzen eta ez da blokeorik erabiltzen. Hau da, indizeak gehitzeak ez du ia baliabiderik kontsumitzen eta ia ez du eraginik aldaketak aplikatzeko abiaduran.

ACID erabiliz, SQL antzeko indizeak ezarri ahal izan ditugu. Koherenteak, eskalagarriak, azkarrak, konposagarriak eta CQL kontsulta-lengoaian integratuta daude. Ez da beharrezkoa aplikazioaren kodean aldaketarik indizeak onartzeko. Dena SQL-n bezain erraza da. Eta garrantzitsuena, indizeek ez diote eragiten jatorrizko transakzio-taulari egindako aldaketen exekuzio-abiadurari.

Zer gertatu zen

Duela hiru urte C*One garatu genuen eta merkataritza-funtzionamenduan jarri genuen martxan.

Zer lortu dugu azkenean? Ebaluatu dezagun argazkien prozesatzeko eta biltegiratzeko azpisistemaren adibidea erabiliz, sare sozial bateko datu-mota garrantzitsuenetako bat. Ez gara argazkien gorputzez hitz egiten, era guztietako metainformazioez baizik. Orain Odnoklassnikik 20 milioi erregistro inguru ditu, sistemak segundoko 80 mila irakurketa-eskaera prozesatzen ditu, datuen aldaketarekin lotutako 8 mila ACID transakzio segundoko.

SQL erreplikazio-faktorea = 1 erabiltzen dugunean (baina RAID 10ean), argazkiaren metainformazioa Microsoft SQL Server exekutatzen duten 32 makina oso erabilgarriko kluster batean gorde zen (gehi 11 babeskopiak). 10 zerbitzari ere esleitu ziren babeskopiak gordetzeko. Guztira 50 auto garesti. Aldi berean, sistemak karga nominalean funtzionatzen zuen, erreserbarik gabe.

Sistema berrira migratu ondoren, erreplikazio-faktorea = 3 jaso genuen - kopia bat datu-zentro bakoitzean. Sistemak Cassandra biltegiratze-nodok eta 63 koordinatzaile-makinak osatzen dute, guztira 6 zerbitzari. Baina makina hauek askoz merkeagoak dira, haien kostu osoa SQL sistema baten kostuaren %69 ingurukoa da. Aldi berean, karga %30ean mantentzen da.

C*One sartzearekin batera, latentzia ere gutxitu egin zen: SQLn, idazketa eragiketa batek 4,5 ms inguru behar zituen. C*One-n - 1,6 ms inguru. Transakzioaren iraupena 40 ms baino gutxiagokoa da batez beste, konpromezua 2 ms-tan amaitzen da, irakurtzeko eta idazteko iraupena batez beste 2 ms-koa da. 99. pertzentilea - 3-3,1 ms bakarrik, denbora-muga kopurua 100 aldiz murriztu da - hori guztia espekulazioaren erabilera hedatuagatik.

Oraingoz, SQL Server nodo gehienak deskargatu egin dira; produktu berriak C*One erabiliz soilik garatzen ari dira. C*One egokitu dugu gure hodeian lan egiteko hodei bakarrekoa, kluster berrien hedapena bizkortu, konfigurazioa erraztu eta funtzionamendua automatizatzea ahalbidetu zuen. Iturburu-koderik gabe, hori egitea askoz zailagoa eta astunagoa izango litzateke.

Orain gure beste biltegiratze instalazioak hodeira transferitzen ari gara, baina hori guztiz bestelakoa da.

Iturria: www.habr.com

Gehitu iruzkin berria