Cassandra. Com no morir si només coneixes Oracle

Hola Habr.

Em dic Misha Butrimov, m'agradaria parlar-vos una mica de Cassandra. La meva història serà útil per a aquells que no s'han trobat mai amb bases de dades NoSQL: té moltes funcions d'implementació i inconvenients que cal conèixer. I si no heu vist res més que Oracle o qualsevol altra base de dades relacional, aquestes coses us salvaran la vida.

Què té de bo la Cassandra? És una base de dades NoSQL dissenyada sense un únic punt de fallada que s'escala bé. Si necessiteu afegir un parell de terabytes per a alguna base de dades, només heu d'afegir nodes a l'anell. Vols ampliar-lo a un altre centre de dades? Afegiu nodes al clúster. Augmenteu els RPS processats? Afegiu nodes al clúster. També funciona en sentit contrari.

Cassandra. Com no morir si només coneixes Oracle

En què més és bona? Es tracta de gestionar moltes peticions. Però quant és molt? 10, 20, 30, 40 mil sol·licituds per segon no són gaires. 100 mil sol·licituds per segon per a la gravació, també. Hi ha empreses que van dir que mantenen 2 milions de sol·licituds per segon. Probablement s'ho hauran de creure.

I en principi, Cassandra té una gran diferència amb les dades relacionals: no s'assembla gens a elles. I això és molt important recordar-ho.

No tot el que sembla igual funciona igual

Una vegada un company va venir a mi i em va preguntar: "Aquí hi ha un llenguatge de consulta CQL Cassandra, i té una declaració seleccionada, té on, té i. Escric cartes i no funciona. Per què?". Tractar Cassandra com una base de dades relacional és la manera perfecta de suïcidar-se violentament. I no ho estic promocionant, està prohibit a Rússia. Només dissenyareu alguna cosa malament.

Per exemple, un client ve a nosaltres i ens diu: “Construïm una base de dades per a sèries de televisió, o una base de dades per a un directori de receptes. Allà tindrem plats de menjar o una llista de sèries de televisió i actors". Diem amb alegria: "Anem!" Només has d'enviar dos bytes, un parell de senyals i ja està, tot funcionarà de manera molt ràpida i fiable. I tot va bé fins que vénen els clients i diuen que les mestresses de casa també estan resolent el problema contrari: tenen una llista de productes, i volen saber quin plat volen cuinar. Estàs mort.

Això es deu al fet que Cassandra és una base de dades híbrida: proporciona simultàniament un valor clau i emmagatzema dades en columnes àmplies. A Java o Kotlin, es podria descriure així:

Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

És a dir, un mapa que també conté un mapa ordenat. La primera clau d'aquest mapa és la clau de fila o clau de partició, la clau de partició. La segona clau, que és la clau d'un mapa ja ordenat, és la clau de clúster.

Per il·lustrar la distribució de la base de dades, dibuixem tres nodes. Ara heu d'entendre com descompondre les dades en nodes. Perquè si ho amuntem tot en un (per cert, n'hi pot haver mil, dos mil, cinc, tants com vulgueu), no es tracta realment de distribució. Per tant, necessitem una funció matemàtica que retorni un nombre. Només un número, un int llarg que caurà en algun rang. I tindrem un node responsable d'un rang, el segon del segon, l'enèsim de l'enèsim.

Cassandra. Com no morir si només coneixes Oracle

Aquest número es pren mitjançant una funció hash, que s'aplica al que anomenem clau de partició. Aquesta és la columna que s'especifica a la directiva de clau primària, i aquesta és la columna que serà la primera i la clau més bàsica del mapa. Determina quin node rebrà quines dades. Es crea una taula a Cassandra amb gairebé la mateixa sintaxi que a SQL:

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

)

La clau primària en aquest cas consta d'una columna i també és la clau de partició.

Com actuaran els nostres usuaris? Alguns aniran a un node, alguns a un altre i altres a un tercer. El resultat és una taula hash ordinària, també coneguda com a mapa, també coneguda com a diccionari en Python, o una estructura simple de valors de clau des de la qual podem llegir tots els valors, llegir i escriure per clau.

Cassandra. Com no morir si només coneixes Oracle

Selecciona: quan permet el filtratge es converteix en una exploració completa o què no s'ha de fer

Escrivim una declaració seleccionada: select * from users where, userid = . Resulta com a Oracle: escrivim select, especifiquem les condicions i tot funciona, els usuaris ho aconsegueixen. Però si seleccioneu, per exemple, un usuari amb un any de naixement determinat, Cassandra es queixa que no pot atendre la sol·licitud. Com que no sap res de com distribuïm les dades sobre l'any de naixement, només té una columna indicada com a clau. Aleshores diu: "D'acord, encara puc complir aquesta sol·licitud. Afegeix el filtratge permès." Afegim la directiva, tot funciona. I en aquest moment passa alguna cosa terrible.

Quan utilitzem dades de prova, tot està bé. I quan executeu una consulta en producció, on tenim, per exemple, 4 milions de registres, aleshores tot no és molt bo per a nosaltres. Perquè permetre el filtratge és una directiva que permet a la Cassandra recollir totes les dades d'aquesta taula de tots els nodes, tots els centres de dades (si n'hi ha molts en aquest clúster) i només després filtrar-les. Aquest és un anàleg de Full Scan i gairebé ningú n'està encantat.

Si només necessitem usuaris per identificació, ens aniria bé. Però de vegades necessitem escriure altres consultes i imposar altres restriccions a la selecció. Per tant, recordem: tot això és un mapa que té una clau de partició, però al seu interior hi ha un mapa ordenat.

I també té una clau, que anomenem clau de agrupació. Aquesta clau, que, al seu torn, consta de les columnes que seleccionem, amb l'ajuda de les quals Cassandra entén com s'ordenen físicament les seves dades i s'ubicaran a cada node. És a dir, per a alguna clau de partició, la clau de clúster us indicarà exactament com introduir les dades a aquest arbre, quin lloc hi ocuparà.

Això és realment un arbre, allà s'anomena simplement un comparador, al qual passem un determinat conjunt de columnes en forma d'objecte, i també s'especifica com a llista de columnes.

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

Fixeu-vos en la directiva de clau primària; el seu primer argument (en el nostre cas, l'any) és sempre la clau de partició. Pot constar d'una o més columnes, no importa. Si hi ha diverses columnes, s'ha d'eliminar de nou entre parèntesis perquè el preprocessador d'idioma entengui que aquesta és la clau primària i, darrere d'ella, totes les altres columnes hi ha la clau de clúster. En aquest cas, es transmetran al comparador en l'ordre en què apareixen. És a dir, la primera columna és més significativa, la segona és menys significativa, etc. Com escrivim, per exemple, és igual a camps per a les classes de dades: enumerem els camps i, per a ells, escrivim quins són més grans i quins són més petits. A Cassandra, aquests són, relativament parlant, els camps de la classe de dades, als quals s'aplicaran els iguals escrits per a aquesta.

Establem classificació i imposem restriccions

Heu de recordar que l'ordre d'ordenació (descendent, ascendent, el que sigui) s'estableix en el mateix moment en què es crea la clau i no es pot canviar més endavant. Determina físicament com s'ordenaran les dades i com s'emmagatzemaran. Si necessiteu canviar la clau de clúster o l'ordre d'ordenació, haureu de crear una taula nova i transferir-hi dades. Això no funcionarà amb un existent.

Cassandra. Com no morir si només coneixes Oracle

Vam omplir la nostra taula d'usuaris i vam veure que van caure en un anell, primer per any de naixement, i després a l'interior de cada node per salari i ID d'usuari. Ara podem seleccionar imposant restriccions.

El nostre treballador torna a aparèixer where, and, i obtenim usuaris, i tot torna a estar bé. Però si intentem utilitzar només una part de la clau d'agrupació, i una de menys significativa, llavors Cassandra es queixarà immediatament que no pot trobar el lloc del nostre mapa on aquest objecte, que té aquests camps per al comparador nul, i aquest. que s'acaba de posar, - on es troba. Hauré de tornar a recuperar totes les dades d'aquest node i filtrar-les. I això és un anàleg de Full Scan dins d'un node, això és dolent.

En qualsevol situació poc clara, creeu una taula nova

Si volem poder orientar-nos als usuaris per DNI, o per edat, o per salari, què hem de fer? Res. Només cal utilitzar dues taules. Si necessiteu arribar als usuaris de tres maneres diferents, hi haurà tres taules. Enrere queden els dies en què estalviàvem espai al cargol. Aquest és el recurs més barat. Costa molt menys que el temps de resposta, cosa que pot ser perjudicial per a l'usuari. És molt més agradable per a l'usuari rebre alguna cosa en un segon que en 10 minuts.

Intercanviem espai innecessari i dades desnormalitzades per la capacitat d'escalar bé i operar de manera fiable. Després de tot, de fet, un clúster que consta de tres centres de dades, cadascun dels quals té cinc nodes, amb un nivell acceptable de preservació de dades (quan no es perd res), és capaç de sobreviure completament a la mort d'un centre de dades. I dos nodes més en cadascun dels dos restants. I només després d'això comencen els problemes. Aquesta és una redundància força bona, val la pena un parell de unitats SSD i processadors addicionals. Per tant, per utilitzar Cassandra, que mai és SQL, en què no hi ha relacions, claus forasteres, cal conèixer regles senzilles.

Dissenyem tot segons la teva petició. El més important no són les dades, sinó com funcionarà l'aplicació. Si necessita rebre diferents dades de diferents maneres o les mateixes dades de diferents maneres, hem de posar-ho de manera que sigui convenient per a l'aplicació. En cas contrari, fallarem en Full Scan i Cassandra no ens donarà cap avantatge.

Desnormalitzar les dades és la norma. Ens oblidem de les formes normals, ja no tenim bases de dades relacionals. Si deixem una cosa 100 vegades, s'estirarà 100 vegades. Encara és més barat que aturar-se.

Seleccionem les claus per a la partició perquè es distribueixin amb normalitat. No volem que el hash de les nostres claus caigui en un rang estret. És a dir, l'any de naixement de l'exemple anterior és un mal exemple. Més precisament, és bo que els nostres usuaris estiguin distribuïts normalment per any de naixement, i dolent si parlem d'alumnes de 5è de primària: la partició allà no serà gaire bona.

L'ordenació es selecciona una vegada a l'etapa de creació de claus de clúster. Si cal canviar-lo, haurem d'actualitzar la nostra taula amb una clau diferent.

I el més important: si necessitem recuperar les mateixes dades de 100 maneres diferents, tindrem 100 taules diferents.

Font: www.habr.com

Afegeix comentari