NewSQL = NoSQL+ACID

NewSQL = NoSQL+ACID
Bis viru kuerzem huet Odnoklassniki ongeféier 50 TB vun Daten gespäichert, déi an Echtzäit am SQL Server veraarbecht ginn. Fir sou e Volume ass et bal onméiglech fir séier an zouverlässeg, a souguer Datenzenter Feeler-tolerant Zougang mat engem SQL DBMS ze bidden. Typesch, an esou Fäll gëtt ee vun den NoSQL-Späichere benotzt, awer net alles kann op NoSQL transferéiert ginn: e puer Entitéite verlaangen ACID Transaktiounsgarantien.

Dëst huet eis zum Gebrauch vun NewSQL-Speicher gefouert, dat heescht e DBMS, deen Fehltoleranz, Skalierbarkeet a Leeschtung vun NoSQL Systemer ubitt, awer gläichzäiteg d'ACID Garantien erhalen, déi mat klassesche Systemer vertraut sinn. Et gi wéineg industriell Systemer vun dëser neier Klass, also hu mir esou e System selwer ëmgesat an a kommerziell Operatioun gesat.

Wéi et funktionnéiert a wat geschitt ass - liest ënnert dem Schnëtt.

Haut ass de monatlecht Publikum vun Odnoklassniki méi wéi 70 Milliounen eenzegaarteg Visiteuren. Mir Mir sinn an den Top fënnef gréisste sozialen Netzwierker op der Welt, an ënnert den zwanzeg Siten op déi Benotzer déi meescht Zäit verbréngen. D'OK Infrastruktur handhabt ganz héich Lasten: méi wéi eng Millioun HTTP-Ufroen / sec pro Front. Deeler vun enger Serverflott vu méi wéi 8000 Stécker sinn no beieneen lokaliséiert - a véier Moskauer Datenzenteren, wat et méiglech mécht eng Netzlatenz vu manner wéi 1 ms tëscht hinnen ze garantéieren.

Mir hunn Cassandra zënter 2010 benotzt, ugefaange mat der Versioun 0.6. Haut ginn et e puer Dosen Cluster a Betrib. De schnellsten Cluster veraarbecht méi wéi 4 Milliounen Operatiounen pro Sekonn, an de gréisste späichert 260 TB.

Wéi och ëmmer, dëst sinn all gewéinlech NoSQL Cluster déi fir d'Späichere benotzt ginn schwaach koordinéiert daten. Mir wollten d'Haaptkonsequent Späichere ersetzen, Microsoft SQL Server, deen zënter der Grënnung vun Odnoklassniki benotzt gouf. D'Späichere besteet aus méi wéi 300 SQL Server Standard Edition Maschinnen, déi 50 TB vun Daten enthalen hunn - Geschäftsentitéiten. Dës Donnéeë ginn als Deel vun ACID Transaktiounen geännert an erfuerderlech héich Konsequenz.

Fir Daten iwwer SQL Server Noden ze verdeelen, hu mir souwuel vertikal wéi horizontal benotzt opzedeelen (schnitt). Historesch hu mir en einfachen Dateschutzschema benotzt: all Entitéit gouf mat engem Token verbonnen - eng Funktioun vun der Entity ID. Entitéite mat deemselwechten Token goufen um selwechte SQL Server gesat. D'Meeschtesch-Detail Bezéiung gouf ëmgesat sou datt d'Tokens vun den Haapt- a Kannerrecords ëmmer matenee passen an um selwechte Server sinn. An engem sozialen Netzwierk gi bal all Rekorder am Numm vum Benotzer generéiert - dat heescht datt all Benotzerdaten an engem funktionnellen Subsystem op engem Server gespäichert sinn. Dat ass, eng Geschäftstransaktioun huet bal ëmmer Tabelle vun engem SQL Server involvéiert, wat et méiglech gemaach huet Datenkonsistenz mat lokalen ACID Transaktiounen ze garantéieren, ouni d'Notzung ze benotzen lues an onzouverlässeg verdeelt ACID Transaktiounen.

Dank Sharding a fir SQL ze beschleunegen:

  • Mir benotzen keng Auslännerschlësselbeschränkungen, well beim Sharing kann d'Entity ID op engem anere Server lokaliséiert sinn.
  • Mir benotzen net gespäichert Prozeduren an Ausléiser wéinst der zousätzlech Belaaschtung op der DBMS CPU.
  • Mir benotzen net JOINs wéinst all vun der uewen a vill zoufälleg liesen aus Scheif.
  • Ausserhalb vun enger Transaktioun benotze mir de Read Uncommitted Isolatiounsniveau fir Deadlocks ze reduzéieren.
  • Mir maachen nëmme kuerz Transaktiounen (am Duerchschnëtt méi kuerz wéi 100 ms).
  • Mir benotzen net Multi-Zeil UPDATE an DELETE wéinst der grousser Zuel vun Deadlocks - mir aktualiséieren nëmmen ee Rekord gläichzäiteg.
  • Mir maachen ëmmer Ufroen nëmmen op Indexen - eng Ufro mat engem komplette Tabellescannplang fir eis heescht d'Datebank iwwerlaascht a verursaache se ze versoen.

Dës Schrëtt hunn eis erlaabt bal maximal Leeschtung aus SQL Serveren ze pressen. Allerdéngs goufen d'Problemer ëmmer méi vill. Loosst eis se kucken.

Problemer mat SQL

  • Zënter datt mir selbstgeschriwwene Schnëtt benotzt hunn, gouf nei Schnëtt bäigefüügt manuell vun Administrateuren gemaach. All dës Zäit, skalierbar Daterepliken waren net servéiert Ufroen.
  • Wéi d'Zuel vun den Opzeechnungen an der Tabell wiisst, fällt d'Geschwindegkeet vun der Insertioun an der Modifikatioun erof wann d'Indexen op eng existéierend Tabelle bäigefüügt ginn, fällt d'Geschwindegkeet duerch e Faktor Schafung an Neischafung vun Indexen op;
  • Eng kleng Quantitéit vu Windows fir SQL Server an der Produktioun ze hunn mécht d'Infrastrukturmanagement schwéier

Awer den Haaptproblem ass

Feeler Toleranz

De klassesche SQL Server huet schlecht Feeler Toleranz. Loosst eis soen datt Dir nëmmen een Datebankserver hutt, an et fällt eemol all dräi Joer. Wärend dëser Zäit ass de Site fir 20 Minutten erof, wat akzeptabel ass. Wann Dir 64 Server hutt, ass de Site eemol all dräi Wochen erof. A wann Dir 200 Serveren hutt, da funktionnéiert de Site net all Woch. Dëst ass Problem.

Wat kann gemaach ginn fir d'Fehlertoleranz vun engem SQL Server ze verbesseren? Wikipedia invitéiert eis ze bauen héich verfügbare Cluster: wou am Fall vun Echec vun engem vun de Komponente gëtt et eng Backupsatellit.

Dëst erfuerdert eng Flott vun deieren Ausrüstung: vill Duplikatioune, optesch Faser, gemeinsame Späicheren, an d'Inklusioun vun enger Reserve funktionnéiert net zouverlässeg: ongeféier 10% vun de Wiesselen enden mam Ausfall vum Backup-Node wéi en Zuch hannert dem Haaptknuet.

Awer den Haaptnodeel vun esou engem héich verfügbare Stärekoup ass Null Disponibilitéit wann den Rechenzentrum an deem et läit fällt. Odnoklassniki huet véier Rechenzentren, a mir mussen d'Operatioun am Fall vun engem komplette Feeler an engem vun hinnen garantéieren.

Fir dëst kënne mir benotzen Multi-Master Replikatioun a SQL Server gebaut. Dës Léisung ass vill méi deier wéinst de Käschte vun der Software a leid ënner bekannte Probleemer mat Replikatioun - onberechenbar Transaktiounsverzögerungen mat synchroner Replikatioun a Verspéidungen bei der Uwendung vun Replikatiounen (an, als Resultat, verluere Modifikatioune) mat asynchroner Replikatioun. Déi implizéiert manuell Konfliktléisung mécht dës Optioun fir eis komplett inapplicabel.

All dës Problemer erfuerdert eng radikal Léisung, a mir hunn ugefaang se am Detail ze analyséieren. Hei musse mir kennen léieren wat SQL Server haaptsächlech mécht - Transaktiounen.

Einfach Transaktioun

Loosst eis déi einfachst Transaktioun betruechten, aus der Siicht vun engem ugewandte SQL Programméierer: eng Foto an en Album addéieren. Albumen a Fotoe ginn op verschiddene Placke gespäichert. Den Album huet eng ëffentlech Foto counter. Dann ass sou eng Transaktioun an de folgende Schrëtt opgedeelt:

  1. Mir spären den Album mam Schlëssel.
  2. Schafen eng Entrée an der Foto Dësch.
  3. Wann d'Foto en ëffentleche Status huet, füügt dann en ëffentleche Fototeller an den Album un, aktualiséieren de Rekord an engagéieren d'Transaktioun.

Oder am Pseudocode:

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

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

TX.commit();

Mir gesinn datt de meescht üblechen Geschäftstransaktiounsszenario ass Daten aus der Datebank an d'Erënnerung vum Applikatiounsserver ze liesen, eppes z'änneren an déi nei Wäerter zréck an d'Datebank ze späicheren. Normalerweis an esou enger Transaktioun update mir verschidden Entitéite, puer Dëscher.

Wann Dir eng Transaktioun ausféiert, kann gläichzäiteg Ännerung vun de selwechte Daten aus engem anere System optrieden. Zum Beispill kann Antispam entscheeden datt de Benotzer iergendwéi verdächteg ass an dofir sollten all d'Fotoen vum Benotzer net méi ëffentlech sinn, se musse fir Moderatioun geschéckt ginn, dat heescht d'Foto änneren.Status op en anere Wäert an auszeschalten déi entspriechend Teller. Natierlech, wann dës Operatioun ouni Garantien vun der Atomitéit vun der Uwendung an der Isolatioun vu konkurréiere Modifikatioune geschitt, wéi an sauerem, da wäert d'Resultat net sinn wat néideg ass - entweder de Fotozähler weist de falsche Wäert, oder net all Fotoe ginn zur Moderatioun geschéckt.

Vill ähnleche Coden, déi verschidde Geschäftsentitéite bannent enger Transaktioun manipuléieren, ass uechter d'ganz Existenz vun Odnoklassniki geschriwwe ginn. Baséierend op d'Erfahrung vu Migratiounen op NoSQL aus Eventuell Konsistenz Mir wëssen datt déi gréissten Erausfuerderung (an Zäitinvestitioun) aus der Entwécklung vum Code kënnt fir Datenkonsistenz z'erhalen. Dofir hu mir d'Haaptfuerderung fir déi nei Lagerung als Viraussetzung fir real ACID Transaktioune fir Applikatiounslogik ugesinn.

Aner, net manner wichteg, Ufuerderunge waren:

  • Wann den Rechenzentrum klappt, muss souwuel d'Liesen an d'Schreiwen op déi nei Späichere verfügbar sinn.
  • Déi aktuell Entwécklungsgeschwindegkeet erhalen. Dat ass, wann Dir mat engem neie Repository schafft, sollt de Betrag vum Code ongeféier d'selwecht sinn, et sollt kee Besoin sinn fir eppes un de Repository ze addéieren, Algorithmen z'entwéckelen fir Konflikter ze léisen, sekundär Indexen z'erhalen, etc.
  • D'Geschwindegkeet vun der neier Späichere muss zimlech héich sinn, souwuel beim Liesen vun Daten wéi och beim Veraarbechtung vun Transaktiounen, wat effektiv bedeit datt akademesch rigoréis, universell, awer lues Léisungen, wéi zum Beispill, net applicabel waren. zwee-Phase engagéiert.
  • Automatesch On-the-Fly Skala.
  • Benotzen regelméisseg bëlleg Serveren, ouni de Besoin fir exotesch Hardware ze kafen.
  • Méiglechkeet vun Stockage Entwécklung vun Firma Entwéckler. An anere Wierder, Prioritéit gouf fir propriétaire oder Open Source Léisunge kritt, am léifsten op Java.

Entscheedungen, Entscheedungen

Analyséiere méiglech Léisungen, mir koumen op zwou méiglech Architekturwahlen:

Déi éischt ass all SQL Server ze huelen an déi erfuerderlech Feeler Toleranz, Skaléierungsmechanismus, Failover Cluster, Konfliktléisung a verdeelt, zouverlässeg a séier ACID Transaktiounen ëmzesetzen. Mir hunn dës Optioun als ganz net-trivial an Aarbechtsintensiv bewäert.

Déi zweet Optioun ass e fäerdege NoSQL-Späichere mat implementéierter Skaléierung ze huelen, e Failover-Cluster, Konfliktléisung, an Transaktiounen a SQL selwer implementéieren. Op den éischte Bléck, souguer d'Aufgab vun der Ëmsetzung vun SQL, net ACID Transaktiounen ze ernimmen, gesäit aus wéi eng Aufgab déi Joeren dauert. Awer dunn hu mir gemierkt datt de SQL Feature Set, dee mir an der Praxis benotzen, sou wäit vun ANSI SQL ass wéi Cassandra CQL wäit vun ANSI SQL. Wann mir CQL nach méi no kucken, hu mir gemierkt datt et zimlech no war wat mir gebraucht hunn.

Cassandra an CQL

Also, wat ass interessant iwwer Cassandra, wéi eng Fäegkeeten huet et?

Als éischt, hei kënnt Dir Dëscher erstellen déi verschidde Datentypen ënnerstëtzen, Dir kënnt SELECT oder UPDATE op de primäre Schlëssel maachen.

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

Fir d'Replikdatenkonsistenz ze garantéieren, benotzt Cassandra Quorum Approche. Am einfachsten Fall heescht dat datt wann dräi Repliken vun der selwechter Zeil op verschiddene Wirbelen vum Stärekoup plazéiert sinn, gëtt d'Schreiwe als erfollegräich ugesinn wann d'Majoritéit vun den Noden (dat ass zwee vun dräi) den Erfolleg vun dëser Schreifoperatioun bestätegt. . D'Zeildaten ginn als konsequent ugesinn wann, beim Liesen, d'Majoritéit vun den Noden gepréift a bestätegt goufen. Also, mat dräi Repliken, ass komplett an direkt Datekonsistenz garantéiert wann een Node feelt. Dës Approche erlaabt eis en nach méi zouverlässeg Schema ëmzesetzen: schéckt ëmmer Ufroen un all dräi Repliken, waart op eng Äntwert vun deenen zwee schnellsten. Déi spéit Äntwert vun der drëtter Replica gëtt an dësem Fall verworf. E Node, dee spéit an der Äntwert ass, kann sérieux Problemer hunn - Bremsen, Müllsammlung am JVM, direkt Erënnerung zréck am Linux Kernel, Hardwarefehler, Trennung vum Netz. Dëst beaflosst awer op kee Fall d'Operatiounen oder d'Donnéeë vum Client.

D'Approche wa mir dräi Wirbelen kontaktéieren an eng Äntwert vun zwee kréien, gëtt genannt Spekulatiounen: eng Demande fir extra Repliken gëtt geschéckt nach ier se "offällt".

En anere Virdeel vu Cassandra ass Batchlog, e Mechanismus dee garantéiert datt eng Partie Ännerungen déi Dir maacht entweder voll applizéiert oder guer net applizéiert ginn. Dëst erlaabt eis A an ACID ze léisen - Atomitéit aus der Këscht.

Déi nootste Saach fir Transaktiounen zu Cassandra sinn déi sougenannte "liicht Transaktiounen". Awer si si wäit vun "echte" ACID Transaktiounen: Tatsächlech ass dëst eng Geleeënheet ze maachen CAS op Daten aus nëmmen engem Rekord, benotzt Konsens mam Schwéiergewiicht Paxos Protokoll. Dofir ass d'Geschwindegkeet vun esou Transaktiounen niddereg.

Wat mir vermësst an Cassandra

Also hu mir real ACID Transaktiounen zu Cassandra missen ëmsetzen. Mat deem kënne mir zwee aner praktesch Features vu klassesche DBMS einfach implementéieren: konsequent séier Indexen, déi eis erlaben Dateauswielen net nëmmen duerch de primäre Schlëssel auszeféieren, an e reegelméissege Generator vu monotonen auto-incrementing IDs.

C* Eng

Sou gouf en neien DBMS gebuer C* Eng, besteet aus dräi Zorte vu Servernoden:

  • Stockage - (bal) Standard Cassandra Serveren verantwortlech fir Daten op lokalen Disken ze späicheren. Wéi d'Laascht an de Volume vun Daten wuessen, kann hir Quantitéit einfach op Zénger an Honnerte skaléiert ginn.
  • Transaktiounskoordinatoren - garantéieren d'Ausféierung vun Transaktiounen.
  • Cliente sinn Applikatiounsserver déi Geschäftsoperatioune implementéieren an Transaktiounen initiéieren. Et kann Dausende vun esou Clienten ginn.

NewSQL = NoSQL+ACID

Serveren vun all Typ sinn Deel vun engem gemeinsame Cluster, benotzen den internen Cassandra Message Protokoll fir mateneen ze kommunizéieren an Klatsch fir Clusterinformatioun auszetauschen. Mat Heartbeat, Serveren léieren iwwer géigesäitege Feeler, erhalen en eenzegt Dateschema - Dëscher, hir Struktur a Replikatioun; Partition Schema, Cluster Topologie, etc.

Clienten

NewSQL = NoSQL+ACID

Amplaz Standard Chauffeuren gëtt Fat Client Modus benotzt. Sou en Node späichert keng Daten, awer kann als Koordinator fir d'Ausféierung vun der Ufro handelen, dat heescht, de Client selwer handelt als Koordinator vu sengen Ufroen: et freet Späicherrepliken a léist Konflikter. Dëst ass net nëmme méi zouverlässeg a méi séier wéi de Standard Chauffer, deen Kommunikatioun mat engem Fernkoordinator erfuerdert, awer och erlaabt Iech d'Transmissioun vun Ufroen ze kontrolléieren. Ausserhalb vun enger Transaktioun op de Client, ginn Ufroe op Repositories geschéckt. Wann de Client eng Transaktioun opgemaach huet, da ginn all Ufroe bannent der Transaktioun un den Transaktiounskoordinator geschéckt.
NewSQL = NoSQL+ACID

C * One Transaktiounskoordinator

De Koordinator ass eppes wat mir fir C*One vun Null implementéiert hunn. Et ass verantwortlech fir d'Gestioun vun Transaktiounen, Spären, an d'Uerdnung an där Transaktiounen applizéiert ginn.

Fir all servéiert Transaktioun generéiert de Koordinator en Zäitstempel: all spéider Transaktioun ass méi grouss wéi déi viregt Transaktioun. Zënter dem Cassandra säi Konfliktléisungssystem baséiert op Zäitstempel (vun zwee konfliktende Rekorder, dee mat dem leschten Zäitstempel gëtt als aktuell ugesinn), gëtt de Konflikt ëmmer zugonschte vun der nächster Transaktioun geléist. Sou hu mir ëmgesat Lamport Uhr - eng bëlleg Manéier Konflikter an engem verdeelt System ze léisen.

Schleisen

Fir Isolatioun ze garantéieren, hu mir décidéiert déi einfachst Method ze benotzen - pessimistesch Schleisen baséiert op dem primäre Schlëssel vum Rekord. An anere Wierder, an enger Transaktioun muss e Rekord als éischt gespaart ginn, nëmmen dann gelies, geännert a gespäichert ginn. Nëmmen no engem erfollegräichen Engagement kann e Rekord opgehuewe ginn, sou datt konkurrenzfäeg Transaktioune se benotze kënnen.

Ëmsetzung vun esou Sperrung ass einfach an engem net-verdeelt Ëmfeld. An engem verdeelt System ginn et zwou Haaptoptiounen: entweder ëmsetzen verdeelt Sperrung op de Stärekoup, oder verdeelt Transaktiounen sou datt Transaktioune mat deemselwechte Rekord ëmmer vum selwechte Koordinator servéiert ginn.

Well an eisem Fall d'Donnéeën schonn ënner Gruppe vu lokalen Transaktiounen an SQL verdeelt sinn, gouf decidéiert lokal Transaktiounsgruppen u Koordinatoren ze ginn: ee Koordinator mécht all Transaktioune mat Tokens vun 0 bis 9, déi zweet - mat Tokens vun 10 bis 19, a sou weider. Als Resultat gëtt jidderee vun de Koordinatorinstanzen de Meeschter vun der Transaktiounsgrupp.

Da kënnen Spären a Form vun engem banalen HashMap an der Erënnerung vum Koordinator ëmgesat ginn.

Koordinator Feeler

Zënter engem Koordinator exklusiv eng Grupp vun Transaktiounen déngt, ass et ganz wichteg fir séier d'Tatsaach vu sengem Echec ze bestëmmen, sou datt den zweeten Versuch fir d'Transaktioun auszeféieren ass Zäit aus. Fir dëst séier an zouverlässeg ze maachen, hu mir e komplett verbonne Quorum Hearbeat Protokoll benotzt:

All Datenzenter hëlt op d'mannst zwee Koordinatornoden. Periodesch schéckt all Koordinator eng Häerzschlagmeldung un déi aner Koordinateuren an informéiert hinnen iwwer säi Fonctionnement, wéi och wéi eng Häerzschlagmeldungen en vun deenen Koordinatoren am Cluster d'lescht Kéier krut.

NewSQL = NoSQL+ACID

Kritt ähnlech Informatioun vun aneren als Deel vun hiren Häerzschlagmeldungen, entscheet all Koordinator fir sech selwer wéi eng Clusterknäppchen funktionnéieren a wéi eng net, guidéiert vum Quorumprinzip: wann den Node X Informatioun vun der Majoritéit vun den Wirbelen am Cluster iwwer déi normal kritt huet. Empfang vun Messagen aus Node Y, dann , Y Wierker. A vice versa, soubal d'Majoritéit mellt fehlend Messagen vum Node Y, dann huet Y refuséiert. Et ass virwëtzeg datt wann de Quorum den Node X informéiert datt et net méi Messagen dovunner kritt, da wäert den Node X selwer sech als gescheitert betruechten.

Häerzschlagmeldungen gi mat héijer Frequenz geschéckt, ongeféier 20 Mol pro Sekonn, mat enger Period vu 50 ms. Am Java ass et schwéier d'Applikatiounsreaktioun innerhalb vun 50 ms ze garantéieren wéinst der vergläichbarer Längt vun de Pausen verursaacht vum Müllsammler. Mir konnten dës Äntwertzäit mam G1 Müllsammler erreechen, wat eis erlaabt en Zil fir d'Dauer vun de GC Pausen ze spezifizéieren. Wéi och ëmmer, heiansdo, zimlech selten, sinn d'Sammlerpausen méi wéi 50 ms, wat zu enger falscher Fehlerkennung féieren kann. Fir dëst ze verhënneren, mellt de Koordinator net e Feeler vun engem Remote Node wann déi éischt Häerzschlagmeldung dovun verschwënnt, nëmmen wann e puer an enger Rei verschwonnen hunn ms.

Awer et ass net genuch fir séier ze verstoen wéi eng Node opgehalen huet ze funktionnéieren. Mir mussen eppes doriwwer maachen.

Reservatioun

Déi klassesch Schema ëmfaasst, am Fall vun engem Meeschter Echec, eng Neiwahlen mat engem vun ufänken moudesch universal algorithms. Wéi och ëmmer, esou Algorithmen hu bekannte Problemer mat der Zäitkonvergenz an der Längt vum Wahlprozess selwer. Mir konnten esou zousätzlech Verspéidungen vermeiden mat engem Koordinator Ersatzschema an engem komplett verbonnene Netzwierk:

NewSQL = NoSQL+ACID

Loosst eis soen datt mir eng Transaktioun am Grupp ausféieren 50. Loosst eis am Viraus den Ersatzschema bestëmmen, dat heescht, wéi eng Noden Transaktiounen am Grupp 50 am Fall vun engem Echec vum Haaptkoordinator ausféieren. Eist Zil ass d'Systemfunktionalitéit am Fall vun engem Datenzenterfehler z'erhalen. Loosst eis feststellen datt déi éischt Reserve e Node vun engem aneren Rechenzentrum ass, an déi zweet Reserve wäert e Node vun engem Drëttel sinn. Dëse Schema gëtt eemol ausgewielt an ännert sech net bis d'Topologie vum Stärekoup ännert, dat heescht bis nei Wirbelen et erakommen (wat ganz selten geschitt). D'Prozedur fir en neien aktive Meeschter ze wielen, wann deen alen feelt, wäert ëmmer wéi follegt sinn: déi éischt Reserve gëtt den aktive Meeschter, a wann se opgehalen huet ze funktionéieren, gëtt déi zweet Reserve den aktive Meeschter.

Dëse Schema ass méi zouverlässeg wéi den universellen Algorithmus, well fir en neie Meeschter ze aktivéieren ass et genuch fir den Echec vum alen ze bestëmmen.

Awer wéi verstinn d'Clienten wéi ee Meeschter elo funktionnéiert? Et ass onméiglech Informatioun un Dausende vu Clienten a 50 ms ze schécken. Eng Situatioun ass méiglech wann e Client eng Ufro schéckt fir eng Transaktioun opzemaachen, nach net wëssend datt dëse Meeschter net méi funktionnéiert, an d'Ufro gëtt Zäit aus. Fir dëst ze verhënneren, schécken d'Clienten spekulativ eng Ufro fir eng Transaktioun un de Gruppmeeschter a béid vu senge Reserven op eemol opzemaachen, awer nëmmen deen deen am Moment den aktive Meeschter ass, wäert op dës Ufro reagéieren. De Client wäert all spéider Kommunikatioun bannent der Transaktioun nëmme mam aktive Meeschter maachen.

Backupsatellit Meeschter Plaz empfaangen Demanden fir Transaktiounen déi net hir sinn an der Schlaang vun ongebuerene Transaktiounen, wou se fir eng Zäit gespäichert sinn. Wann den aktive Master stierft, veraarbecht den neie Master Ufroe fir Transaktiounen aus senger Schlaang opzemaachen a reagéiert op de Client. Wann de Client schonn eng Transaktioun mam alen Meeschter opgemaach huet, da gëtt déi zweet Äntwert ignoréiert (an, selbstverständlech, esou eng Transaktioun gëtt net fäerdeg a gëtt vum Client widderholl).

Wéi d'Transaktioun Wierker

Loosst eis soen datt e Client eng Demande un de Koordinator geschéckt huet fir eng Transaktioun opzemaachen fir sou an esou eng Entitéit mat esou an esou engem primäre Schlëssel. De Koordinator spären dës Entitéit a setzt se an der Spär Dësch an Erënnerung. Wann néideg, liest de Koordinator dës Entitéit aus der Späichere a späichert déi resultéierend Donnéeën an engem Transaktiounszoustand an der Erënnerung vum Koordinator.

NewSQL = NoSQL+ACID

Wann e Client Daten an enger Transaktioun wëllt änneren, schéckt en eng Ufro un de Koordinator fir d'Entitéit z'änneren, an de Koordinator setzt déi nei Donnéeën an der Transaktiounsstatustabell an der Erënnerung. Dëst fäerdeg den Opnahmen - keng Opnam gëtt op d'Späichere gemaach.

NewSQL = NoSQL+ACID

Wann e Client seng eege geännert Donnéeën als Deel vun enger aktiver Transaktioun freet, handelt de Koordinator wéi follegt:

  • wann d'ID schonn an der Transaktioun ass, da ginn d'Donnéeën aus der Erënnerung geholl;
  • wann et keng ID an der Erënnerung ass, da ginn déi fehlend Donnéeën aus de Späicherknäppchen gelies, kombinéiert mat deenen déi schonn an der Erënnerung sinn, an d'Resultat gëtt dem Client kritt.

Sou kann de Client seng eege Ännerunge liesen, awer aner Clienten gesinn dës Ännerungen net, well se nëmmen an der Erënnerung vum Koordinator sinn, si sinn nach net an de Cassandra-Knäppchen.

NewSQL = NoSQL+ACID

Wann de Client eng Verpflichtung schéckt, gëtt de Staat, deen an der Erënnerung vum Service war, vum Koordinator an enger protokolléierter Batch gespäichert, a gëtt als protokolléiert Batch op d'Cassandra-Späichere geschéckt. D'Geschäfter maachen alles wat néideg ass fir sécherzestellen datt dëse Package atomesch (komplett) applizéiert gëtt, an eng Äntwert op de Koordinator zréckginn, deen d'Schlässer verëffentlecht an den Erfolleg vun der Transaktioun dem Client bestätegt.

NewSQL = NoSQL+ACID

A fir zréckzekréien, brauch de Koordinator nëmmen d'Erënnerung ze befreien, déi vum Transaktiounsstaat besat ass.

Als Resultat vun den uewe genannte Verbesserungen hu mir d'ACID Prinzipien ëmgesat:

  • Atomitéit. Dëst ass eng Garantie datt keng Transaktioun deelweis am System opgeholl gëtt entweder all seng Ënneroperatiounen ofgeschloss ginn, oder keng wäert ofgeschloss ginn. Mir halen dëse Prinzip duerch protokolléiert Batch zu Cassandra.
  • Konsistenz. All erfollegräich Transaktioun, per Definitioun, records nëmme valabel Resultater. Wann, no der Ouverture vun enger Transaktioun an engem Deel vun den Operatiounen, entdeckt gëtt datt d'Resultat ongëlteg ass, gëtt e Réckroll gemaach.
  • Isoléierung. Wann eng Transaktioun ausgefouert gëtt, sollten gläichzäiteg Transaktioune säin Resultat net beaflossen. Konkurrenztransaktiounen sinn isoléiert mat pessimistesche Spären op de Koordinator. Fir Liesen ausserhalb vun enger Transaktioun gëtt den Isolatiounsprinzip um Read Committed Niveau observéiert.
  • Nohaltegkeet. Onofhängeg vu Probleemer op méi nidderegen Niveauen - Systemblackout, Hardwarefehler - Ännerungen, déi duerch eng erfollegräich ofgeschloss Transaktioun gemaach goufen, sollten erhale bleiwen wann d'Operatiounen erëm ufänken.

Liesen duerch Indexen

Loosst eis en einfachen Dësch huelen:

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

Et huet eng ID (primär Schlëssel), Besëtzer an Ännerung Datum. Dir musst eng ganz einfach Ufro maachen - wielt Daten iwwer de Besëtzer mam Ännerungsdatum "fir de leschten Dag".

SELECT *
WHERE owner=?
AND modified>?

Fir datt esou eng Ufro séier veraarbecht gëtt, musst Dir an engem klassesche SQL DBMS en Index opbauen duerch Kolonnen (Besëtzer, geännert). Mir kënnen dat ganz einfach maachen, well mir elo SAIER Garantie hunn!

Indizes an C * One

Et gëtt eng Quelltabel mat Fotoen an deenen d'Rekord ID de primäre Schlëssel ass.

NewSQL = NoSQL+ACID

Fir en Index schaaft C * One en neien Dësch, deen eng Kopie vum Original ass. De Schlëssel ass d'selwecht wéi den Indexausdrock, an et enthält och de primäre Schlëssel vum Rekord aus der Quelltabel:

NewSQL = NoSQL+ACID

Elo kann d'Ufro fir "Besëtzer fir de leschten Dag" als Auswiel vun engem aneren Dësch ëmgeschriwwe ginn:

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

D'Konsistenz vun den Donnéeën an de Quelltabelfotoen an den Indextabelle i1 gëtt automatesch vum Koordinator erhale gelooss. Baséierend op den Dateschema eleng, wann eng Ännerung kritt gëtt, generéiert a späichert de Koordinator eng Ännerung net nëmmen an der Haapttabell, awer och a Kopien. Keng zousätzlech Aktiounen ginn op den Indextabelle gemaach, d'Logbicher ginn net gelies a keng Späre gi benotzt. Dat ass, Indexer derbäi ze verbrauchen bal keng Ressourcen an huet praktesch keen Effekt op d'Geschwindegkeet vun der Uwendung vun Ännerungen.

Mat ACID konnte mir SQL-ähnlech Indexen implementéieren. Si si konsequent, skalierbar, séier, komponéierbar a gebaut an d'CQL Ufro Sprooch. Keng Ännerunge vum Applikatiounscode sinn erfuerderlech fir Indexen z'ënnerstëtzen. Alles ass sou einfach wéi an SQL. A virun allem, Indizes beaflossen net d'Ausféierungsgeschwindegkeet vun den Ännerunge vun der ursprénglecher Transaktiounstabell.

Wat ass geschitt

Mir hunn den C*One virun dräi Joer entwéckelt an a kommerziell Operatioun lancéiert.

Wat hu mer um Enn kritt? Loosst eis dat evaluéieren andeems Dir d'Beispill vun der Fotoveraarbechtung a Lagerung-Subsystem benotzt, eng vun de wichtegsten Zorten vun Daten an engem sozialen Netzwierk. Mir schwätzen net vun de Kierper vun de Fotoen selwer, mä iwwer all Zorte vu Meta-Informatiounen. Elo huet Odnoklassniki ongeféier 20 Milliarden esou Opzeechnungen, de System veraarbecht 80 Tausend Liesfuerderunge pro Sekonn, bis zu 8 Tausend ACID Transaktiounen pro Sekonn verbonne mat Datemodifikatioun.

Wa mir SQL mat Replikatiounsfaktor = 1 benotzt hunn (awer am RAID 10), gouf d'Fotometainformatioun op engem héich verfügbare Cluster vun 32 Maschinnen gespäichert, déi Microsoft SQL Server lafen (plus 11 Backups). 10 Servere goufen och zougewisen fir Backups ze späicheren. Am Ganzen 50 deier Autoen. Zur gläicher zäit huet de system mat nominéierte belaaschtung, ouni reserve.

Nom Migratioun op den neie System krute mir Replikatiounsfaktor = 3 - eng Kopie an all Datenzenter. De System besteet aus 63 Cassandra Späicherknäppchen a 6 Koordinatormaschinnen, fir insgesamt 69 Serveren. Awer dës Maschinnen si vill méi bëlleg, hir Gesamtkäschte sinn ongeféier 30% vun de Käschte vun engem SQL System. Zur selwechter Zäit gëtt d'Laascht op 30% gehal.

Mat der Aféierung vum C * One ass d'Latenz och erofgaang: an SQL huet eng Schreifoperatioun ongeféier 4,5 ms gedauert. An C*One - ongeféier 1,6 ms. D'Transaktiounsdauer ass am Duerchschnëtt manner wéi 40 ms, d'Verpflichtung ass an 2 ms ofgeschloss, d'Lies- a Schreifdauer ass am Duerchschnëtt 2 ms. 99th percentile - nëmmen 3-3,1 ms, d'Zuel vun den Timeouts ass ëm 100 Mol erofgaang - alles wéinst der verbreeter Notzung vu Spekulatiounen.

Bis elo sinn déi meescht vun de SQL Server Noden ofgebaut ginn nei Produkter ginn nëmme mat C*One entwéckelt. Mir hunn C*One ugepasst fir an eiser Cloud ze schaffen eent-Wollek, wat et méiglech gemaach huet d'Deployment vun neie Cluster ze beschleunegen, d'Konfiguratioun ze vereinfachen an d'Operatioun automatiséieren. Ouni de Quellcode wier dëst vill méi schwéier a ëmständlech ze maachen.

Elo schaffen mir un eis aner Späicheranlagen op d'Cloud ze transferéieren - awer dat ass eng ganz aner Geschicht.

Source: will.com

Setzt e Commentaire