Cassandra. Hogyan ne halj meg, ha csak az Oracle-t ismered

Szia Habr.

A nevem Misha Butrimov, szeretnék egy kicsit mesélni Cassandráról. A történetem azoknak lesz hasznos, akik még soha nem találkoztak NoSQL-adatbázisokkal – rengeteg implementációs funkcióval és buktatóval rendelkezik, amelyekről tudnia kell. És ha az Oracle-en vagy bármely más relációs adatbázison kívül nem látott semmit, ezek a dolgok megmentik az életét.

Mi olyan jó Cassandrában? Ez egy NoSQL-adatbázis, amelyet egyetlen hibapont nélkül terveztek, és jól skálázható. Ha néhány terabájtot kell hozzáadnia egy adatbázishoz, egyszerűen adjon hozzá csomópontokat a gyűrűhöz. Ki kell bővíteni egy másik adatközpontba? Csomópontok hozzáadása a fürthöz. Növeli a feldolgozott RPS-t? Csomópontok hozzáadása a fürthöz. Ellenkező irányban is működik.

Cassandra. Hogyan ne halj meg, ha csak az Oracle-t ismered

Miben jó még? Sok kérés kezeléséről van szó. De mennyi a sok? 10, 20, 30, 40 ezer kérés másodpercenként nem sok. 100 ezer kérés másodpercenként a felvételre - szintén. Vannak olyan cégek, amelyek azt mondták, hogy másodpercenként 2 millió kérést tartanak meg. Valószínűleg el kell hinniük.

És elvileg Cassandrának van egy nagy különbsége a relációs adatokhoz képest - egyáltalán nem hasonlít rájuk. És ezt nagyon fontos megjegyezni.

Nem minden, ami ugyanúgy néz ki, működik ugyanúgy

Egyszer egy kollégám odajött hozzám, és megkérdezte: „Itt van a CQL Cassandra lekérdezési nyelv, és van egy select utasítás, van hol, van és. Leveleket írok és nem megy. Miért?". Cassandra relációs adatbázisként való kezelése tökéletes módja az erőszakos öngyilkosság elkövetésének. És nem reklámozom, Oroszországban tilos. Csak valamit rosszul tervezel.

Például odajön hozzánk egy ügyfél, és azt mondja: „Építsünk adatbázist tévésorozatokhoz, vagy adatbázist egy receptkönyvtárhoz. Lesznek ott ételeink, vagy TV-sorozatok és színészek listája.” Örömmel mondjuk: "Menjünk!" Csak küldjön két bájtot, néhány jelet és kész is, minden nagyon gyorsan és megbízhatóan fog működni. És minden rendben van, amíg nem jönnek a vásárlók és azt mondják, hogy a háziasszonyok az ellenkező problémát is megoldják: van egy terméklistájuk, és tudni akarják, milyen ételt szeretnének főzni. halott vagy.

A Cassandra ugyanis egy hibrid adatbázis: egyszerre biztosít kulcsértéket, és széles oszlopokban tárolja az adatokat. Java vagy Kotlin nyelven a következőképpen írható le:

Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

Vagyis egy olyan térképet, amely egy rendezett térképet is tartalmaz. A leképezés első kulcsa a sorkulcs vagy a partíciókulcs – a particionáló kulcs. A második kulcs, amely egy már rendezett térkép kulcsa, a Clustering kulcs.

Az adatbázis eloszlásának szemléltetésére rajzoljunk három csomópontot. Most meg kell értenie, hogyan lehet az adatokat csomópontokra bontani. Mert ha mindent egybe zsúfolunk (egyébként lehet ezer, kétezer, öt - amennyit csak akarsz), akkor itt nem igazán a terjesztésről van szó. Ezért szükségünk van egy matematikai függvényre, amely egy számot ad vissza. Csak egy szám, egy hosszú int, amely valamilyen tartományba esik. És lesz egy csomópontunk az egyik tartományért, a második a másodikért, az n-edik az n-edikért.

Cassandra. Hogyan ne halj meg, ha csak az Oracle-t ismered

Ezt a számot egy hash függvény veszi fel, amelyet az általunk partíciós kulcsnak nevezettre alkalmazunk. Ez az az oszlop, amely az Elsődleges kulcs direktívában van megadva, és ez az oszlop lesz a térkép első és legalapvetőbb kulcsa. Meghatározza, hogy melyik csomópont milyen adatokat kapjon. A Cassandra-ban egy tábla jön létre majdnem ugyanazzal a szintaxissal, mint az SQL-ben:

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

)

Az elsődleges kulcs ebben az esetben egy oszlopból áll, és egyben a particionáló kulcs is.

Hogyan teljesítenek majd felhasználóiink? Némelyik az egyik csomóponthoz megy, néhány a másikhoz, és néhány a harmadikhoz. Az eredmény egy közönséges hash tábla, más néven térkép, vagy más néven szótár a Pythonban, vagy egy egyszerű kulcsérték-struktúra, amelyből az összes értéket ki tudjuk olvasni, kulcsonként olvashatjuk és írhatjuk.

Cassandra. Hogyan ne halj meg, ha csak az Oracle-t ismered

Válassza ki: amikor a szűrés engedélyezése teljes vizsgálattá válik, vagy mit ne tegyen

Írjunk néhány válogatást: select * from users where, userid = . Kiderül, mint az Oracle-ben: kiírjuk a select-et, megadjuk a feltételeket és minden működik, a felhasználók megkapják. De ha például egy bizonyos születési évszámmal rendelkező felhasználót választ ki, Cassandra panaszkodik, hogy nem tudja teljesíteni a kérést. Mivel egyáltalán nem tud arról, hogyan osztjuk szét a születési évre vonatkozó adatokat – csak egy oszlopot jelölt meg kulcsként. Aztán azt mondja: „Rendben, még teljesíthetem ezt a kérést. Szűrés engedélyezése hozzáadása." Hozzáadjuk az irányelvet, minden működik. És ebben a pillanatban valami szörnyűség történik.

Ha tesztadatokon futunk, minden rendben van. És amikor végrehajt egy lekérdezést a termelésben, ahol például 4 millió rekordunk van, akkor minden nem megy túl jól. Ugyanis a szűrés engedélyezése egy olyan direktíva, amely lehetővé teszi, hogy a Cassandra összegyűjtse az összes adatot ebből a táblából az összes csomópontból, minden adatközpontból (ha sok van belőlük ebben a fürtben), és csak ezután szűrheti. Ez a Full Scan analógja, és szinte senki sem örül neki.

Ha csak azonosítóval rendelkező felhasználókra lenne szükségünk, akkor ezzel is jól járnánk. De néha más lekérdezéseket kell írnunk, és más korlátozásokat kell bevezetnünk a kiválasztásra. Ezért ne feledjük: ez mind egy térkép, amelynek particionáló kulcsa van, de benne van egy rendezett térkép.

És van egy kulcsa is, amit klaszterkulcsnak hívunk. Ez a kulcs, amely viszont az általunk kiválasztott oszlopokból áll, amelyek segítségével Cassandra megérti, hogy az adatai hogyan vannak fizikailag rendezve, és az egyes csomópontokon elhelyezkednek. Vagyis valamilyen partíciókulcsnál a Clustering kulcs pontosan megmondja, hogyan kell ebbe a fába tolni az adatokat, milyen helyet foglalnak el ott.

Ez tényleg egy fa, ott egyszerűen egy komparátort hívnak, amihez objektum formájában adunk át egy bizonyos oszlopkészletet, és ez oszloplistaként is megadva.

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

Ügyeljen az Elsődleges kulcs direktívára, amelynek első argumentuma (esetünkben az év) mindig a partíciókulcs. Ez egy vagy több oszlopból állhat, nem számít. Ha több oszlop van, akkor azt ismét zárójelben kell eltávolítani, hogy a nyelvi előfeldolgozó megértse, hogy ez az elsődleges kulcs, mögötte pedig az összes többi oszlop a Clustering kulcs. Ebben az esetben az összehasonlítóban a megjelenésük sorrendjében kerülnek továbbításra. Vagyis az első oszlop jelentősebb, a második kevésbé jelentős, és így tovább. Az írásmód például megegyezik az adatosztályok mezőivel: listázzuk a mezőket, és azokhoz írjuk, hogy melyik a nagyobb és melyik a kisebb. A Cassandrában ezek relatíve az adatosztály mezői, amelyekre a ráírt egyenlők kerülnek alkalmazásra.

Rendezést állítunk be és korlátozásokat vezetünk be

Ne feledje, hogy a rendezési sorrend (csökkenő, növekvő, bármi) a kulcs létrehozásának pillanatában van beállítva, és később nem módosítható. Fizikailag meghatározza, hogy az adatok hogyan lesznek rendezve és hogyan tárolódnak. Ha módosítania kell a fürtözési kulcsot vagy a rendezési sorrendet, akkor létre kell hoznia egy új táblát, és át kell vinnie az adatokat. Ez nem fog működni egy meglévővel.

Cassandra. Hogyan ne halj meg, ha csak az Oracle-t ismered

Megtöltöttük a táblázatunkat felhasználókkal, és láttuk, hogy egy gyűrűbe estek, először születési év szerint, majd minden csomóponton belül fizetés és felhasználói azonosító alapján. Most már korlátozások megadásával választhatunk.

Újra megjelenik a mi működő where, and, és kapunk felhasználókat, és minden újra rendben van. De ha megpróbáljuk a fürtözési kulcsnak csak egy részét használni, és egy kevésbé jelentőset, akkor Cassandra azonnal panaszkodni fog, hogy nem találja azt a helyet a térképünkön, ahol ez az objektum, amelyben ezek a mezők vannak a null-összehasonlítóhoz, és ez hogy most volt beállítva , - ahol fekszik. Újra le kell húznom az összes adatot erről a csomópontról, és szűrnem kell. És ez a csomóponton belüli Full Scan analógja, ez rossz.

Bármilyen tisztázatlan helyzetben hozzon létre egy új táblázatot

Ha meg akarjuk célozni a felhasználókat azonosító, életkor vagy fizetés alapján, mit tegyünk? Semmi. Csak használjon két asztalt. Ha három különböző módon kell elérnie a felhasználókat, három táblázat lesz. Elmúltak azok az idők, amikor helyet takarítottunk meg a csavaron. Ez a legolcsóbb forrás. Sokkal kevesebbe kerül, mint a válaszidő, ami káros lehet a felhasználóra nézve. A felhasználó számára sokkal kellemesebb, ha egy másodperc alatt kap valamit, mint 10 perc alatt.

Felesleges helyet és denormalizált adatokat cserélünk a jó méretezés és a megbízható működés érdekében. Valójában egy három adatközpontból álló fürt, amelyek mindegyike öt csomóponttal rendelkezik, elfogadható szintű adatmegőrzéssel (amikor semmi sem vész el), képes teljesen túlélni egy adatközpont halálát. És még két csomópont a maradék kettőben. És csak ezután kezdődnek a problémák. Ez elég jó redundancia, megér pár extra SSD meghajtót és processzort. Ezért a Cassandra használatához, ami sosem SQL, amelyben nincsenek kapcsolatok, idegen kulcsok, egyszerű szabályokat kell ismerni.

Mindent az Ön igényei szerint tervezünk. A lényeg nem az adatok, hanem az, hogy az alkalmazás hogyan fog működni velük. Ha különböző adatokat kell kapnia különböző módon, vagy ugyanazokat az adatokat különböző módon, akkor azt az alkalmazás számára kényelmesen kell elhelyezni. Ellenkező esetben kudarcot vallunk a Full Scan-ban, és Cassandra nem ad nekünk előnyt.

Az adatok denormalizálása a norma. Elfelejtjük a normál formákat, már nincsenek relációs adatbázisaink. Ha 100-szor leteszünk valamit, az 100-szor fog lefeküdni. Még mindig olcsóbb, mint megállni.

A particionáláshoz úgy választjuk ki a kulcsokat, hogy azok normálisan legyenek elosztva. Nem akarjuk, hogy kulcsaink hash-je egyetlen szűk tartományba essen. Vagyis a születési év a fenti példában rossz példa. Pontosabban jó, ha a felhasználóink ​​normálisan születési év szerint oszlanak el, és rossz, ha 5. osztályos tanulókról beszélünk - ott nem lesz túl jó a particionálás.

A rendezés egyszer van kiválasztva a fürtözési kulcs létrehozási szakaszában. Ha módosítani kell, akkor a táblázatunkat egy másik kulccsal kell frissítenünk.

És ami a legfontosabb: ha ugyanazt az adatot 100 különböző módon kell lekérnünk, akkor 100 különböző táblánk lesz.

Forrás: will.com

Hozzászólás