Касандра. Како да не умрете ако го знаете само Oracle

Еј Хабр.

Јас се викам Миша Бутримов, би сакал да ви кажам малку за Касандра. Мојата приказна ќе биде корисна за оние кои никогаш не се сретнале со бази на податоци на NoSQL - има многу функции за имплементација и стапици за кои треба да знаете. И ако не сте виделе ништо друго освен Oracle или која било друга релациона база на податоци, овие работи ќе ви го спасат животот.

Што е добро за Касандра? Тоа е база на податоци NoSQL дизајнирана без ниту една точка на неуспех што добро се размерува. Ако треба да додадете неколку терабајти за некоја база на податоци, едноставно додавате јазли во прстенот. Да се ​​прошири на друг центар за податоци? Додадете јазли во кластерот. Да се ​​зголеми обработениот RPS? Додадете јазли во кластерот. Работи и во спротивна насока.

Касандра. Како да не умрете ако го знаете само Oracle

Во што друго е добра таа? Се работи за справување со многу барања. Но, колку е многу? 10, 20, 30, 40 илјади барања во секунда не е многу. 100 илјади барања во секунда за снимање - исто така. Има фирми кои рекоа дека задржуваат по 2 милиони барања во секунда. Веројатно ќе мора да веруваат.

И во принцип, Касандра има една голема разлика од релационите податоци - таа воопшто не е слична на нив. И ова е многу важно да се запамети.

Не функционира сè што изгледа исто

Еднаш еден колега дојде кај мене и ме праша: „Еве јазик за барање CQL Cassandra, и има избрана изјава, има каде, има и. Пишувам писма и не ми оди. Зошто?". Третирањето на Касандра како релациона база на податоци е совршен начин да се изврши насилно самоубиство. И јас не го промовирам, тоа е забрането во Русија. Само ќе дизајнираш нешто погрешно.

На пример, клиентот доаѓа кај нас и вели: „Ајде да изградиме база на податоци за ТВ серии или база на податоци за директориум со рецепти. Таму ќе имаме јадења со храна или список на ТВ серии и актери во него“. Велиме радосно: „Ајде да одиме! Само испратете два бајта, неколку знаци и готово, сè ќе работи многу брзо и сигурно. И се е во ред додека не дојдат муштериите и не кажат дека и домаќинките го решаваат спротивниот проблем: имаат список на производи и сакаат да знаат какво јадење сакаат да зготват. Ти си мртов.

Тоа е затоа што Касандра е хибридна база на податоци: таа истовремено обезбедува клучна вредност и складира податоци во широки колони. Во Јава или Котлин, може да се опише вака:

Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

Односно мапа која содржи и подредена карта. Првиот клуч на оваа карта е копчето Row или клучот за партиција - клучот за партиционирање. Вториот клуч, кој е клуч за веќе подредена мапа, е клучот Clustering.

За да ја илустрираме дистрибуцијата на базата на податоци, да нацртаме три јазли. Сега треба да разберете како да ги разложите податоците во јазли. Затоа што ако натрупаме сè во едно (патем, може да има илјада, две илјади, пет - колку сакаш), тука всушност не се работи за дистрибуција. Затоа, потребна ни е математичка функција која ќе врати број. Само бројка, долга интенција која ќе падне во одреден опсег. И ќе имаме еден јазол одговорен за еден опсег, вториот за вториот, n-тиот за n-ти.

Касандра. Како да не умрете ако го знаете само Oracle

Овој број се зема со помош на хаш-функција, која се применува на она што го нарекуваме клуч за партиција. Ова е колоната што е наведена во директивата за примарен клуч, а ова е колоната што ќе биде првиот и најосновниот клуч на картата. Определува кој јазол кои податоци ќе ги прими. Во Касандра се креира табела со речиси иста синтакса како во SQL:

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

)

Примарниот клуч во овој случај се состои од една колона, а исто така е и клучот за партиционирање.

Како ќе работат нашите корисници? Некои ќе одат на еден јазол, некои на друг, а некои на трет. Резултатот е обична хеш-табела, позната и како мапа, позната и како речник во Python, или едноставна структура на вредности на Key од која можеме да ги читаме сите вредности, да читаме и пишуваме по клуч.

Касандра. Како да не умрете ако го знаете само Oracle

Изберете: кога филтрирањето ќе се претвори во целосно скенирање или што да не се прави

Ајде да напишеме некоја избрана изјава: select * from users where, userid = . Излегува како во Oracle: пишуваме изберете, ги специфицираме условите и сè работи, корисниците го добиваат. Но, ако изберете, на пример, корисник со одредена година на раѓање, Касандра се жали дека не може да го исполни барањето. Бидејќи таа воопшто не знае ништо за тоа како ги дистрибуираме податоците за годината на раѓање - таа има само една колона означена како клуч. Потоа таа вели: „Во ред, сè уште можам да го исполнам ова барање. Додадете дозволи филтрирање." Ја додаваме директивата, се работи. И во овој момент се случува нешто страшно.

Кога работиме на тест податоци, сè е во ред. И кога ќе извршите барање во производството, каде што имаме, на пример, 4 милиони записи, тогаш сè не е многу добро за нас. Затоа што филтрирањето дозволи е директива која и овозможува на Касандра да ги собере сите податоци од оваа табела од сите јазли, сите центри за податоци (ако има многу такви во овој кластер) и дури потоа да ги филтрира. Ова е аналог на Целосно скенирање и ретко кој е воодушевен од него.

Ако ни требаа корисници само по лична карта, ќе ни беше добро со ова. Но, понекогаш треба да напишеме други прашања и да наметнеме други ограничувања за изборот. Затоа, се сеќаваме: сето ова е мапа што има клуч за партиционирање, но внатре има подредена карта.

И таа, исто така, има клуч, кој го нарекуваме Клуч за кластерирање. Овој клуч, кој, пак, се состои од колоните што ги избираме, со помош на кои Касандра разбира како нејзините податоци се физички подредени и ќе бидат лоцирани на секој јазол. Односно, за некој клуч за партиција, клучот Clustering ќе ви каже точно како да ги турнете податоците во ова дрво, какво место ќе заземе таму.

Ова е навистина дрво, таму едноставно се нарекува компаратор, на кој му пренесуваме одреден сет на колони во форма на објект, а исто така е наведен како листа на колони.

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

Обрнете внимание на директивата за примарен клуч; нејзиниот прв аргумент (во нашиот случај, годината) е секогаш клуч за партиција. Може да се состои од една или повеќе колони, не е важно. Ако има неколку колони, треба повторно да се отстрани во загради за да може јазичниот препроцесор да разбере дека ова е Примарниот клуч, а зад него сите други колони се клучот Кластерирање. Во овој случај, тие ќе бидат пренесени во компараторот по редоследот по кој се појавуваат. Односно, првата колона е позначајна, втората е помалку значајна итн. Како пишуваме, на пример, е еднакво на полињата за класите на податоци: ги наведуваме полињата и за нив пишуваме кои се поголеми, а кои помали. Во Касандра, ова се, релативно кажано, полињата на класата на податоци, на кои ќе се применат еднаквите напишани за неа.

Поставуваме сортирање и наметнуваме ограничувања

Треба да запомните дека редоследот на сортирање (опаѓачки, растечки, што било) е поставен во истиот момент кога клучот е креиран и не може да се промени подоцна. Физички одредува како ќе се подредуваат податоците и како ќе се складираат. Ако треба да го смените клучот за кластерирање или редоследот на сортирање, ќе мора да креирате нова табела и да префрлите податоци во неа. Ова нема да работи со постоечка.

Касандра. Како да не умрете ако го знаете само Oracle

Ја наполнивме масата со корисници и видовме дека паѓаат во ринг, прво по година на раѓање, а потоа внатре на секој јазол по плата и корисничка легитимација. Сега можеме да избираме со наметнување ограничувања.

Повторно се појавува нашата работна where, and, и добиваме корисници, и сè е повторно во ред. Но, ако се обидеме да користиме само дел од клучот Clustering, и тоа помалку значајно, тогаш Касандра веднаш ќе се пожали дека не може да го најде местото во нашата карта каде што овој објект, кој ги има овие полиња за нула споредувачот, и овој штотуку беше поставено, - каде што лежи. Ќе морам повторно да ги повлечам сите податоци од овој јазол и да ги филтрирам. И ова е аналог на Целосно скенирање во јазол, ова е лошо.

Во секоја нејасна ситуација, креирајте нова табела

Ако сакаме да можеме да ги таргетираме корисниците по лична карта, или по возраст или по плата, што треба да правиме? Ништо. Само користете две табели. Ако треба да допрете до корисниците на три различни начини, ќе има три табели. Помина времето кога заштедувавме простор на завртката. Ова е најевтиниот ресурс. Тоа чини многу помалку од времето на одговор, што може да биде штетно за корисникот. На корисникот му е многу попријатно да добие нешто во секунда отколку за 10 минути.

Ние тргуваме со непотребен простор и денормализирани податоци за способноста да се размери добро и да работи сигурно. На крајот на краиштата, всушност, кластерот што се состои од три центри за податоци, од кои секој има пет јазли, со прифатливо ниво на зачувување на податоците (кога ништо не е изгубено), може целосно да ја преживее смртта на еден центар за податоци. И уште два јазли во секој од преостанатите два. И дури после ова почнуваат проблемите. Ова е прилично добар вишок, вреди неколку дополнителни SSD дискови и процесори. Затоа, за да ја користите Касандра, која никогаш не е SQL, во која нема врски, странски клучеви, треба да знаете едноставни правила.

Ние дизајнираме сè по ваше барање. Главната работа не се податоците, туку како апликацијата ќе работи со нив. Ако треба да прима различни податоци на различни начини или исти податоци на различни начини, мора да ги ставиме на начин што е погоден за апликацијата. Во спротивно, ќе потфрлиме во Full Scan и Касандра нема да ни даде никаква предност.

Денормализирањето на податоците е норма. Забораваме на нормалните форми, веќе немаме релациони бази на податоци. Ако спуштиме нешто 100 пати, тоа ќе легне 100 пати. Сè уште е поевтино од запирање.

Ги избираме копчињата за партиционирање, така што тие се дистрибуираат нормално. Не сакаме хашот на нашите клучеви да падне во еден тесен опсег. Односно, годината на раѓање во примерот погоре е лош пример. Поточно, добро е ако нашите корисници се вообичаено распоредени по година на раѓање, а лошо ако зборуваме за ученици од 5-то одделение - поделбата таму нема да биде многу добра.

Сортирањето се избира еднаш во фазата на создавање клуч за кластерирање. Ако треба да се смени, ќе мора да ја ажурираме нашата табела со друг клуч.

И најважното нешто: ако треба да ги вратиме истите податоци на 100 различни начини, тогаш ќе имаме 100 различни табели.

Извор: www.habr.com

Додадете коментар