Cassandra. Kuidas mitte surra, kui tead vaid Oracle'it

Tere, Habr.

Minu nimi on Misha Butrimov ja sooviksin rÀÀkida Cassandra'st. Minu jutt on kasulik neile, kes pole kunagi NoSQL-iga kokku puutunud — sellel on palju teostuse eripĂ€rasid ja peidetud vĂ”tteid, millest on hea teada. Kui olete nĂ€inud vaid Oracle'it vĂ”i mĂ”nda muud relatsioonilist andmebaasi, siis need teadmised vĂ”ivad teie elu palju kergemaks teha.

Miks on Cassandra hea? See on NoSQL-andmebaas, mis on projekteeritud ilma ĂŒhegi rikke punktita ja millel on suurepĂ€rane skaleeritavus. Kui peate lisama paar terabaiti andmeid, lisate lihtsalt sĂ”lmed ringi. Soovite selle laiendada teise andmekeskusesse? Lisage sĂ”lmed klastrisse. Kas soovite suurendada töödeldud RPS-i? Lisage sĂ”lmed klastrisse. Sama kehtib ka vastupidiselt.

Cassandra. Kuidas mitte surra, kui tead vaid Oracle'it

Milles veel on see hea? Paljude pĂ€ringute töötlemises. Aga palju — kui palju? 10, 20, 30, 40 tuhat pĂ€ringut sekundis on natuke. 100 tuhat pĂ€ringut sekundis kirjutamiseks — samuti. On ettevĂ”tteid, kes vĂ€idavad, et nad hoiavad 2 miljonit pĂ€ringut sekundis. Neile tuleb vist uskuda.

Ja Cassandra'l on ĂŒks suur erinevus relatsioonilistest andmetest — see ei sarnane neile ĂŒldse. Ja seda on vĂ€ga oluline meeles pidada.

Mitte kÔik, mis vÀlja nÀeb sarnane, ei tööta sarnaselt.

Kord kĂŒsis ĂŒks kolleeg: «Siin on CQL, Cassandra pĂ€ringukeel, ja seal on select-lause, seal on where, seal on and. Ma kirjutan tĂ€hti, aga see ei tööta. Miks?». Kui suhtuda Cassandra'sse nagu relatsioonilisse andmebaasi, siis on see ideaalne viis elu lĂ”petamiseks. Ja ma ei propageeri seda, see on Venemaal keelatud. Te lihtsalt projekteerite midagi valesti.

NĂ€iteks tuleb tellija ja ĂŒtleb: «Ehitage meile andmebaas sarjade jaoks vĂ”i retseptide infosĂŒsteem. Meil on seal roogasid koos koostisosadega vĂ”i nimekiri sarjadest ja nĂ€itlejatest». Meil on rÔÔm: «Teeme seda!». See on kaks bait'i edasi saata, paar tabelit ja kĂ”ik on valmis, kĂ”ik töötab vĂ€ga kiiresti ja usaldusvÀÀrselt. Ja kĂ”ik on suurepĂ€rane, kuni tellijad ei tule ja ĂŒtle, et koduperenaised lahendavad veel ka vastupidi ĂŒlesande: neil on nimekiri koostisosadest ja nad tahavad teada, millist rooga nad soovivad valmistada. Te olete nĂŒĂŒd hukule mÀÀratud.

Selle pĂ”hjuseks on see, et Cassandra on hĂŒbriidandmebaas: see on samal ajal nii vĂ”tmevÀÀrtus kui ka salvestab andmeid laias veergudes. Java vĂ”i Kotlin keeles vĂ”iks seda niimoodi kirjeldada:

Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

See tĂ€hendab, et kaardis on sees veel jĂ€rjestatud kaart. Esimene vĂ”ti selles kaardis on Row key ehk Partition key — partitsioneerimise vĂ”ti. Teine vĂ”ti, mis viib juba jĂ€rjestatud kaardini, on Clustering key.

Andmebaasi hajutatusest illustreerimiseks joonistame kolm sĂ”lme. NĂŒĂŒd on vaja mĂ”ista, kuidas andmed sĂ”lmedele jaotada. Sest kui me paneme kĂ”ik ĂŒhte (sĂ”lmi vĂ”ib olla tuhandeid, kahte tuhat, viit — kui palju tahes), ei ole see just vĂ€ga hajutatud. SeetĂ”ttu on meil vaja matemaatilist funktsiooni, mis tagastab arvu. Lihtsalt numbri, pika int'i, mis jÀÀb teatud vahemikku. Ja meil on ĂŒks sĂ”lm, mis vastutab ĂŒhe vahemiku eest, teine — teise, n-nes — n-nda.

Cassandra. Kuidas mitte surra, kui tead vaid Oracle'it

See number saadakse hash-funktsiooni abil, mida rakendatakse just sellele, mida me nimetame Partition key. See on see veerg, mis on toodud Primary key direktiivis, ja see veerg, mis on esialgne ja peamine kaardistamise vĂ”ti. See mÀÀrab, millised andmed jĂ”uavad millisele sĂ”lmele. Tabel luuakse Cassandras peaaegu sama sĂŒntaksiga nagu SQL-is:

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

)

Primary key koosneb antud juhul ĂŒhest veerust, mis on samas ka partitseerimise vĂ”ti.

Kuidas meie kasutajad jaotuvad? Osa lĂ€heb ĂŒhele sĂ”lmele, osa teisele ja osa kolmandale. Tulemuseks on tavaline hash-tabel, see on ka kaardistus, Pythonis on see sĂ”nastik, samuti on see lihtne Key value-struktuur, mille kaudu saame lugeda kĂ”iki vÀÀrtusi ning lugeda ja kirjutada vĂ”tme abil.

Cassandra. Kuidas mitte surra, kui tead vaid Oracle'it

Select: kui allow filtering muutub full scan-iks, vÔi kuidas mitte teha

Kirjutame mingi select statementi: select * from users where user_id = . Tundub, et asi on Oracle’i moodi: kirjutame select, mÀÀrame tingimused ja kĂ”ik töötab, kasutajad saadakse kĂ€tte. Kuid kui valida nĂ€iteks kasutaja, kellel on teatud sĂŒnniaasta, siis Cassandra ĂŒtleb, et ei saa pĂ€ringut tĂ€ita. Sest tal ei ole aimugi, kuidas meie andmed sĂŒnniaasta kohta jaotuvad — tal on ainus vĂ”tme veerg. Siis ta ĂŒtleb: „Hea kĂŒll, ma saan siiski seda pĂ€ringut tĂ€ita. Lisage allow filtering.” Me lisame direktiivi ja kĂ”ik töötab. Ja sel hetkel juhtub kohutav asi.

Kui me katsetame testandmetega, siis on kĂ”ik suurepĂ€rane. Aga kui teete pĂ€ringu tootmises, kus meil on nĂ€iteks 4 miljonit kirjet, siis ei ole meil asjad just vĂ€ga hĂ€sti. Sest allow filtering — see on direktiiv, mis lubab Cassandrale koguda kĂ”ik andmed sellest tabelist kĂ”igilt sĂ”lmedelt, andmekeskustega (kui neid on palju selles klastris), ja siis alles seejĂ€rel filtreerida. See on analoogne Full Scan’iga ja vĂ€hesed on sellest elevil.

Kui me vajaksime kasutajaid ainult identifikaatorite jÀrgi, sobiks see meile. Kuid mÔnikord peame esitama teisi pÀringuid ja kehtestama muid filtreid. Seega peame meeles: see kÔik on meil kaart, millel on partitsioneerimisvÔti, kuid selle sees on sorteeritud kaart.

Ja sellel on samuti vĂ”ti, mida nimetame Clustering Key. See vĂ”ti koosneb veergudest, mille valime, millega Cassandra mĂ”istab, kuidas andmed fĂŒĂŒsiliselt sorteeritakse ja igas sĂ”lmes paiknevad. See tĂ€hendab, et teatud Partition key jaoks Clustering key ĂŒtleb, kuidas tĂ€pselt andmed sellele puule suruda, kuhu nad seal jÀÀvad.

See on tÔeliselt puu, seal kutsutakse lihtsalt esile komparaator, kuhu edastame teatud veergude kogumi objektina, ja see mÀÀratakse samuti veergude loendina.

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

Pöörake tĂ€helepanu primaarvĂ”tme direktiivile: selle esimene argument (meie juhul aasta) on alati partitsioonivĂ”ti. See vĂ”ib koosneda ĂŒhest vĂ”i mitmest veerust, see pole oluline. Kui veerge on mitu, tuleb see veel korra sulgudesse panna, et keele eeltöötleja mĂ”istaks, et tegemist on tĂ”epoolest primaarvĂ”tmega, mille jĂ€rel jĂ€rgivad kĂ”ik teised veerud - sissetulev vĂ”ti. Samuti edastatakse need vĂ”rreldes selles jĂ€rjekorras, milles need on. See tĂ€hendab, et esimene veerg on olulisem, teine - vĂ€hem oluline ja nii edasi. Nagu me kirjutame andmepĂ€ringute klasside puhul, nĂ€iteks vĂ”rreldes: loetleme veerud ja mÀÀrame, millised on olulisemad ja millised vĂ€hem. Cassandra's on see tinglikult öeldes andmepĂ€ringu klassi veerud, millele rakendatakse kirjutatud vĂ”rreldes.

Seame sorteerimise, rakendame piiranguid

Oluline on meeles pidada, et sorteerimisjĂ€rjekord (kas kasvav, kahanev vĂ”i ĂŒkskĂ”ik milline) mÀÀratakse hetkel, mil luuakse vĂ”ti, ja seda ei saa hiljem muuta. See mÀÀrab fĂŒĂŒsiliselt, kuidas andmed jĂ€rjestatakse ja kuhu need paigutatakse. Kui on vajalik muuta Clustering key vĂ”i sorteerimisjĂ€rjekorda, tuleb luua uus tabel ja andmed sinna ĂŒle kanda. Niisuguse juba olemasolevaga ei saa nii teha.

Cassandra. Kuidas mitte surra, kui tead vaid Oracle'it

Oleme tĂ€itnud oma tabeli kasutajatega ja nĂ€inud, et nad on jĂ€rjestatud alguses sĂŒnniaja jĂ€rgi ja siis sees igas sĂ”lmes palga ja kasutaja ID jĂ€rgi. NĂŒĂŒd saame teha valikuid, seades piirangud.

Kordub taas meie töötav where, and, ja kasutajad saavad meile ning kĂ”ik on jĂ€lle hĂ€sti. Kuid kui proovime kasutada ainult osa Clustering key'ist, mis on vĂ€hem tĂ€htis, siis Cassandra ĂŒtleb kohe, et ei leia meie kaardilt kohta, kus see objekt, millel on need vĂ€ljad komparatorina null, ja kus on see, mille just mÀÀrasime, — kus see asub. Pean jĂ€lle kĂ”ik andmed sellest sĂ”lmest ĂŒles tĂ”stma ja need filtreerima. Ja see on analoogne Full Scan'iga sĂ”lme piires, see on halb.

Igas olukorras loo uus tabel.

Kui soovime, et saaksime kasutajaid ID, vanuse vĂ”i palga alusel leida, siis mida teha? Mitte midagi. Tuleb lihtsalt kasutada kahte tabelit. Kui kasutajaid tuleb leida kolme erineva meetodi jĂ€rgi, siis on tabeleid kolm. Need ajad on möödas, kui pĂŒĂŒdsime kettaruumi kokku hoida. See on odavaim ressurss. See maksab tunduvalt vĂ€hem kui vastusaeg, mis vĂ”ib kasutajale saatuslikuks osutuda. Kasutajale on palju meeldivam saada midagi sekundiga, kui 10 minutiga.

Measime suuruse, denormaliseeritud andmete peale vĂ”imaldame paremat skaleerimist ja usaldusvÀÀrset toimimist. Tegelikult vĂ”ib klaster, mis koosneb kolmest andmekeskusest, milles igas on viis sĂ”lme, taluda ĂŒhe andmekeskuse tĂ€ielikku kadumist, sĂ€ilitades samas andmete vastuvĂ”etava taseme (kui midagi kindlasti ei kaota). Ja veel kaks sĂ”lme igas kahes ĂŒlejÀÀnud. Ja alles pĂ€rast seda algavad probleemid. See on ĂŒsna hea varundamine, mis maksab paar-kolm liigsest SSD-diskist ja protsessorist. Seega, et kasutada Cassandrat, mis ei ole SQL, kus pole seoseid ega vĂ€liseid vĂ”tmeid, tuleb teadmisi omada lihtsatest reeglitest.

Kujundame kÔik alates pÀringust. Peamine ei ole andmed, vaid see, kuidas rakendus nendega töötama hakkab. Kui rakendus vajab erinevate andmete saamist erinevates viisides vÔi sama andme saamiseks erinevates viisides, peame need paigaldama selliselt, et see oleks rakendusele mugav. Vastasel juhul sattume Full Scan'i, ja Cassandra ei too meile mingit eelist.

Andmed denormeerida on normaalne. Unustame normaalsed vormid, meil ei ole enam relatsioonilisi andmebaase. Paneme midagi 100 korda ja see jÀÀb 100 korda. See on ikka odavam kui puruneda.

Valime partitsioneerimiseks vĂ”tmed nii, et need oleks korralikult jaotatud. Me ei taha, et meie vĂ”tmete hash satuks kitsasse vahemikku. Ehkki, sĂŒnniaasta eeltoodud nĂ€ites on halb nĂ€ide. Tegelikult on see hea, kui meie kasutajad on sĂŒnniaasta jĂ€rgi korralikult jaotatud, ja halb, kui tegemist on 5. klassi Ă”pilastega — seal ei toimi partitsioneerimine hĂ€sti.

Sorteerimine valitakse ĂŒks kord Clustering Key loomise etapis. Kui seda on vaja muuta, tuleb meie tabel teise vĂ”tmega ĂŒmber tĂ”sta.

Ja kÔige tÀhtsam: kui meil on vaja andmeid 100 erineval viisil kÀtte saada, peame meil olema 100 erinevat tabelit.

Allikas: habr.com

Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster