Kasandra. Kako ne umrijeti ako poznaješ samo Oracle

Hej Habr.

Moje ime je Misha Butrimov, želio bih vam reći nešto o Cassandri. Moja će priča biti korisna onima koji se nikada nisu susreli s NoSQL bazama podataka - ima mnogo značajki implementacije i zamki o kojima trebate znati. A ako niste vidjeli ništa osim Oraclea ili bilo koje druge relacijske baze podataka, ove stvari će vam spasiti život.

Što je tako dobro u Cassandri? To je NoSQL baza podataka dizajnirana bez ijedne točke kvara koja se dobro skalira. Ako trebate dodati nekoliko terabajta za neku bazu podataka, jednostavno dodajte čvorove u prsten. Proširiti ga na drugi podatkovni centar? Dodajte čvorove u klaster. Povećati obrađeni RPS? Dodajte čvorove u klaster. Djeluje i u suprotnom smjeru.

Kasandra. Kako ne umrijeti ako poznaješ samo Oracle

U čemu je još dobra? Radi se o obradi velikog broja zahtjeva. Ali koliko je puno? 10, 20, 30, 40 tisuća zahtjeva u sekundi nije puno. 100 tisuća zahtjeva u sekundi za snimanje - također. Postoje tvrtke koje su rekle da drže 2 milijuna zahtjeva u sekundi. Vjerojatno će morati vjerovati.

A u principu, Cassandra ima jednu veliku razliku od relacijskih podataka - uopće im nije slična. I ovo je vrlo važno zapamtiti.

Ne funkcionira sve što izgleda isto

Jednom mi je kolega došao i pitao: “Ovo je CQL Cassandra upitni jezik, i ima select iskaz, ima where, ima and. Pišem pisma i ne ide. Zašto?". Tretiranje Cassandre kao relacijske baze podataka savršen je način za počinjenje nasilnog samoubojstva. I ne promoviram to, to je u Rusiji zabranjeno. Samo ćeš nešto krivo dizajnirati.

Na primjer, dođe nam kupac i kaže: “Idemo napraviti bazu podataka za TV serije ili bazu podataka za imenik recepata. Tamo ćemo imati jela s hranom ili popis TV serija i glumaca u njima.” Radosno kažemo: "Idemo!" Samo pošaljite dva bajta, par znakova i gotovi ste, sve će raditi vrlo brzo i pouzdano. I sve je u redu dok mušterije ne dođu i kažu da domaćice rješavaju i suprotan problem: imaju popis proizvoda i žele znati koje jelo žele skuhati. Vi ste mrtvi.

To je zato što je Cassandra hibridna baza podataka: ona istovremeno pruža ključnu vrijednost i pohranjuje podatke u širokim stupcima. U Javi ili Kotlinu to bi se moglo opisati ovako:

Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

Odnosno karta koja sadrži i sortiranu kartu. Prvi ključ ove mape je tipka reda ili tipka particije - particioni ključ. Drugi ključ, koji je ključ za već sortiranu kartu, je ključ grupiranja.

Kako bismo ilustrirali distribuciju baze podataka, nacrtajmo tri čvora. Sada morate razumjeti kako rastaviti podatke na čvorove. Jer ako sve trpamo u jedno (usput, može ih biti tisuću, dvije tisuće, pet - koliko hoćete), tu se zapravo i ne radi o raspodjeli. Stoga nam treba matematička funkcija koja će vratiti broj. Samo broj, dugi int koji će pasti u neki raspon. I imat ćemo jedan čvor odgovoran za jedan raspon, drugi za drugi, n-ti za n-ti.

Kasandra. Kako ne umrijeti ako poznaješ samo Oracle

Taj se broj uzima pomoću hash funkcije koja se primjenjuje na ono što nazivamo particijski ključ. Ovo je stupac koji je naveden u direktivi primarnog ključa, a ovo je stupac koji će biti prvi i najosnovniji ključ karte. Određuje koji će čvor primati koje podatke. Tablica se stvara u Cassandri s gotovo istom sintaksom kao u SQL-u:

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

)

Primarni ključ se u ovom slučaju sastoji od jednog stupca, a ujedno je i particioni ključ.

Kakva će biti učinkovitost naših korisnika? Neki će otići u jedan čvor, neki u drugi, a neki u treći. Rezultat je obična hash tablica, također poznata kao karta, također poznata kao rječnik u Pythonu, ili jednostavna struktura vrijednosti ključa iz koje možemo čitati sve vrijednosti, čitati i pisati po ključu.

Kasandra. Kako ne umrijeti ako poznaješ samo Oracle

Odaberite: kada se dopušteno filtriranje pretvara u potpuno skeniranje ili što ne raditi

Napišimo neku select izjavu: select * from users where, userid = . Ispada kao u Oracleu: napišemo select, specificiramo uvjete i sve radi, korisnici dobivaju. Ali ako odaberete, primjerice, korisnika s određenom godinom rođenja, Cassandra se žali da ne može ispuniti zahtjev. Budući da ona ne zna baš ništa o tome kako distribuiramo podatke o godini rođenja - ona ima samo jedan stupac označen kao ključ. Zatim kaže: “U redu, još uvijek mogu ispuniti ovaj zahtjev. Dodaj dopusti filtriranje." Dodamo direktivu, sve radi. I u ovom trenutku se događa nešto strašno.

Kad radimo na testnim podacima, sve je u redu. A kad izvršite upit u produkciji, gdje imamo, primjerice, 4 milijuna zapisa, onda nam baš i nije sve dobro. Zato što je dopusti filtriranje direktiva koja omogućuje Cassandri da prikupi sve podatke iz ove tablice sa svih čvorova, svih podatkovnih centara (ako ih ima mnogo u ovom klasteru), i tek onda ih filtrira. Ovo je analogni Full Scan, i rijetko tko je oduševljen njime.

Da nam trebaju samo korisnici po ID-u, ovo bi nam odgovaralo. Ali ponekad moramo napisati druge upite i nametnuti druga ograničenja na odabir. Stoga se sjećamo: ovo je sve karta koja ima particioni ključ, ali unutar nje je sortirana karta.

I ona također ima ključ, koji zovemo Ključ grupiranja. Ovaj ključ, koji se pak sastoji od stupaca koje odaberemo, uz pomoć kojih Cassandra razumije kako su njezini podaci fizički sortirani i kako će se nalaziti na svakom čvoru. To jest, za neki ključ particije, ključ grupiranja će vam točno reći kako gurnuti podatke u ovo stablo, koje će mjesto tamo zauzeti.

Ovo je zapravo stablo, tu se jednostavno zove komparator, kojem prosljeđujemo određeni skup stupaca u obliku objekta, a također je specificiran kao popis stupaca.

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

Obratite pozornost na direktivu primarnog ključa; njen prvi argument (u našem slučaju godina) uvijek je particijski ključ. Može se sastojati od jednog ili više stupaca, nije bitno. Ako postoji nekoliko stupaca, potrebno ga je ponovno ukloniti u zagradama kako bi pretprocesor jezika shvatio da je to primarni ključ, a iza njega su svi ostali stupci ključ klasteriranja. U tom će slučaju biti preneseni u komparator redoslijedom kojim se pojavljuju. To jest, prvi stupac je značajniji, drugi je manje značajan, i tako dalje. Kako pišemo, primjerice, jednako polja za klase podataka: ispisujemo polja i za njih pišemo koja su veća, a koja manja. U Cassandri su to, relativno govoreći, polja klase podataka na koja će se primijeniti jednakosti napisane za nju.

Postavljamo sortiranje i namećemo ograničenja

Morate zapamtiti da se redoslijed sortiranja (silazni, uzlazni, bilo koji) postavlja u istom trenutku kada se kreira ključ i ne može se kasnije mijenjati. Fizički određuje kako će podaci biti sortirani i kako će biti pohranjeni. Ako trebate promijeniti ključ klasteriranja ili redoslijed sortiranja, morat ćete stvoriti novu tablicu i prenijeti podatke u nju. Ovo neće funkcionirati s postojećim.

Kasandra. Kako ne umrijeti ako poznaješ samo Oracle

Ispunili smo našu tablicu korisnicima i vidjeli da su upali u prsten, prvo po godini rođenja, a zatim unutar svakog čvora po plaći i ID-u korisnika. Sada možemo birati nametanjem ograničenja.

Opet se pojavljuje naš radni where, and, i dobijemo korisnike, i opet je sve u redu. Ali ako pokušamo upotrijebiti samo dio ključa klasteriranja, i to manje značajan, tada će se Cassandra odmah požaliti da ne može pronaći mjesto na našoj mapi gdje je ovaj objekt, koji ima ova polja za nulti komparator, i ovaj to je upravo postavljeno, - gdje leži. Morat ću ponovno izvući sve podatke iz ovog čvora i filtrirati ih. A ovo je analogija potpunog skeniranja unutar čvora, ovo je loše.

U bilo kojoj nejasnoj situaciji izradite novu tablicu

Ako želimo imati mogućnost ciljanja korisnika prema ID-u, ili prema dobi, ili prema plaći, što trebamo učiniti? Ništa. Koristite samo dvije tablice. Ako trebate doprijeti do korisnika na tri različita načina, postojat će tri tablice. Prošli su dani kada smo štedjeli prostor na vijku. Ovo je najjeftiniji resurs. To košta puno manje od vremena odgovora, što može biti štetno za korisnika. Korisniku je mnogo ugodnije primiti nešto u sekundi nego u 10 minuta.

Mijenjamo nepotreban prostor i denormalizirane podatke za mogućnost dobrog skaliranja i pouzdanog rada. Uostalom, zapravo, klaster koji se sastoji od tri podatkovna centra, od kojih svaki ima pet čvorova, s prihvatljivom razinom očuvanosti podataka (kada se ništa ne gubi), može u potpunosti preživjeti smrt jednog podatkovnog centra. I još dva čvora u svakom od preostala dva. I tek nakon toga počinju problemi. Ovo je prilično dobra redundancija, vrijedi nekoliko dodatnih SSD diskova i procesora. Dakle, da biste koristili Cassandru, koja nikada nije SQL, u kojoj nema odnosa, stranih ključeva, morate znati jednostavna pravila.

Dizajniramo sve prema Vašem zahtjevu. Glavna stvar nisu podaci, već kako će aplikacija s njima raditi. Ako treba primiti različite podatke na različite načine ili iste podatke na različite načine, moramo to postaviti na način koji je prikladan za aplikaciju. U suprotnom, nećemo uspjeti u Full Scanu i Cassandra nam neće dati nikakvu prednost.

Denormalizacija podataka je norma. Zaboravljamo na normalne forme, više nemamo relacijske baze podataka. Ako nešto spustimo 100 puta, ono će 100 puta leći. Još uvijek je jeftinije nego stati.

Odaberemo ključeve za particioniranje tako da se normalno distribuiraju. Ne želimo da hash naših ključeva padne u jedan uski raspon. Odnosno, godina rođenja u gornjem primjeru je loš primjer. Točnije, dobro je ako su naši korisnici normalno raspoređeni po godinama rođenja, a loše ako je riječ o učenicima 5. razreda - tu particioniranje neće biti baš dobro.

Razvrstavanje se odabire jednom u fazi stvaranja ključa klasteriranja. Ako je treba promijeniti, morat ćemo ažurirati našu tablicu drugim ključem.

I ono najvažnije: ako iste podatke trebamo dohvatiti na 100 različitih načina, tada ćemo imati 100 različitih tablica.

Izvor: www.habr.com

Dodajte komentar