Cassandra. Kako ne umrijeti ako samo poznaješ Oracle

Hej Habr.

Moje ime je Miša Butrimov, želeo bih da vam kažem nešto o Kasandri. Moja priča će biti korisna onima koji se nikada nisu susreli sa NoSQL bazama podataka - ona ima puno implementacijskih karakteristika i zamki o kojima morate znati. A ako niste vidjeli ništa osim Oraclea ili bilo koje druge relacijske baze podataka, ove stvari će vam spasiti život.

Šta je tako dobro kod Kasandre? To je NoSQL baza podataka dizajnirana bez ijedne tač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.

Cassandra. Kako ne umrijeti ako samo poznaješ Oracle

U čemu je još dobra? Radi se o obradi velikog broja zahtjeva. Ali koliko je puno? 10, 20, 30, 40 hiljada zahteva u sekundi nije mnogo. 100 hiljada zahteva u sekundi za snimanje - takođe. Postoje kompanije koje kažu da drže 2 miliona zahtjeva u sekundi. Verovatno će morati da poveruju.

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

Ne radi sve što izgleda isto

Jednom mi je došao kolega i pitao: „Evo CQL Cassandra jezika upita, i on ima naredbu za odabir, ima gdje, ima i. Pišem pisma i ne ide. Zašto?". Tretiranje Cassandre kao relacijske baze podataka je savršen način da se izvrši nasilno samoubistvo. I ne promovišem to, zabranjeno je u Rusiji. Samo ćeš dizajnirati nešto pogrešno.

Na primjer, dođe nam kupac i kaže: „Hajde da napravimo bazu podataka za TV serije, ili bazu podataka za imenik recepata. Tamo ćemo imati jela sa hranom ili spisak TV serija i glumaca u njemu.” 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 listu proizvoda, a žele da znaju koje jelo žele da skuvaju. Mrtav si.

To je zato što je Cassandra hibridna baza podataka: ona istovremeno daje ključnu vrijednost i pohranjuje podatke u široke stupce. U Javi ili Kotlinu, to bi se moglo opisati ovako:

Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

To jest, karta koja također sadrži sortiranu kartu. Prvi ključ ove mape je tipka za red ili particiona tipka - particiona tipka. Drugi ključ, koji je ključ za već sortiranu mapu, je ključ za grupisanje.

Da bismo ilustrovali distribuciju baze podataka, nacrtajmo tri čvora. Sada morate razumjeti kako dekomponirati podatke u čvorove. Jer ako sve strpamo u jedno (usput, može ih biti hiljadu, dve hiljade, pet - koliko hoćete), ovde se zapravo i ne radi o distribuciji. Stoga nam je potrebna matematička funkcija koja će vratiti broj. Samo broj, dugi int koji će pasti u neki raspon. I imaćemo jedan čvor odgovoran za jedan opseg, drugi za drugi, n-ti za n-ti.

Cassandra. Kako ne umrijeti ako samo poznaješ Oracle

Ovaj broj se uzima pomoću hash funkcije, koja se primjenjuje na ono što zovemo particijski ključ. Ovo je kolona koja je navedena u direktivi o primarnom ključu, a ovo je kolona koja će biti prvi i najosnovniji ključ mape. Određuje koji će čvor primiti koje podatke. Tabela je kreirana u Cassandri sa 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 jedne kolone, a ujedno je i particioni ključ.

Kako će se ponašati naši korisnici? Neki će ići u jedan čvor, neki u drugi, a neki u treći. Rezultat je obična hash tablica, također poznata kao mapa, 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.

Cassandra. Kako ne umrijeti ako samo poznaješ Oracle

Odaberite: kada se dozvoli filtriranje pretvori u potpuno skeniranje ili šta ne raditi

Hajde da napišemo neku izjavu za odabir: select * from users where, userid = . Ispada kao u Oracleu: pišemo select, specificiramo uslove i sve radi, korisnici to dobijaju. Ali ako odaberete, na primjer, korisnika s određenom godinom rođenja, Cassandra se žali da ne može ispuniti zahtjev. Zato što ona ne zna baš ništa o tome kako distribuiramo podatke o godini rođenja - ona ima samo jednu kolonu označenu kao ključ. Zatim ona kaže: „U redu, još uvijek mogu ispuniti ovaj zahtjev. Dodaj dozvoli filtriranje." Dodamo direktivu, sve radi. I u ovom trenutku se dešava nešto strašno.

Kada radimo na testnim podacima, sve je u redu. A kada izvršite upit u produkciji, gdje imamo, na primjer, 4 miliona zapisa, onda nam nije baš sve dobro. Jer dozvoli filtriranje je direktiva koja omogućava Cassandri da prikupi sve podatke iz ove tabele sa svih čvorova, svih centara podataka (ako ih ima mnogo u ovom klasteru), i tek onda ih filtrira. Ovo je analog Full Scan-a i rijetko ko je oduševljen njime.

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

I ona takođe ima ključ, koji mi zovemo ključ za grupisanje. Ovaj ključ, koji se zauzvrat sastoji od stupaca koje odabiremo, uz pomoć kojih Cassandra razumije kako su njeni podaci fizički sortirani i kako će se nalaziti na svakom čvoru. Odnosno, za neki particijski ključ, ključ za grupisanje će vam reći kako tačno ugurati podatke u ovo stablo, koje će mjesto tamo zauzeti.

Ovo je stvarno stablo, tamo se jednostavno poziva komparator, kojem prosljeđujemo određeni skup stupaca u obliku objekta, a također je specificiran kao lista kolona.

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

Obratite pažnju na direktivu o primarnom ključu; njen prvi argument (u našem slučaju, godina) je uvijek Particijski ključ. Može se sastojati od jedne ili više kolona, ​​nije bitno. Ako postoji nekoliko kolona, ​​potrebno ga je ponovo ukloniti u zagradama kako bi pretprocesor jezika shvatio da je ovo primarni ključ, a iza njega svi ostali stupci su ključ za grupisanje. U ovom slučaju, oni će se prenositi u komparatoru redoslijedom kojim se pojavljuju. Odnosno, prva kolona je značajnija, druga manje značajna, itd. Način na koji pišemo, na primjer, jednak je poljima za klase podataka: navodimo polja, a za njih pišemo koja su veća, a koja manja. U Cassandri, to su, relativno govoreći, polja klase podataka na koja će se primijeniti jednaki za nju.

Postavljamo sortiranje i namećemo ograničenja

Morate imati na umu da je redoslijed sortiranja (silazni, rastući, bilo koji) postavljen u istom trenutku kada je ključ kreiran i ne može se kasnije mijenjati. On fizički određuje kako će podaci biti sortirani i kako će biti pohranjeni. Ako trebate promijeniti ključ klastera ili redoslijed sortiranja, morat ćete kreirati novu tablicu i prenijeti podatke u nju. Ovo neće funkcionirati s postojećim.

Cassandra. Kako ne umrijeti ako samo poznaješ Oracle

Popunili smo našu tabelu korisnicima i vidjeli da su upali u prsten, prvo po godini rođenja, a zatim unutra na svakom čvoru po plati i ID-u korisnika. Sada možemo birati nametanjem ograničenja.

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

U bilo kojoj nejasnoj situaciji, kreirajte novu tabelu

Ako želimo da budemo u mogućnosti da ciljamo korisnike po ID-u, ili po godinama, ili po plaći, šta da radimo? Ništa. Koristite samo dva stola. Ako trebate doći do korisnika na tri različita načina, postojat će tri tabele. Prošlo je vrijeme kada smo štedjeli prostor na šrafovima. Ovo je najjeftiniji resurs. To košta mnogo manje od vremena odgovora, što može biti štetno za korisnika. Korisniku je mnogo ugodnije da dobije nešto u sekundi nego za 10 minuta.

Razmjenjujemo nepotreban prostor i denormalizirane podatke za mogućnost dobrog skaliranja i pouzdanog rada. Uostalom, zapravo, klaster koji se sastoji od tri data centra, od kojih svaki ima pet čvorova, sa prihvatljivim nivoom očuvanja podataka (kada se ništa ne izgubi), u stanju je 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. Stoga, da biste koristili Cassandru, koja nikada nije SQL, u kojoj nema relacija, stranih ključeva, morate znati jednostavna pravila.

Dizajniramo sve po Vašem zahtjevu. Glavna stvar nisu podaci, već kako će aplikacija raditi s njima. Ako treba da primi različite podatke na različite načine ili iste podatke na različite načine, moramo ih postaviti na način koji je pogodan za aplikaciju. U suprotnom, nećemo uspjeti u Full Scan 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 ležati 100 puta. I dalje je jeftinije nego stati.

Odabiremo ključeve za particioniranje tako da se normalno distribuiraju. Ne želimo da heš naših ključeva padne u jedan uski raspon. Odnosno, godina rođenja u gornjem primjeru je loš primjer. Tač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 - podjela tamo neće biti baš dobra.

Sortiranje se bira jednom u fazi kreiranja ključa klastera. Ako treba da se promeni, moraćemo da ažuriramo našu tabelu drugim ključem.

I ono što je najvažnije: ako trebamo dohvatiti iste podatke na 100 različitih načina, onda ćemo imati 100 različitih tabela.

izvor: www.habr.com

Dodajte komentar