Cassandra. Ako nezomrieť, ak poznáte iba Oracle

Ahoj Habr.

Volám sa Misha Butrimov, rád by som vám povedal niečo o Cassandre. Môj príbeh bude užitočný pre tých, ktorí sa s NoSQL databázami nikdy nestretli – má veľa implementačných funkcií a úskalí, o ktorých musíte vedieť. A ak ste nevideli nič iné ako Oracle alebo inú relačná databázu, tieto veci vám zachránia život.

Čo je na Cassandre také dobré? Je to databáza NoSQL navrhnutá bez jediného bodu zlyhania, ktorá sa dobre škáluje. Ak potrebujete pridať pár terabajtov pre nejakú databázu, jednoducho pridáte uzly do kruhu. Rozbaliť ho do iného dátového centra? Pridajte uzly do klastra. Zvýšiť spracované RPS? Pridajte uzly do klastra. Funguje to aj v opačnom smere.

Cassandra. Ako nezomrieť, ak poznáte iba Oracle

V čom je ešte dobrá? Ide o vybavovanie množstva žiadostí. Ale koľko je veľa? 10, 20, 30, 40 tisíc požiadaviek za sekundu nie je veľa. 100 tisíc požiadaviek za sekundu na nahrávanie - tiež. Existujú spoločnosti, ktoré uviedli, že uchovávajú 2 milióny žiadostí za sekundu. Asi tomu budú musieť veriť.

A v zásade má Cassandra od relačných údajov jeden veľký rozdiel – vôbec sa im nepodobá. A to je veľmi dôležité mať na pamäti.

Nie všetko, čo vyzerá rovnako, funguje rovnako

Raz za mnou prišiel kolega a spýtal sa: „Tu je dopytovací jazyk CQL Cassandra a má príkaz select, má kde, má a. Píšem listy a nejde to. Prečo?". Zaobchádzať s Cassandrou ako s databázou vzťahov je dokonalý spôsob, ako spáchať násilnú samovraždu. A nepropagujem to, v Rusku je to zakázané. Len si niečo zle navrhneš.

Napríklad k nám príde zákazník a povie: „Poďme vybudovať databázu pre televízne seriály alebo databázu pre adresár receptov. Budeme tam mať jedlá alebo zoznam televíznych seriálov a hercov v ňom.“ Radostne hovoríme: "Poďme!" Stačí poslať dva bajty, pár znakov a hotovo, všetko bude fungovať veľmi rýchlo a spoľahlivo. A všetko je v poriadku, kým neprídu zákazníčky a nepovedia, že gazdinky riešia aj opačný problém: majú zoznam produktov a chcú vedieť, aké jedlo chcú uvariť. Si mŕtvy.

Cassandra je totiž hybridná databáza: súčasne poskytuje kľúčovú hodnotu a ukladá údaje do širokých stĺpcov. V Jave alebo Kotline by sa to dalo opísať takto:

Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

Teda mapu, ktorá obsahuje aj zoradenú mapu. Prvým kľúčom k tejto mape je kľúč Row alebo Partition key – kľúč na rozdelenie. Druhým kľúčom, ktorý je kľúčom k už zoradenej mape, je kláves Clustering.

Na ilustráciu rozloženia databázy nakreslíme tri uzly. Teraz musíte pochopiť, ako rozložiť údaje na uzly. Pretože ak všetko napcháme do jedného (mimochodom, môže ich byť tisíc, dvetisíc, päť – koľko chcete), o distribúciu tu naozaj nejde. Preto potrebujeme matematickú funkciu, ktorá vráti číslo. Len číslo, dlhý interval, ktorý bude spadať do určitého rozsahu. A budeme mať jeden uzol zodpovedný za jeden rozsah, druhý za druhý, n-tý za n-tý.

Cassandra. Ako nezomrieť, ak poznáte iba Oracle

Toto číslo sa získa pomocou hašovacej funkcie, ktorá sa aplikuje na to, čo nazývame kľúč oddielu. Toto je stĺpec, ktorý je špecifikovaný v direktíve Primary key, a toto je stĺpec, ktorý bude prvým a najzákladnejším kľúčom mapy. Určuje, ktorý uzol bude prijímať aké údaje. V Cassandra sa vytvorí tabuľka s takmer rovnakou syntaxou ako v SQL:

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

)

Primárny kľúč v tomto prípade pozostáva z jedného stĺpca a je to aj rozdeľovací kľúč.

Ako budú fungovať naši používatelia? Niektorí pôjdu do jedného uzla, niektorí do iného a niektorí do tretieho. Výsledkom je obyčajná hašovacia tabuľka, známa aj ako mapa, známa aj ako slovník v Pythone, alebo jednoduchá kľúčová hodnotová štruktúra, z ktorej môžeme čítať a zapisovať všetky hodnoty podľa kľúča.

Cassandra. Ako nezomrieť, ak poznáte iba Oracle

Vyberte: keď sa povolenie filtrovania zmení na úplnú kontrolu alebo čo nerobiť

Napíšme nejaké vybrané vyhlásenie: select * from users where, userid = . Dopadá to ako v Oracle: napíšeme select, špecifikujeme podmienky a všetko funguje, užívatelia to dostanú. Ak však vyberiete napríklad používateľa s určitým rokom narodenia, Cassandra sa sťažuje, že nemôže splniť požiadavku. Pretože nevie vôbec nič o tom, ako distribuujeme údaje o roku narodenia - má len jeden stĺpec označený ako kľúč. Potom povie: „Dobre, stále môžem splniť túto požiadavku. Pridať povolenie filtrovania." Pridávame smernicu, všetko funguje. A v tejto chvíli sa stane niečo hrozné.

Keď spustíme testovacie dáta, všetko je v poriadku. A keď spustíte dotaz vo výrobe, kde máme napríklad 4 milióny záznamov, tak nám nie je všetko veľmi dobré. Pretože allow filtering je direktíva, ktorá umožňuje Cassandre zhromaždiť všetky dáta z tejto tabuľky zo všetkých uzlov, všetkých dátových centier (ak ich je v tomto klastri veľa) a až potom ich filtrovať. Toto je analóg úplného skenovania a málokto je s ním spokojný.

Ak by sme potrebovali používateľov iba podľa ID, vystačili by sme si s týmto. Niekedy však potrebujeme napísať ďalšie dotazy a uložiť ďalšie obmedzenia na výber. Preto si pamätáme: toto všetko je mapa, ktorá má rozdeľovací kľúč, ale vo vnútri je zoradená mapa.

A má aj kľúč, ktorý nazývame Clustering Key. Tento kľúč, ktorý sa zase skladá zo stĺpcov, ktoré vyberieme, pomocou ktorých Cassandra chápe, ako sú jej údaje fyzicky triedené a budú umiestnené na každom uzle. To znamená, že pre niektorý Partition kľúč vám kľúč Clustering presne povie, ako vložiť údaje do tohto stromu, aké miesto tam zaberie.

Toto je naozaj strom, jednoducho sa tam volá komparátor, ktorému odovzdávame určitú množinu stĺpcov vo forme objektu a je špecifikovaný aj ako zoznam stĺpcov.

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

Venujte pozornosť direktíve Primárny kľúč, jej prvým argumentom (v našom prípade rok) je vždy Partition key. Môže pozostávať z jedného alebo viacerých stĺpcov, na tom nezáleží. Ak existuje niekoľko stĺpcov, je potrebné ich znova odstrániť v zátvorkách, aby jazykový preprocesor pochopil, že toto je primárny kľúč a za ním sú všetky ostatné stĺpce klastrový kľúč. V takom prípade sa prenesú do porovnávača v poradí, v akom sa objavia. To znamená, že prvý stĺpec je výraznejší, druhý je menej významný atď. Ako píšeme napríklad polia rovná sa dátové triedy: vypíšeme polia a k nim napíšeme, ktoré sú väčšie a ktoré menšie. V Cassandre sú to relatívne vzaté polia dátovej triedy, na ktoré sa bude vzťahovať rovná sa pre ňu napísaná.

Nastavujeme triedenie a zavádzame obmedzenia

Musíte pamätať na to, že poradie zoradenia (zostupne, vzostupne, čokoľvek) sa nastavuje v rovnakom momente, keď je kľúč vytvorený, a nemožno ho neskôr zmeniť. Fyzicky určuje, ako budú dáta triedené a ako budú uložené. Ak potrebujete zmeniť kľúč klastrovania alebo poradie triedenia, budete musieť vytvoriť novú tabuľku a preniesť do nej údaje. Toto nebude fungovať s existujúcim.

Cassandra. Ako nezomrieť, ak poznáte iba Oracle

Naplnili sme náš stôl používateľmi a videli sme, že sa dostali do kruhu, najprv podľa roku narodenia a potom vnútri na každom uzle podľa platu a ID používateľa. Teraz si môžeme vyberať zavedením obmedzení.

Opäť sa objavuje náš pracovný where, anda získame používateľov a všetko je opäť v poriadku. Ak sa však pokúsime použiť iba časť kľúča klastra a menej významnú, Cassandra sa okamžite sťažuje, že nemôže nájsť miesto na našej mape, kde by tento objekt, ktorý má tieto polia pre nulový komparátor, a tento to bolo práve nastavené, - kde leží. Budem musieť znova stiahnuť všetky údaje z tohto uzla a filtrovať ich. A toto je analóg úplného skenovania v uzle, to je zlé.

V akejkoľvek nejasnej situácii vytvorte novú tabuľku

Čo by sme mali urobiť, ak chceme byť schopní zacieliť na používateľov podľa ID, veku alebo platu? Nič. Stačí použiť dve tabuľky. Ak potrebujete osloviť používateľov tromi rôznymi spôsobmi, budú k dispozícii tri tabuľky. Časy, keď sme šetrili miesto na skrutke, sú preč. Toto je najlacnejší zdroj. Stojí to oveľa menej ako čas odozvy, čo môže byť pre používateľa škodlivé. Pre používateľa je oveľa príjemnejšie dostať niečo za sekundu ako za 10 minút.

Nepotrebný priestor a denormalizované údaje vymieňame za schopnosť dobre škálovať a spoľahlivo fungovať. Koniec koncov, v skutočnosti klaster, ktorý pozostáva z troch dátových centier, z ktorých každé má päť uzlov, s prijateľnou úrovňou zachovania dát (keď sa nič nestratí), je schopný úplne prežiť smrť jedného dátového centra. A ďalšie dva uzly v každom zo zvyšných dvoch. A až potom začnú problémy. To je celkom dobrá redundancia, stojí za to pár SSD diskov a procesorov navyše. Preto, aby ste mohli používať Cassandru, ktorá nikdy nie je SQL, v ktorej neexistujú žiadne vzťahy, cudzie kľúče, musíte poznať jednoduché pravidlá.

Všetko navrhneme podľa vašej požiadavky. Hlavné nie sú dáta, ale to, ako s nimi bude aplikácia pracovať. Ak potrebuje prijímať rôzne údaje rôznymi spôsobmi alebo rovnaké údaje rôznymi spôsobmi, musíme to dať spôsobom, ktorý je pre aplikáciu vhodný. V opačnom prípade zlyháme v Úplnom skenovaní a Cassandra nám nedá žiadnu výhodu.

Denormalizácia údajov je normou. Zabúdame na normálne formy, už nemáme relačné databázy. Ak niečo položíme 100-krát, 100-krát si to ľahne. Stále je to lacnejšie ako zastaviť.

Kľúče na rozdelenie vyberáme tak, aby boli distribuované normálne. Nechceme, aby hash našich kľúčov spadal do jedného úzkeho rozsahu. To znamená, že rok narodenia v príklade vyššie je zlý príklad. Presnejšie povedané, je dobré, ak sú naši používatelia normálne rozdelení podľa ročníka narodenia, a zlé, ak sa bavíme o žiakoch 5. ročníka – rozdelenie tam nebude veľmi dobré.

Triedenie sa vyberie raz vo fáze vytvorenia kľúča klastra. Ak to bude potrebné zmeniť, budeme musieť aktualizovať našu tabuľku s iným kľúčom.

A najdôležitejšia vec: ak potrebujeme získať rovnaké údaje 100 rôznymi spôsobmi, potom budeme mať 100 rôznych tabuliek.

Zdroj: hab.com

Pridať komentár