Cassandra. Hoe net te stjerren as jo allinich Oracle kenne

Hoi Habr.

Myn namme is Misha Butrimov, ik soe graach fertelle jo in bytsje oer Cassandra. Myn ferhaal sil nuttich wêze foar dyjingen dy't noch noait NoSQL-databases hawwe tsjinkaam - it hat in protte ymplemintaasjefunksjes en falkûlen wêr't jo oer witte moatte. En as jo neat oars hawwe sjoen as Oracle of in oare relaasjedatabase, sille dizze dingen jo libben rêde.

Wat is sa goed oan Cassandra? It is in NoSQL-database ûntworpen sûnder ien inkeld punt fan mislearring dy't goed skale. As jo ​​​​in pear terabytes moatte tafoegje foar guon database, foegje jo gewoan knopen ta oan 'e ring. It útwreidzje nei in oar datasintrum? Foegje knopen ta oan it kluster. Fergrutsje ferwurke RPS? Foegje knopen ta oan it kluster. It wurket ek yn 'e tsjinoerstelde rjochting.

Cassandra. Hoe net te stjerren as jo allinich Oracle kenne

Wat is se oars goed yn? It giet om it behanneljen fan in protte oanfragen. Mar hoefolle is in protte? 10, 20, 30, 40 tûzen oanfragen per sekonde is net folle. 100 tûzen fersiken per sekonde foar opname - ek. D'r binne bedriuwen dy't seine dat se 2 miljoen oanfragen per sekonde hâlde. Se sille it wol leauwe moatte.

En yn prinsipe hat Cassandra ien grut ferskil mei relaasjegegevens - it is hielendal net gelyk oan har. En dit is tige wichtich om te ûnthâlden.

Net alles dat itselde liket wurket itselde

Ienris kaam in kollega nei my en frege: "Hjir is in CQL Cassandra-fraachtaal, en it hat in selekteare ferklearring, it hat wêr, it hat en. Ik skriuw brieven en it wurket net. Wêrom?". Cassandra behannelje as in relationele databank is de perfekte manier om gewelddiedich selsmoard te plegen. En ik befoarderje it net, it is ferbean yn Ruslân. Jo sille gewoan wat ferkeard ûntwerpe.

Bygelyks, in klant komt nei ús en seit: “Litte wy in databank bouwe foar tv-searjes, of in databank foar in reseptmap. Wy sille dêr itensketten hawwe of in list mei tv-searjes en akteurs deryn. Wy sizze bliid: "Litte wy gean!" Stjoer gewoan twa bytes, in pear tekens en jo binne klear, alles sil heul fluch en betrouber wurkje. En alles is goed oant de klanten komme en sizze dat húsfroulju ek it tsjinoerstelde probleem oplosse: se hawwe in list mei produkten, en se wolle witte hokker gerjocht se wolle koken. Do bist dea.

Dit komt om't Cassandra in hybride databank is: it leveret tagelyk in kaaiwearde en bewarret gegevens yn brede kolommen. Yn Java of Kotlin kin it sa beskreaun wurde:

Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

Dat is in kaart dêr't ek in sortearre kaart yn stiet. De earste kaai foar dizze kaart is de Row-kaai of Partition-kaai - de partitioning-kaai. De twadde kaai, dat is de kaai foar in al sortearre kaart, is de Clustering kaai.

Om de ferdieling fan 'e databank te yllustrearjen, litte wy trije knopen tekenje. No moatte jo begripe hoe't jo de gegevens yn knooppunten ûntbine. Want as wy alles yn ien stappe (d'r kinne trouwens tûzen, twatûzen, fiif wêze - safolle as jo wolle), dan giet it net echt oer distribúsje. Dêrom hawwe wy in wiskundige funksje nedich dy't in getal werombringt. Krekt in nûmer, in lange int dat sil falle yn guon berik. En wy sille ien knooppunt hawwe ferantwurdlik foar ien berik, de twadde foar de twadde, de n-de foar de n-de.

Cassandra. Hoe net te stjerren as jo allinich Oracle kenne

Dit nûmer wurdt nommen mei in hash-funksje, dy't tapast wurdt op wat wy de Partition-kaai neame. Dit is de kolom dy't wurdt oantsjutte yn de primêre kaai rjochtline, en dit is de kolom dy't sil wêze de earste en meast basale kaai fan de kaart. It bepaalt hokker knooppunt hokker gegevens sil ûntfange. In tabel wurdt makke yn Cassandra mei hast deselde syntaksis as yn SQL:

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

)

De primêre kaai yn dit gefal bestiet út ien kolom, en it is ek de partitioning kaai.

Hoe sille ús brûkers prestearje? Guon sille nei ien knooppunt gean, guon nei in oare, en guon nei in tredde. It resultaat is in gewoane hash-tabel, ek wol in kaart neamd, ek wol bekend as in wurdboek yn Python, of in ienfâldige kaaiweardestruktuer wêrfan wy alle wearden lêze kinne, lêze en skriuwe troch kaai.

Cassandra. Hoe net te stjerren as jo allinich Oracle kenne

Selektearje: as filtering tastean feroaret yn folsleine scan, of wat net te dwaan

Litte wy wat selekteare ferklearring skriuwe: select * from users where, userid = . It docht bliken as yn Oracle: wy skriuwe selektearje, spesifisearje de betingsten en alles wurket, brûkers krije it. Mar as jo bygelyks in brûker selektearje mei in bepaald bertejier, klaget Cassandra dat it it fersyk net kin foldwaan. Om't se hielendal neat wit oer hoe't wy gegevens oer it bertejier ferspriede - hat se mar ien kolom oanjûn as kaai. Dan seit se: "Oké, ik kin dit fersyk noch folbringe. Foegje tastean filtering ta." Wy foegje de rjochtline ta, alles wurket. En op dit stuit bart der wat ferskrikliks.

As wy op testgegevens rinne, is alles goed. En as jo in query útfiere yn produksje, wêr't wy bygelyks 4 miljoen records hawwe, dan is alles net heul goed foar ús. Omdat tastean filterjen is in rjochtline wêrmei Cassandra te sammeljen alle gegevens út dizze tabel út alle knopen, alle gegevens sintra (as der in protte fan harren yn dit kluster), en pas dan filterje it. Dit is in analoog fan Full Scan, en amper ien is der bliid mei.

As wy allinne nedich brûkers troch ID, wy soenen wêze goed mei dit. Mar soms moatte wy oare fragen skriuwe en oare beheiningen oplizze oan 'e seleksje. Dêrom, wy ûnthâlde: dit is allegear in kaart dy't hat in partitioning kaai, mar binnen it is in sortearre kaart.

En sy hat ek in kaai, dy't wy neame de Clustering Key. Dizze kaai, dy't op syn beurt bestiet út 'e kolommen dy't wy selektearje, mei help wêrfan Cassandra begrypt hoe't har gegevens fysyk wurde sorteare en sille op elke knooppunt lizze. Dat is, foar guon Partition-kaai sil de Clustering-kaai jo krekt fertelle hoe't jo de gegevens yn dizze beam kinne triuwe, hokker plak it dêr sil nimme.

Dit is echt in beam, dêr wurdt gewoan in komparator neamd, dêr't wy in bepaalde set fan kolommen yn 'e foarm fan in foarwerp trochjaan, en it wurdt ek oanjûn as in list mei kolommen.

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

Soarch omtinken foar de rjochtline foar primêre kaai; it earste argumint (yn ús gefal, it jier) is altyd Partition-kaai. It kin bestean út ien of mear kolommen, it makket neat út. As der ferskate kolommen binne, moat it wer tusken heakjes fuortsmiten wurde, sadat de taalfoarferwurker begrypt dat dit de Primêre kaai is, en efter it binne alle oare kolommen de Clustering-kaai. Yn dit gefal wurde se yn 'e komparator oerbrocht yn' e folchoarder wêryn't se ferskine. Dat is, de earste kolom is wichtiger, de twadde is minder wichtich, ensfh. Hoe't wy skriuwe, bygelyks, is gelyk oan fjilden foar gegevensklassen: wy listje de fjilden, en foar har skriuwe wy hokker grutter binne en hokker lytser binne. Yn Cassandra binne dat, relatyf sjoen, de fjilden fan 'e gegevensklasse, dêr't de lykweardich foar skreaun wurde sil tapast wurde.

Wy sette sortearring en lizze beheiningen op

Jo moatte betinke dat de sortearring folchoarder (ôfnimmend, oprinnend, wat dan ek) wurdt ynsteld op itselde momint as de kaai wurdt oanmakke, en it kin net feroare wurde letter. It bepaalt fysyk hoe't de gegevens wurde sorteare en hoe't se wurde opslein. As jo ​​de Clustering-kaai of sortearringsoarder feroarje moatte, moatte jo in nije tabel oanmeitsje en gegevens dêryn oerdrage. Dit sil net wurkje mei in besteande.

Cassandra. Hoe net te stjerren as jo allinich Oracle kenne

Wy folje ús tafel mei brûkers en seagen dat se yn in ring foelen, earst troch bertejier, en dan binnen op elke knooppunt troch salaris en brûkers-ID. No kinne wy ​​​​selektearje troch beheiningen op te lizzen.

Us wurkjende ien ferskynt wer where, and, en wy krije brûkers, en alles is wer goed. Mar as wy besykje mar in diel fan 'e Clustering-kaai te brûken, en in minder wichtige, dan sil Cassandra daliks kleie dat it it plak net kin fine op ús kaart wêr't dit objekt, dat dizze fjilden hat foar de nulfergeliker, en dizze iene dat wie krekt set , - dêr't er leit. Ik sil alle gegevens fan dit knooppunt opnij moatte ophelje en it filterje. En dit is in analoog fan Full Scan binnen in knooppunt, dit is min.

Meitsje yn elke ûndúdlike situaasje in nije tabel

As wy brûkers wolle rjochtsje op ID, of op leeftyd, of op salaris, wat moatte wy dwaan? Neat. Brûk gewoan twa tabellen. As jo ​​​​brûkers op trije ferskillende manieren moatte berikke, sille d'r trije tabellen wêze. Foarby binne de dagen doe't wy bewarre romte op 'e skroef. Dit is de goedkeapste boarne. It kostet folle minder dan reaksjetiid, dat kin skealik wêze foar de brûker. It is folle nofliker foar de brûker om wat yn in sekonde te ûntfangen dan yn 10 minuten.

Wy hannelje ûnnedige romte en denormalisearre gegevens foar de mooglikheid om goed te skaaljen en betrouber te operearjen. Ommers, in kluster dat bestiet út trije datasintra, elk fan dat hat fiif knopen, mei in akseptabel nivo fan gegevens behâld (as neat is ferlern), is by steat om te oerlibje de dea fan ien datacenter folslein. En noch twa knopen yn elk fan 'e oerbleaune twa. En pas dêrnei begjinne de problemen. Dit is in aardich goede redundânsje, it is in pear ekstra SSD-skiven en processors wurdich. Dêrom, om Cassandra te brûken, dy't noait SQL is, wêryn gjin relaasjes, bûtenlânske kaaien binne, moatte jo ienfâldige regels witte.

Wy ûntwerpe alles neffens jo fersyk. It wichtichste is net de gegevens, mar hoe't de applikaasje dermei sil wurkje. As it ferskate gegevens op ferskate manieren of deselde gegevens op ferskate manieren moat ûntfange, moatte wy it op in manier pleatse dy't handich is foar de applikaasje. Oars, sille wy mislearje yn Folsleine scan en Cassandra sil ús gjin foardiel jaan.

Denormalisearjen fan gegevens is de noarm. Wy ferjitte oer normale foarmen, wy hawwe gjin relaasjedatabases mear. As wy wat 100 kear dellizze, leit it 100 kear del. It is noch goedkeaper as stopje.

Wy selektearje de kaaien foar partitioning sadat se normaal ferdield wurde. Wy wolle net dat de hash fan ús kaaien yn ien smel berik falle. Dat is, it bertejier yn it foarbyld hjirboppe is in min foarbyld. Mear krekter, it is goed as ús brûkers normaal ferdield wurde troch bertejier, en min as wy it hawwe oer learlingen fan 5e klasse - de partitioning dêr sil net heul goed wêze.

Sortearjen wurdt ien kear selektearre by it oanmeitsjen fan Clustering Key. As it feroare wurde moat, sille wy ús tabel moatte bywurkje mei in oare kaai.

En it wichtichste ding: as wy deselde gegevens op 100 ferskillende manieren moatte ophelje, dan sille wy 100 ferskillende tabellen hawwe.

Boarne: www.habr.com

Add a comment