Cassandra. Wéi net stierwen wann Dir nëmmen Oracle kennt

Hey Habr.

Mäin Numm ass Misha Butrimov, ech wëll Iech e bëssen iwwer d'Cassandra soen. Meng Geschicht wäert nëtzlech sinn fir déi, déi nach ni NoSQL-Datebanken begéint hunn - et huet vill Implementéierungsfeatures a Fallen, déi Dir wësse musst. A wann Dir näischt anescht wéi Oracle oder all aner relational Datebank gesinn hutt, wäerten dës Saachen Äert Liewen retten.

Wat ass sou gutt iwwer Cassandra? Et ass eng NoSQL Datebank entworf ouni en eenzege Punkt vum Versoen déi gutt skaléiert. Wann Dir e puer Terabytes fir eng Datebank addéiere musst, füügt Dir einfach Noden un de Ring. Erweidert et op en aneren Datenzenter? Füügt Noden an de Cluster. Erhéijung veraarbecht RPS? Füügt Noden an de Cluster. Et funktionnéiert och an de Géigendeel Richtung.

Cassandra. Wéi net stierwen wann Dir nëmmen Oracle kennt

Wat soss ass si gutt? Et geet drëms vill Ufroen ze behandelen. Awer wéi vill ass vill? 10, 20, 30, 40 dausend Demanden pro Sekonn ass net vill. 100 dausend Demanden pro Sekonn fir opzehuelen - ze. Et gi Firmen déi gesot hunn datt se 2 Milliounen Ufroe pro Sekonn halen. Si mussen et wuel gleewen.

An am Prinzip huet d'Cassandra ee groussen Ënnerscheed vu relational Daten - et ass guer net ähnlech mat hinnen. An dëst ass ganz wichteg ze erënneren.

Net alles wat d'selwecht ausgesäit funktionnéiert d'selwecht

Eemol ass e Kolleg bei mech komm a gefrot: "Hei ass d'CQL Cassandra Query Sprooch, an et huet eng gewielt Ausso, et huet wou, et huet an. Ech schreiwen Bréiwer an et geet net. Firwat?". Cassandra wéi eng relational Datebank ze behandelen ass de perfekte Wee fir gewaltsam Suizid ze maachen. An ech förderen et net, et ass an Russland verbueden. Dir wäert just eppes falsch designen.

Zum Beispill kënnt e Client bei eis a seet: "Loosst eis eng Datebank fir TV Serien bauen, oder eng Datebank fir e Rezeptverzeechnes. Mir wäerten Iessen Platen do hunn oder eng Lëscht vun TV Serien an Akteuren an et. Mir soen frou: "Komm mer goen!" Schéckt just zwee Bytes, e puer Schëlder an Dir sidd fäerdeg, alles funktionnéiert ganz séier an zouverlässeg. An alles ass gutt bis d'Clientë kommen a soen datt d'Hausfrauen och de Géigendeel Problem léisen: Si hunn eng Lëscht mat Produkter, a si wëlle wësse wat fir eng Plat se kachen. Dir sidd dout.

Dëst ass well Cassandra eng Hybrid Datebank ass: et gëtt gläichzäiteg e Schlësselwäert a späichert Daten a breet Sailen. Op Java oder Kotlin kéint et esou beschriwwe ginn:

Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

Dat ass, eng Kaart déi och eng zortéiert Kaart enthält. Den éischte Schlëssel fir dës Kaart ass de Row Schlëssel oder Partition Schlëssel - de Partitioning Schlëssel. Den zweete Schlëssel, deen de Schlëssel fir eng scho zortéiert Kaart ass, ass de Clustering Schlëssel.

Fir d'Verdeelung vun der Datebank ze illustréieren, loosst eis dräi Wirbelen zéien. Elo musst Dir verstoen wéi d'Donnéeën an Noden zerstéiert ginn. Well wa mir alles an een kräischen (iwwregens, et kënnen dausend, zweedausend, fënnef sinn - sou vill wéi Dir wëllt), ass et net wierklech ëm d'Verdeelung. Dofir brauche mir eng mathematesch Funktioun déi eng Zuel zréckkënnt. Just eng Zuel, eng laang Int déi an e puer Beräich falen. A mir wäerten een Node verantwortlech fir eng Rei hunn, déi zweet fir déi zweet, den nth fir den nth.

Cassandra. Wéi net stierwen wann Dir nëmmen Oracle kennt

Dës Nummer gëtt mat enger Hashfunktioun geholl, déi applizéiert gëtt op dat wat mir de Partitionsschlëssel nennen. Dëst ass d'Kolonn déi an der Primärschlëssel Direktiv spezifizéiert ass, an dëst ass d'Kolonn déi den éischten a meescht Basis Schlëssel vun der Kaart wäert sinn. Et bestëmmt wéi eng Node déi Daten kritt. En Dësch gëtt a Cassandra erstallt mat bal déiselwecht Syntax wéi an SQL:

CREATE TABLE users (
	user_id uu id,
	name text,
	year int,
	salary float,
	PRIMARY KEY(user_id)

)

De Primärschlëssel an dësem Fall besteet aus enger Kolonn, an et ass och de Partitionsschlëssel.

Wéi wäerten eis Benotzer Leeschtung? E puer ginn op een Node, e puer an en aneren, an e puer op en Drëttel. D'Resultat ass eng gewéinlech Hash-Tabelle, och bekannt als Kaart, och bekannt als Wierderbuch am Python, oder eng einfach Schlësselwäertstruktur aus där mir all Wäerter kënne liesen, liesen a schreiwen mam Schlëssel.

Cassandra. Wéi net stierwen wann Dir nëmmen Oracle kennt

Wielt: wann Filter erlaabt gëtt a voller Scan, oder wat net ze maachen

Loosst eis e puer ausgewielt Ausso schreiwen: select * from users where, userid = . Et stellt sech eraus wéi an Oracle: mir schreiwen auswielen, spezifizéieren d'Konditiounen an alles funktionnéiert, d'Benotzer kréien et. Awer wann Dir zum Beispill e Benotzer mat engem bestëmmte Gebuertsjoer auswielt, beschwéiert d'Cassandra datt hien d'Ufro net erfëllt. Well si weess guer näischt iwwer wéi mir Daten iwwer d'Gebuertsjoer verdeelen - si huet nëmmen eng Kolonn als Schlëssel uginn. Da seet si: "Okay, ech kann dës Ufro nach erfëllen. Filter erlaabt." Mir addéieren d'Direktiv, alles funktionnéiert. An an dësem Moment geschitt eppes schreckleches.

Wa mir op Testdaten lafen, ass alles gutt. A wann Dir eng Ufro an der Produktioun ausféiert, wou mir zum Beispill 4 Millioune Rekorder hunn, dann ass alles net ganz gutt fir eis. Well Filter erlaabt ass eng Direktiv déi Cassandra erlaabt all Daten aus dëser Tabell aus all Wirbelen, all Datenzenteren ze sammelen (wann et vill vun hinnen an dësem Stärekoup sinn), an nëmmen dann ze filteren. Dëst ass en Analog vum Full Scan, a kaum jiddereen ass frou doriwwer.

Wa mir nëmmen Benotzer duerch ID brauchen, da wiere mir gutt mat dësem. Awer heiansdo musse mir aner Ufroen schreiwen an aner Restriktiounen op d'Auswiel opsetzen. Dofir erënnere mir eis: dëst ass alles eng Kaart déi e Partitionschlëssel huet, awer dobannen ass eng zortéiert Kaart.

A si huet och e Schlëssel, dee mir de Clustering Key nennen. Dëse Schlëssel, deen am Tour aus de Sailen besteet, déi mir auswielen, mat der Hëllef vun deenen d'Cassandra versteet wéi seng Donnéeën kierperlech sortéiert sinn an op all Node lokaliséiert ginn. Dat ass, fir e puer Partitionsschlëssel, wäert de Clustering-Schlëssel Iech genau soen wéi Dir d'Donnéeën an dëse Bam dréckt, wéi eng Plaz et do wäert huelen.

Dëst ass wierklech e Bam, e Comparator gëtt einfach do genannt, un dee mir e bestëmmte Satz vu Sailen a Form vun engem Objet passéieren, an et gëtt och als Lëscht vu Sailen uginn.

CREATE TABLE users_by_year_salary_id (
	user_id uuid,
	name text,
	year int,
	salary float,
	PRIMARY KEY((year), salary, user_id)

Opgepasst op d'Primärschlëssel Direktiv; säin éischten Argument (an eisem Fall, d'Joer) ass ëmmer Partitionsschlëssel. Et kann aus enger oder méi Kolonnen besteet, et ass egal. Wann et e puer Spalten sinn, muss se erëm an de Klammern geläscht ginn, sou datt de Sproochpreprocessor versteet datt dëst de Primärschlëssel ass, an hannert him all déi aner Kolonnen sinn de Clustering-Schlëssel. An dësem Fall gi se am Comparator iwwerdroen an der Uerdnung an där se erscheinen. Dat ass, déi éischt Kolonn ass méi bedeitend, déi zweet ass manner bedeitend, a sou weider. Wéi mir schreiwen, zum Beispill, entsprécht Felder fir Dateklassen: Mir lëschten d'Felder op, a fir si schreiwen mir wéi eng méi grouss sinn a wéi eng méi kleng sinn. An Cassandra sinn dës, relativ gesinn, d'Felder vun der Dateklass, op déi d'Gläichheet, déi dofir geschriwwe sinn, applizéiert ginn.

Mir setzen d'Sortéierung an setzen Restriktiounen op

Dir musst drun erënneren datt d'Sortéierungsuerdnung (zittend, opsteigend, wat och ëmmer) am selwechte Moment gesat gëtt wann de Schlëssel erstallt gëtt, an et kann net méi spéit geännert ginn. Et bestëmmt kierperlech wéi d'Donnéeën zortéiert ginn a wéi se gespäichert ginn. Wann Dir de Clusteringschlëssel oder d'Sortéierungsuerdnung ännere musst, musst Dir eng nei Tabell erstellen an d'Donnéeën dran transferéieren. Dëst wäert net mat engem bestehend Aarbecht.

Cassandra. Wéi net stierwen wann Dir nëmmen Oracle kennt

Mir hunn eisen Dësch mat Benotzer gefëllt a gesinn datt se an e Rank gefall sinn, fir d'éischt nom Gebuertsjoer, an dann dobannen op all Node no Pai a Benotzer ID. Elo kënne mir wielen andeems mir Restriktiounen opsetzen.

Eis Aarbechter erschéngt erëm where, and, a mir kréien Benotzer, an alles ass erëm gutt. Awer wa mir probéieren nëmmen en Deel vum Clustering Schlëssel ze benotzen, an e manner bedeitendsten, da wäert d'Cassandra direkt beschwéieren datt et d'Plaz op eiser Kaart net fënnt, wou dësen Objet, deen dës Felder fir den Nullvergläicher huet, an dësen dat war just gesat , - wou hie läit. Ech muss all d'Donnéeën vun dësem Node erëm opzéien an se filteren. An dëst ass en Analog vu Full Scan bannent engem Node, dëst ass schlecht.

An all onkloer Situatioun, schafen eng nei Dësch

Wa mir fäeg sinn d'Benotzer no ID, oder Alter oder Pai ze zielen, wat solle mir maachen? Näischt. Benotzt just zwee Dëscher. Wann Dir Benotzer op dräi verschidde Weeër erreechen musst, ginn et dräi Dëscher. Fort sinn d'Deeg wou mir Plaz op der Schraube gespuert hunn. Dëst ass déi bëllegst Ressource. Et kascht vill manner wéi d'Äntwertzäit, wat fir de Benotzer schiedlech ka sinn. Et ass vill méi agreabel fir de Benotzer eppes an enger Sekonn ze kréien wéi an 10 Minutten.

Mir handelen onnéideg Plaz an denormaliséierter Donnéeën fir d'Fäegkeet gutt ze skaléieren an zouverlässeg ze bedreiwen. Tatsächlech ass e Stärekoup, deen aus dräi Datenzenteren besteet, déi jidderee fënnef Wirbelen huet, mat engem akzeptablen Niveau vun der Dateschutz (wann näischt verluer geet), den Doud vun engem Datenzenter komplett iwwerliewe kann. An zwee méi Wirbelen an all eenzel vun de verbleiwen zwee. An nëmmen duerno fänken d'Problemer un. Dëst ass eng zimlech gutt Redundanz, et ass e puer extra SSD-Laufwerke a Prozessoren wäert. Dofir, fir Cassandra ze benotzen, déi ni SQL ass, an deem et keng Bezéiungen, auslännesch Schlësselen sinn, musst Dir einfach Regelen kennen.

Mir designen alles no Ärer Demande. Den Haapt Saach ass net d'Donnéeën, mee wéi d'Applikatioun wäert mat et schaffen. Wann et verschidden Donnéeën op verschidde Weeër oder déiselwecht Donnéeën op verschidde Manéiere muss kréien, musse mir et op eng Manéier setzen déi bequem ass fir d'Applikatioun. Soss wäerte mir am Full Scan feelen an d'Cassandra gëtt eis kee Virdeel.

Denormaliséieren Daten ass d'Norm. Mir vergiessen normal Formen, mir hu keng relational Datenbanken méi. Wa mir eppes 100 Mol erofsetzen, da wäert et 100 Mol leien. Et ass ëmmer nach méi bëlleg wéi ze stoppen.

Mir wielt d'Schlëssel fir d'Partitionéierung sou datt se normalerweis verdeelt ginn. Mir wëllen net datt den Hash vun eise Schlësselen an ee schmuele Beräich falen. Dat ass, d'Gebuertsjoer am Beispill hei uewen ass e schlecht Beispill. Méi präzis ass et gutt wann eis Benotzer normalerweis no Gebuertsjoer verdeelt sinn, a schlecht wa mir vu 5. Schouljoer schwätzen - d'Trennung do wäert net ganz gutt sinn.

D'Sortéierung gëtt eemol an der Clustering Key Kreatiounsstadium ausgewielt. Wann et muss geännert ginn, musse mir eisen Dësch mat engem anere Schlëssel aktualiséieren.

An dat Wichtegst: wa mir déiselwecht Donnéeën op 100 verschidde Weeër musse recuperéieren, da wäerte mir 100 verschidden Dëscher hunn.

Source: will.com

Setzt e Commentaire