Kasandra. Si të mos vdisni nëse dini vetëm Oracle

Hej Habr.

Unë quhem Misha Butrimov, do të doja t'ju tregoja pak për Kasandrën. Historia ime do të jetë e dobishme për ata që nuk kanë hasur kurrë në bazat e të dhënave NoSQL - ai ka shumë veçori dhe gracka të zbatimit për të cilat duhet të dini. Dhe nëse nuk keni parë asgjë tjetër përveç Oracle ose ndonjë bazë të dhënash tjetër relacionale, këto gjëra do t'ju shpëtojnë jetën.

Çfarë ka kaq të mirë për Cassandra? Është një bazë të dhënash NoSQL e krijuar pa një pikë të vetme dështimi që shkallëzohet mirë. Nëse ju duhet të shtoni disa terabajt për disa bazë të dhënash, thjesht shtoni nyje në unazë. Të zgjerohet në një qendër tjetër të dhënash? Shtoni nyje në grup. Të rritet RPS e përpunuar? Shtoni nyje në grup. Punon edhe në drejtim të kundërt.

Kasandra. Si të mos vdisni nëse dini vetëm Oracle

Në çfarë tjetër është e mirë ajo? Bëhet fjalë për trajtimin e shumë kërkesave. Por sa është shumë? 10, 20, 30, 40 mijë kërkesa në sekondë nuk janë shumë. 100 mijë kërkesa në sekondë për regjistrim - gjithashtu. Ka kompani që kanë thënë se mbajnë 2 milionë kërkesa në sekondë. Ata ndoshta do të duhet ta besojnë atë.

Dhe në parim, Cassandra ka një ndryshim të madh nga të dhënat relacionale - nuk është aspak e ngjashme me to. Dhe kjo është shumë e rëndësishme të mbani mend.

Jo çdo gjë që duket e njëjtë funksionon njësoj

Një herë një koleg erdhi tek unë dhe më pyeti: “Këtu është një gjuhë pyetjesh CQL Cassandra, dhe ka një deklaratë të zgjedhur, ka ku, ka dhe. Shkruaj letra dhe nuk funksionon. Pse?". Trajtimi i Kasandrës si një bazë të dhënash relacionale është mënyra e përsosur për të kryer vetëvrasje të dhunshme. Dhe unë nuk po e promovoj atë, është e ndaluar në Rusi. Ju thjesht do të dizajnoni diçka të gabuar.

Për shembull, një klient vjen tek ne dhe thotë: “Le të ndërtojmë një bazë të dhënash për serialet televizive, ose një bazë të dhënash për një drejtori recetash. Ne do të kemi gatime ushqimore atje ose një listë me seriale televizive dhe aktorë në të.” Ne themi me gëzim: "Le të shkojmë!" Thjesht dërgoni dy bajt, disa shenja dhe keni mbaruar, gjithçka do të funksionojë shumë shpejt dhe me besueshmëri. Dhe gjithçka është në rregull derisa klientët vijnë dhe thonë se amvisat po zgjidhin edhe problemin e kundërt: kanë një listë produktesh dhe duan të dinë se çfarë pjate duan të gatuajnë. Je i vdekur.

Kjo ndodh sepse Cassandra është një bazë të dhënash hibride: ajo njëkohësisht siguron një vlerë kyçe dhe ruan të dhënat në kolona të gjera. Në Java ose Kotlin, mund të përshkruhet kështu:

Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

Kjo është, një hartë që përmban gjithashtu një hartë të renditur. Çelësi i parë në këtë hartë është tasti i rreshtit ose çelësi i ndarjes - çelësi i ndarjes. Çelësi i dytë, i cili është çelësi i një harte tashmë të renditur, është çelësi Clustering.

Për të ilustruar shpërndarjen e bazës së të dhënave, le të vizatojmë tre nyje. Tani duhet të kuptoni se si t'i zbërtheni të dhënat në nyje. Sepse nëse grumbullojmë gjithçka në një (nga rruga, mund të ketë një mijë, dy mijë, pesë - sa të doni), kjo nuk ka të bëjë me shpërndarjen. Prandaj, na duhet një funksion matematik që do të kthejë një numër. Vetëm një numër, një int i gjatë që do të bjerë në një gamë. Dhe ne do të kemi një nyje përgjegjëse për një varg, e dyta për të dytën, e n-ta për të ntën.

Kasandra. Si të mos vdisni nëse dini vetëm Oracle

Ky numër merret duke përdorur një funksion hash, i cili aplikohet në atë që ne e quajmë çelësi i ndarjes. Kjo është kolona që specifikohet në direktivën e çelësit primar, dhe kjo është kolona që do të jetë çelësi i parë dhe më themelor i hartës. Ajo përcakton se cila nyje do të marrë cilat të dhëna. Një tabelë është krijuar në Cassandra me pothuajse të njëjtën sintaksë si në SQL:

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

)

Çelësi Primar në këtë rast përbëhet nga një kolonë, dhe është gjithashtu çelësi i ndarjes.

Si do të performojnë përdoruesit tanë? Disa do të shkojnë në një nyje, disa në një tjetër dhe disa në një të tretë. Rezultati është një tabelë e zakonshme hash, e njohur gjithashtu si një hartë, e njohur gjithashtu si një fjalor në Python, ose një strukturë e thjeshtë e vlerave kryesore nga e cila mund të lexojmë të gjitha vlerat, të lexojmë dhe shkruajmë me çelës.

Kasandra. Si të mos vdisni nëse dini vetëm Oracle

Zgjidh: kur lejohet filtrimi kthehet në skanim të plotë, ose çfarë të mos bëhet

Le të shkruajmë një deklaratë të zgjedhur: select * from users where, userid = . Rezulton si në Oracle: ne shkruajmë zgjidhni, specifikojmë kushtet dhe gjithçka funksionon, përdoruesit e marrin atë. Por nëse zgjidhni, për shembull, një përdorues me një vit të caktuar të lindjes, Cassandra ankohet se nuk mund ta përmbushë kërkesën. Për shkak se ajo nuk di asgjë fare se si shpërndajmë të dhënat për vitin e lindjes - ajo ka vetëm një kolonë të treguar si çelës. Pastaj ajo thotë: “Mirë, unë ende mund ta përmbush këtë kërkesë. Shto leje filtrimi." Shtojmë direktivën, gjithçka funksionon. Dhe në këtë moment ndodh diçka e tmerrshme.

Kur ekzekutojmë të dhënat e provës, gjithçka është në rregull. Dhe kur ekzekutoni një pyetje në prodhim, ku ne kemi, për shembull, 4 milion regjistrime, atëherë gjithçka nuk është shumë mirë për ne. Sepse lejo filtrimi është një direktivë që lejon Cassandra të mbledhë të gjitha të dhënat nga kjo tabelë nga të gjitha nyjet, të gjitha qendrat e të dhënave (nëse ka shumë prej tyre në këtë grup) dhe vetëm atëherë ta filtojë atë. Ky është një analog i Full Scan, dhe vështirë se dikush është i kënaqur me të.

Nëse do të kishim nevojë vetëm për përdoruesit me ID, do të ishim mirë me këtë. Por ndonjëherë na duhet të shkruajmë pyetje të tjera dhe të vendosim kufizime të tjera në përzgjedhje. Prandaj, kujtojmë: e gjithë kjo është një hartë që ka një çelës ndarjeje, por brenda saj është një hartë e renditur.

Dhe ajo gjithashtu ka një çelës, të cilin ne e quajmë Çelësi Clustering. Ky çelës, i cili, nga ana tjetër, përbëhet nga kolonat që ne zgjedhim, me ndihmën e të cilave Cassandra kupton se si janë renditur fizikisht të dhënat e saj dhe do të vendosen në secilën nyje. Kjo do të thotë, për disa çelësa të ndarjes, çelësi Clustering do t'ju tregojë saktësisht se si t'i shtyni të dhënat në këtë pemë, çfarë vendi do të zërë atje.

Kjo është me të vërtetë një pemë, thjesht quhet një krahasues, të cilit i kalojmë një grup të caktuar kolonash në formën e një objekti, dhe gjithashtu specifikohet si një listë kolonash.

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

Kushtojini vëmendje direktivës së çelësit primar; argumenti i saj i parë (në rastin tonë, viti) është gjithmonë çelësi i ndarjes. Mund të përbëhet nga një ose më shumë kolona, ​​nuk ka rëndësi. Nëse ka disa kolona, ​​ajo duhet të hiqet përsëri në kllapa në mënyrë që paraprocesori i gjuhës të kuptojë se ky është çelësi Primar, dhe pas tij të gjitha kolonat e tjera janë çelësi Clustering. Në këtë rast, ato do të transmetohen në krahasues sipas radhës në të cilën shfaqen. Kjo do të thotë, kolona e parë është më domethënëse, e dyta është më pak e rëndësishme, e kështu me radhë. Si shkruajmë, për shembull, është e barabartë me fushat për klasat e të dhënave: ne listojmë fushat dhe për to shkruajmë se cilat janë më të mëdha dhe cilat janë më të vogla. Në Cassandra, këto janë, në mënyrë relativisht të folur, fushat e klasës së të dhënave, në të cilat do të aplikohen barazimet e shkruara për të.

Ne vendosim renditje dhe vendosim kufizime

Duhet të mbani mend se rendi i renditjes (zbritje, ngjitje, çfarëdo) vendoset në të njëjtin moment kur krijohet çelësi dhe nuk mund të ndryshohet më vonë. Ai përcakton fizikisht se si do të renditen të dhënat dhe si do të ruhen. Nëse keni nevojë të ndryshoni tastin Clustering ose renditjen e renditjes, do t'ju duhet të krijoni një tabelë të re dhe të transferoni të dhëna në të. Kjo nuk do të funksionojë me një ekzistues.

Kasandra. Si të mos vdisni nëse dini vetëm Oracle

Ne mbushëm tryezën tonë me përdorues dhe pamë që ata binin në një unazë, fillimisht sipas vitit të lindjes, dhe më pas brenda në çdo nyje sipas pagës dhe ID-së së përdoruesit. Tani mund të zgjedhim duke vendosur kufizime.

Puna jonë shfaqet sërish where, and, dhe ne kemi përdorues, dhe gjithçka është përsëri në rregull. Por nëse përpiqemi të përdorim vetëm një pjesë të çelësit Clustering, dhe një më pak domethënës, atëherë Cassandra menjëherë do të ankohet se nuk mund të gjejë vendin në hartën tonë ku ky objekt, i cili ka këto fusha për krahasuesin null, dhe ky. që sapo ishte vendosur , - ku ai shtrihet. Do të më duhet të tërheq përsëri të gjitha të dhënat nga kjo nyje dhe ta filtroj atë. Dhe ky është një analog i Full Scan brenda një nyje, kjo është e keqe.

Në çdo situatë të paqartë, krijoni një tabelë të re

Nëse duam të jemi në gjendje të synojmë përdoruesit sipas ID-së, ose sipas moshës, ose sipas pagës, çfarë duhet të bëjmë? Asgjë. Përdorni vetëm dy tabela. Nëse ju duhet të arrini përdoruesit në tre mënyra të ndryshme, do të ketë tre tabela. Kanë ikur kohët kur kemi kursyer hapësirë ​​në vidë. Ky është burimi më i lirë. Kushton shumë më pak se koha e përgjigjes, e cila mund të jetë e dëmshme për përdoruesin. Është shumë më e këndshme për përdoruesin të marrë diçka në një sekondë sesa në 10 minuta.

Ne tregtojmë hapësirën e panevojshme dhe të dhënat e denormalizuara për aftësinë për të shkallëzuar mirë dhe për të funksionuar me besueshmëri. Në fund të fundit, në fakt, një grup që përbëhet nga tre qendra të dhënash, secila prej të cilave ka pesë nyje, me një nivel të pranueshëm të ruajtjes së të dhënave (kur asgjë nuk humbet), është në gjendje t'i mbijetojë plotësisht vdekjes së një qendre të dhënash. Dhe dy nyje të tjera në secilën nga dy të tjerat. Dhe vetëm pas kësaj fillojnë problemet. Ky është një tepricë mjaft e mirë, ia vlen disa disqe SSD dhe procesorë shtesë. Prandaj, për të përdorur Cassandra, e cila nuk është kurrë SQL, në të cilën nuk ka marrëdhënie, çelësa të huaj, duhet të dini rregulla të thjeshta.

Ne projektojmë gjithçka sipas kërkesës tuaj. Gjëja kryesore nuk janë të dhënat, por si do të funksionojë aplikacioni me to. Nëse duhet të marrë të dhëna të ndryshme në mënyra të ndryshme ose të njëjtat të dhëna në mënyra të ndryshme, ne duhet t'i vendosim ato në një mënyrë të përshtatshme për aplikacionin. Përndryshe, ne do të dështojmë në Full Scan dhe Cassandra nuk do të na japë asnjë avantazh.

Denormalizimi i të dhënave është normë. Ne harrojmë format normale, nuk kemi më baza të të dhënave relacionale. Nëse e vendosim diçka 100 herë, ajo do të shtrihet 100 herë. Është akoma më lirë se të ndalosh.

Ne zgjedhim çelësat për ndarje në mënyrë që ato të shpërndahen normalisht. Ne nuk duam që hash-i i çelësave tanë të bjerë në një gamë të ngushtë. Kjo do të thotë, viti i lindjes në shembullin e mësipërm është një shembull i keq. Më saktësisht, është mirë nëse përdoruesit tanë janë të shpërndarë normalisht sipas vitit të lindjes, dhe keq nëse flasim për nxënësit e klasës së 5-të - ndarja atje nuk do të jetë shumë e mirë.

Renditja zgjidhet një herë në fazën e krijimit të çelësit të grupimit. Nëse duhet të ndryshohet, do të duhet të përditësojmë tabelën tonë me një çelës tjetër.

Dhe gjëja më e rëndësishme: nëse na duhet të marrim të njëjtat të dhëna në 100 mënyra të ndryshme, atëherë do të kemi 100 tabela të ndryshme.

Burimi: www.habr.com

Shto një koment