Kasandra. Kiel ne morti se vi nur konas Oracle

Hej Habr.

Mi nomiĝas Misha Butrimov, mi ŝatus rakonti al vi iomete pri Kasandra. Mia rakonto estos utila al tiuj, kiuj neniam renkontis NoSQL-datumbazon - ĝi havas multajn efektivigajn funkciojn kaj malfacilaĵojn, pri kiuj vi bezonas scii. Kaj se vi ne vidis ion alian ol Oracle aŭ ajnan alian rilatan datumbazon, ĉi tiuj aferoj savos vian vivon.

Kio estas tiel bona pri Kasandra? Ĝi estas NoSQL-datumbazo desegnita sen ununura punkto de fiasko, kiu bone skalas. Se vi bezonas aldoni kelkajn terabajtojn por iu datumbazo, vi simple aldonu nodojn al la ringo. Vastigi ĝin al alia datumcentro? Aldonu nodojn al la areto. Ĉu pliigi procesitan RPS? Aldonu nodojn al la areto. Ĝi funkcias ankaŭ en la kontraŭa direkto.

Kasandra. Kiel ne morti se vi nur konas Oracle

Pri kio alia ŝi lertas? Temas pri pritraktado de multaj petoj. Sed kiom multe estas? 10, 20, 30, 40 mil petoj sekundo ne estas multe. 100 mil petoj sekundo por registrado - ankaŭ. Estas kompanioj, kiuj diris, ke ili konservas 2 milionojn da petoj sekundo. Ili verŝajne devos kredi ĝin.

Kaj principe, Kasandra havas unu grandan diferencon de interrilataj datumoj - ĝi tute ne similas al ili. Kaj ĉi tio estas tre grave memori.

Ne ĉio, kio aspektas sama, funkcias same

Iam kolego venis al mi kaj demandis: “Jen CQL Cassandra demandlingvo, kaj ĝi havas elektitan deklaron, ĝi havas kie, ĝi havas kaj. Mi skribas leterojn kaj ĝi ne funkcias. Kial?". Trakti Cassandra kiel rilata datumbazo estas la perfekta maniero fari perfortan memmortigon. Kaj mi ne reklamas ĝin, ĝi estas malpermesita en Rusio. Vi nur desegnos ion malĝustan.

Ekzemple, kliento venas al ni kaj diras: “Ni konstruu datumbazon por televidaj serioj, aŭ datumbazon por recepta dosierujo. Ni havos manĝpladojn tie aŭ liston de televidserioj kaj aktoroj en ĝi." Ni diras ĝoje: "Ni iru!" Nur sendu du bajtojn, kelkajn signojn kaj vi finis, ĉio funkcios tre rapide kaj fidinde. Kaj ĉio estas en ordo, ĝis la klientoj venas kaj diras, ke dommastrinoj ankaŭ solvas la kontraŭan problemon: ili havas liston de produktoj, kaj ili volas scii, kian pladon ili volas kuiri. Vi estas morta.

Ĉi tio estas ĉar Cassandra estas hibrida datumbazo: ĝi samtempe provizas ŝlosilan valoron kaj stokas datumojn en larĝaj kolumnoj. En Java aŭ Kotlin, ĝi povus esti priskribita jene:

Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

Tio estas, mapo kiu enhavas ankaŭ ordigitan mapon. La unua ŝlosilo al ĉi tiu mapo estas la Vicoŝlosilo aŭ Dispartiga ŝlosilo - la dispartiga ŝlosilo. La dua ŝlosilo, kiu estas la ŝlosilo al jam ordigita mapo, estas la Clustering ŝlosilo.

Por ilustri la distribuadon de la datumbazo, ni desegnu tri nodojn. Nun vi devas kompreni kiel malkomponi la datumojn en nodojn. Ĉar se ni enŝlosas ĉion en unu (cetere, povas esti mil, du mil, kvin – tiom da kiom vi volas), ĉi tio ne vere temas pri distribuo. Tial ni bezonas matematikan funkcion, kiu redonos nombron. Nur nombro, longa int, kiu falos en iun gamon. Kaj ni havos unu nodon respondeca por unu gamo, la dua por la dua, la n-a por la n-a.

Kasandra. Kiel ne morti se vi nur konas Oracle

Ĉi tiu nombro estas prenita uzante hash-funkcion, kiu estas aplikata al tio, kion ni nomas la Dispartiga ŝlosilo. Ĉi tiu estas la kolumno kiu estas specifita en la Ĉefŝlosila direktivo, kaj ĉi tiu estas la kolumno kiu estos la unua kaj plej baza ŝlosilo de la mapo. Ĝi determinas kiu nodo ricevos kiujn datumojn. Tablo estas kreita en Kasandra kun preskaŭ la sama sintakso kiel en SQL:

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

)

La Ĉefŝlosilo en ĉi tiu kazo konsistas el unu kolumno, kaj ĝi ankaŭ estas la dispartiga ŝlosilo.

Kiel plenumos niaj uzantoj? Iuj iros al unu nodo, iuj al alia, kaj iuj al tria. La rezulto estas ordinara hashtabelo, ankaŭ konata kiel mapo, ankaŭ konata kiel vortaro en Python, aŭ simpla Ŝlosilvalora strukturo el kiu ni povas legi ĉiujn valorojn, legi kaj skribi per ŝlosilo.

Kasandra. Kiel ne morti se vi nur konas Oracle

Elektu: kiam permesi filtradon fariĝas plena skanado, aŭ kion ne fari

Ni skribu iun elektitan deklaron: select * from users where, userid = . Rezultas kiel en Oracle: ni skribas select, precizigas la kondiĉojn kaj ĉio funkcias, uzantoj ricevas ĝin. Sed se vi elektas, ekzemple, uzanton kun certa naskiĝjaro, Cassandra plendas, ke ĝi ne povas plenumi la peton. Ĉar ŝi tute ne scias pri kiel ni distribuas datumojn pri la naskiĝjaro - ŝi havas nur unu kolumnon indikita kiel ŝlosilo. Tiam ŝi diras, "Bone, mi ankoraŭ povas plenumi ĉi tiun peton. Aldonu permesi filtradon." Ni aldonas la direktivon, ĉio funkcias. Kaj en ĉi tiu momento io terura okazas.

Kiam ni funkcias per testaj datumoj, ĉio estas en ordo. Kaj kiam vi plenumas demandon en produktado, kie ni havas, ekzemple, 4 milionojn da registroj, tiam ĉio ne estas tre bona por ni. Ĉar permesi filtradon estas direktivo, kiu permesas al Cassandra kolekti ĉiujn datumojn de ĉi tiu tabelo de ĉiuj nodoj, ĉiuj datumcentroj (se estas multaj el ili en ĉi tiu areto), kaj nur tiam filtri ĝin. Ĉi tio estas analogo de Full Scan, kaj preskaŭ neniu ĝojas pri ĝi.

Se ni nur bezonus uzantojn laŭ ID, ni estus bone kun ĉi tio. Sed foje ni bezonas skribi aliajn demandojn kaj trudi aliajn limigojn al la elekto. Sekve, ni memoras: ĉi tio estas ĉio mapo, kiu havas dispartigan ŝlosilon, sed interne de ĝi estas ordigita mapo.

Kaj ŝi ankaŭ havas ŝlosilon, kiun ni nomas la Clustering Key. Ĉi tiu ŝlosilo, kiu, siavice, konsistas el la kolumnoj, kiujn ni elektas, kun la helpo de kiuj Cassandra komprenas, kiel ĝiaj datumoj estas fizike ordigitaj kaj troviĝos sur ĉiu nodo. Tio estas, por iu Partition-ŝlosilo, la Clustering-ŝlosilo diros al vi precize kiel puŝi la datumojn en ĉi tiun arbon, kian lokon ĝi prenos tie.

Ĉi tio vere estas arbo, komparilo estas simple nomata tie, al kiu ni pasas certan aron da kolumnoj en formo de objekto, kaj ĝi ankaŭ estas specifita kiel listo de kolumnoj.

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

Atentu la direktivon pri Ĉefŝlosilo; ĝia unua argumento (en nia kazo, la jaro) ĉiam estas Dispartiga ŝlosilo. Ĝi povas konsisti el unu aŭ pluraj kolumnoj, ne gravas. Se estas pluraj kolumnoj, ĝi devas esti denove forigita inter krampoj, por ke la lingva antaŭprocesoro komprenu, ke ĉi tio estas la Ĉefŝlosilo, kaj malantaŭ ĝi ĉiuj aliaj kolumnoj estas la Clustering-ŝlosilo. En ĉi tiu kazo, ili estos transdonitaj en la komparilo en la ordo en kiu ili aperas. Tio estas, la unua kolumno estas pli signifa, la dua estas malpli signifa, ktp. Kiel ni skribas, ekzemple, egalas kampojn por datumklasoj: ni listigas la kampojn, kaj por ili ni skribas kiuj estas pli grandaj kaj kiuj estas pli malgrandaj. En Kasandra, ĉi tiuj estas, relative parolante, la kampoj de la datumklaso, al kiuj la egalaj skribitaj por ĝi estos aplikitaj.

Ni starigas ordigon kaj trudas limigojn

Vi devas memori, ke la ordigo (malkreskanta, supreniranta, kio ajn) estas agordita en la sama momento kiam la ŝlosilo estas kreita, kaj ĝi ne povas esti ŝanĝita poste. Ĝi fizike determinas kiel la datumoj estos ordigitaj kaj kiel ĝi estos konservita. Se vi bezonas ŝanĝi la Clustering-ŝlosilon aŭ ordigi, vi devos krei novan tabelon kaj transdoni datumojn en ĝin. Ĉi tio ne funkcios kun ekzistanta.

Kasandra. Kiel ne morti se vi nur konas Oracle

Ni plenigis nian tablon per uzantoj kaj vidis, ke ili falis en ringon, unue laŭ naskiĝjaro, kaj poste interne sur ĉiu nodo laŭ salajro kaj uzantidentigilo. Nun ni povas elekti trudante limigojn.

Nia laboranta denove aperas where, and, kaj ni ricevas uzantojn, kaj ĉio denove estas en ordo. Sed se ni provas uzi nur parton de la Clustering-ŝlosilo, kaj malpli signifa, tiam Kasandra tuj plendos, ke ĝi ne povas trovi la lokon en nia mapo kie ĉi tiu objekto, kiu havas ĉi tiujn kampojn por la nula komparilo, kaj ĉi tiu. tio estis ĵus starigita , - kie li kuŝas. Mi devos denove eltiri ĉiujn datumojn de ĉi tiu nodo kaj filtri ĝin. Kaj ĉi tio estas analogo de Plena Skanado ene de nodo, ĉi tio estas malbona.

En ajna neklara situacio, kreu novan tabelon

Se ni volas povi celi uzantojn laŭ identigilo, aŭ laŭ aĝo, aŭ laŭ salajro, kion ni faru? Nenio. Nur uzu du tabelojn. Se vi bezonas atingi uzantojn en tri malsamaj manieroj, estos tri tabloj. Forpasis la tagoj, kiam ni ŝparis spacon sur la ŝraŭbo. Ĉi tiu estas la plej malmultekosta rimedo. Ĝi kostas multe malpli ol responda tempo, kio povas esti malutila al la uzanto. Estas multe pli agrable por la uzanto ricevi ion en sekundo ol en 10 minutoj.

Ni komercas nenecesan spacon kaj malnormaligitajn datumojn por la kapablo bone skali kaj funkcii fidinde. Post ĉio, fakte, areto kiu konsistas el tri datumcentroj, ĉiu el kiuj havas kvin nodojn, kun akceptebla nivelo de datumkonservado (kiam nenio estas perdita), kapablas travivi la morton de unu datumcentro tute. Kaj du pliaj nodoj en ĉiu el la ceteraj du. Kaj nur post tio komenciĝas la problemoj. Ĉi tio estas sufiĉe bona redundo, ĝi valoras kelkajn kromajn SSD-diskojn kaj procesorojn. Tial, por uzi Cassandra, kiu neniam estas SQL, en kiu ne ekzistas rilatoj, fremdaj ŝlosiloj, vi devas scii simplajn regulojn.

Ni desegnas ĉion laŭ via peto. La ĉefa afero ne estas la datumoj, sed kiel la aplikaĵo funkcios kun ĝi. Se ĝi bezonas ricevi malsamajn datumojn en malsamaj manieroj aŭ la samajn datumojn en malsamaj manieroj, ni devas meti ĝin en maniero kiu estas oportuna por la aplikaĵo. Alie, ni malsukcesos en Plena Skanado kaj Cassandra ne donos al ni ajnan avantaĝon.

Malnormaligi datumojn estas la normo. Ni forgesas pri normalaj formoj, ni ne plu havas rilatajn datumbazojn. Se ni demetas ion 100 fojojn, ĝi kuŝos 100 fojojn. Ĝi estas ankoraŭ pli malmultekosta ol ĉesi.

Ni elektas la ŝlosilojn por dispartigo por ke ili estu distribuitaj normale. Ni ne volas, ke la haŝo de niaj ŝlosiloj falu en unu mallarĝan gamon. Tio estas, la naskiĝjaro en la supra ekzemplo estas malbona ekzemplo. Pli precize, estas bone, se niaj uzantoj estas normale distribuitaj laŭ naskiĝjaro, kaj malbone se ni parolas pri studentoj de 5-a grado - la tiea dispartigo ne estos tre bona.

Ordigo estas elektita unufoje ĉe la krea stadio de Clustering Key. Se ĝi devas esti ŝanĝita, ni devos ĝisdatigi nian tabelon per malsama ŝlosilo.

Kaj la plej grava afero: se ni bezonas preni la samajn datumojn en 100 malsamaj manieroj, tiam ni havos 100 malsamajn tabelojn.

fonto: www.habr.com

Aldoni komenton