Cum să te uiți în ochii lui Cassandra fără a pierde date, stabilitate și încredere în NoSQL

Cum să te uiți în ochii lui Cassandra fără a pierde date, stabilitate și încredere în NoSQL

Se spune că totul în viață merită încercat măcar o dată. Și dacă sunteți obișnuit să lucrați cu SGBD-uri relaționale, atunci merită să vă familiarizați cu NoSQL în practică, în primul rând, cel puțin pentru dezvoltarea generală. Acum, datorită dezvoltării rapide a acestei tehnologii, există o mulțime de opinii contradictorii și dezbateri aprinse pe această temă, care alimentează în special interesul.
Dacă te aprofundezi în esența tuturor acestor dispute, poți vedea că ele apar din cauza unei abordări greșite. Cei care folosesc bazele de date NoSQL exact acolo unde este nevoie sunt multumiti si primesc toate avantajele din aceasta solutie. Iar experimentatorii care se bazează pe această tehnologie ca pe un panaceu acolo unde nu se aplică deloc sunt dezamăgiți, pierzând punctele forte ale bazelor de date relaționale fără a obține beneficii semnificative.

Vă voi povesti despre experiența noastră în implementarea unei soluții bazate pe SGBD Cassandra: cu ce ne-am confruntat, cum am ieșit din situații dificile, dacă am putut beneficia de folosirea NoSQL și unde a trebuit să investim eforturi/fonduri suplimentare. .
Sarcina inițială este de a construi un sistem care înregistrează apelurile într-un fel de stocare.

Principiul de funcționare al sistemului este următorul. Intrarea include fișiere cu o structură specifică care descrie structura apelului. Aplicația se asigură apoi că această structură este stocată în coloanele corespunzătoare. Pe viitor, apelurile salvate sunt folosite pentru a afișa informații despre consumul de trafic pentru abonați (taxe, apeluri, istoric de sold).

Cum să te uiți în ochii lui Cassandra fără a pierde date, stabilitate și încredere în NoSQL

Este destul de clar de ce au ales-o pe Cassandra - ea scrie ca o mitralieră, este ușor scalabilă și tolerantă la greșeli.

Deci, asta ne-a dat experiența

Da, un nod eșuat nu este o tragedie. Aceasta este esența toleranței la greșeală a Cassandrei. Dar un nod poate fi viu și, în același timp, poate începe să sufere în performanță. După cum sa dovedit, acest lucru afectează imediat performanța întregului cluster.

Cassandra nu te va proteja acolo unde te-a salvat Oracle cu constrângerile sale. Și dacă autorul aplicației nu a înțeles acest lucru dinainte, atunci dublul care a sosit pentru Cassandra nu este mai rău decât originalul. Odată ce a sosit, îl vom introduce.

IB nu i-a plăcut foarte mult Cassandra gratuită din cutie: Nu există înregistrarea acțiunilor utilizatorului, nicio diferențiere a drepturilor. Informațiile despre apeluri sunt considerate date cu caracter personal, ceea ce înseamnă că toate încercările de a le solicita/modifica în orice mod trebuie înregistrate cu posibilitatea de auditare ulterioară. De asemenea, trebuie să fii conștient de necesitatea de a separa drepturile la diferite niveluri pentru diferiți utilizatori. Un simplu inginer de operare și un super admin care poate șterge liber întreg spațiul cheie sunt roluri diferite, responsabilități și competențe diferite. Fără o astfel de diferențiere a drepturilor de acces, valoarea și integritatea datelor vor intra imediat sub semnul întrebării mai repede decât cu ORICE nivel de consistență.

Nu am ținut cont de faptul că apelurile necesită atât analize serioase, cât și eșantionare periodică pentru o varietate de condiții. Deoarece înregistrările selectate ar trebui apoi să fie șterse și rescrise (ca parte a sarcinii, trebuie să sprijinim procesul de actualizare a datelor atunci când datele au intrat inițial în bucla noastră incorect), Cassandra nu este prietena noastră aici. Cassandra este ca o pușculiță - este convenabil să pui lucruri, dar nu poți să numeri în ea.

Am întâmpinat o problemă la transferul datelor în zonele de testare (5 noduri în test față de 20 la bal). În acest caz, depozitul nu poate fi folosit.

Problema cu actualizarea schemei de date a unei aplicații care scrie către Cassandra. O retragere va genera o mulțime de pietre funerare, ceea ce poate duce la pierderi de productivitate în moduri imprevizibile.. Cassandra este optimizată pentru înregistrare și nu se gândește prea mult înainte de a scrie.Orice operație cu date existente în ea este și o înregistrare. Adică, ștergând cele inutile, pur și simplu vom produce și mai multe înregistrări și doar unele dintre ele vor fi marcate cu pietre funerare.

Timeouts la inserare. Cassandra este frumoasă în înregistrare, dar uneori, fluxul de intrare o poate nedumeri în mod semnificativ. Acest lucru se întâmplă atunci când aplicația începe să circule în jurul mai multor înregistrări care nu pot fi inserate dintr-un motiv oarecare. Și vom avea nevoie de un DBA adevărat care va monitoriza gc.log, jurnalele de sistem și de depanare pentru interogări lente, metrici privind compactarea în așteptare.

Mai multe centre de date într-un cluster. De unde să citești și unde să scrii?
Poate împărțit în citit și scris? Și dacă da, ar trebui să existe un DC mai aproape de aplicația pentru scriere sau citire? Și nu vom ajunge cu un adevărat creier divizat dacă alegem un nivel de consistență greșit? Există o mulțime de întrebări, o mulțime de setări necunoscute, posibilități cu care chiar vrei să le faci.

Cum ne-am hotărât

Pentru a preveni scufundarea nodului, SWAP a fost dezactivat. Și acum, dacă există o lipsă de memorie, nodul ar trebui să coboare și să nu creeze pauze mari gc.

Deci, nu ne mai bazăm pe logica din baza de date. Dezvoltatorii de aplicații se reinformează și încep să ia în mod activ măsuri de precauție în propriul cod. Separare clară ideală a stocării și procesării datelor.

Am achiziționat asistență de la DataStax. Dezvoltarea Cassandrei în cutie a încetat deja (ultimul comit a fost în februarie 2018). În același timp, Datastax oferă servicii excelente și un număr mare de soluții modificate și adaptate pentru soluțiile IP existente.

De asemenea, vreau să remarc că Cassandra nu este foarte convenabilă pentru interogări de selecție. Desigur, CQL este un mare pas înainte pentru utilizatori (comparativ cu Trift). Dar dacă aveți departamente întregi care sunt obișnuite cu astfel de alinări convenabile, filtrare gratuită după orice domeniu și capabilități de optimizare a interogărilor, iar aceste departamente lucrează pentru a rezolva reclamațiile și accidentele, atunci soluția pe Cassandra li se pare ostilă și stupidă. Și am început să decidem cum ar trebui să facă colegii noștri mostre.

Am luat în considerare două opțiuni.În prima opțiune, scriem apeluri nu numai în C*, ci și în baza de date Oracle arhivată. Numai că, spre deosebire de C*, această bază de date stochează apelurile doar pentru luna curentă (adâncime suficientă de stocare a apelurilor pentru cazurile de reîncărcare). Aici am văzut imediat următoarea problemă: dacă scriem sincron, atunci pierdem toate avantajele C* asociate cu inserarea rapidă; dacă scriem asincron, nu există nicio garanție că toate apelurile necesare au ajuns în Oracle. A existat un plus, dar unul mare: pentru funcționare rămâne același dezvoltator PL/SQL familiar, adică implementăm practic modelul „Fațadă”, o opțiune alternativă. Implementăm un mecanism care descarcă apelurile din C*, extrage niște date pentru îmbogățire din tabelele corespunzătoare din Oracle, unește mostrele rezultate și ne oferă rezultatul, pe care apoi îl folosim cumva (roll back, repetă, analizăm, admirăm). Contra: procesul este destul de în mai mulți pași și, în plus, nu există nicio interfață pentru angajații operaționali.

Până la urmă, ne-am hotărât pe a doua variantă. Apache Spark a fost folosit pentru mostre din diferite borcane. Esența mecanismului a fost redusă la codul Java, care, folosind cheile specificate (abonat, timpul apelului - taste de secțiune), extrage datele din C*, precum și datele necesare pentru îmbogățire din orice altă bază de date. După care le unește în memoria sa și afișează rezultatul în tabelul rezultat. Am desenat o față de pânză peste scânteie și s-a dovedit destul de utilizabilă.

Cum să te uiți în ochii lui Cassandra fără a pierde date, stabilitate și încredere în NoSQL

Când am rezolvat problema actualizării datelor de testare industrială, am luat din nou în considerare câteva soluții. Atât transferul prin Sstloader cât și opțiunea de împărțire a clusterului din zona de testare în două părți, fiecare aparținând alternativ aceluiași cluster cu cel promoțional, fiind astfel alimentat de acesta. La actualizarea testului, s-a planificat schimbarea acestora: partea care a funcționat în test este șters și intrat în producție, iar cealaltă începe să lucreze cu datele separat. Cu toate acestea, după ce ne-am gândit din nou, am evaluat mai rațional datele care merită transferate și am realizat că apelurile în sine sunt o entitate inconsecventă pentru teste, generată rapid dacă este necesar, și este setul de date promoționale care nu are valoare pentru transferul către Test. Există mai multe obiecte de depozitare care merită mutate, dar acestea sunt literalmente câteva mese și nu foarte grele. Prin urmare noi ca soluție, Spark a venit din nou în ajutor, cu ajutorul căruia am scris și am început să folosim activ un script pentru transferul de date între tabele, prom-test.

Politica noastră actuală de implementare ne permite să lucrăm fără rollback. Înainte de promoție, există un test obligatoriu, unde o greșeală nu este atât de costisitoare. În caz de eșec, puteți oricând să renunțați la casespace și să rulați întreaga schemă de la început.

Pentru a asigura disponibilitatea continuă a Cassandrei, ai nevoie de un dba și nu doar de el. Toți cei care lucrează cu aplicația trebuie să înțeleagă unde și cum să se uite la situația actuală și cum să diagnosticheze problemele în timp util. Pentru a face acest lucru, folosim în mod activ DataStax OpsCenter (Administrarea și monitorizarea încărcăturilor de lucru), metrica sistemului Cassandra Driver (numărul de timeout-uri pentru scrierea în C*, numărul de timeout-uri pentru citirea din C*, latența maximă etc.), monitorizarea operațiunii a aplicației în sine, lucrând cu Cassandra.

Când ne-am gândit la întrebarea anterioară, ne-am dat seama unde ar putea fi principalul nostru risc. Acestea sunt formulare de afișare a datelor care afișează date de la mai multe interogări independente către stocare. În acest fel putem obține informații destul de inconsecvente. Dar această problemă ar fi la fel de relevantă dacă am lucra cu un singur centru de date. Deci, cel mai rezonabil lucru aici este, desigur, să creați o funcție batch pentru citirea datelor pe o aplicație terță parte, care va asigura că datele sunt primite într-o singură perioadă de timp. În ceea ce privește împărțirea în citire și scriere din punct de vedere al performanței, aici am fost opriți de riscul ca, cu o oarecare pierdere a conexiunii între DC-uri, să ajungem la două clustere care sunt complet inconsecvente între ele.

Drept urmare, deocamdată oprit la nivelul de consistență pentru scrierea EACH_QUORUM, pentru citire - LOCAL_QUORUM

Scurte impresii și concluzii

Pentru a evalua soluția rezultată din punct de vedere al suportului operațional și al perspectivelor de dezvoltare ulterioară, am decis să ne gândim unde mai poate fi aplicată o astfel de dezvoltare.

Imediat, apoi punctarea datelor pentru programe precum „Plătiți când este convenabil” (încărcăm informații în C*, calculul folosind scripturi Spark), contabilizarea revendicărilor cu agregare pe zonă, stocarea rolurilor și calcularea drepturilor de acces ale utilizatorilor în funcție de rol matrice.

După cum puteți vedea, repertoriul este larg și variat. Și dacă alegem tabăra susținătorilor/oponenților NoSQL, atunci ne vom alătura susținătorilor, din moment ce ne-am primit avantajele, și exact acolo unde ne așteptam.

Chiar și opțiunea Cassandra din cutie permite scalarea orizontală în timp real, rezolvând absolut fără durere problema creșterii datelor în sistem. Am reușit să mutăm un mecanism de încărcare foarte mare pentru calcularea agregatelor de apeluri într-un circuit separat și, de asemenea, să separăm schema și logica aplicației, scăpând de practica proastă de a scrie joburi și obiecte personalizate în baza de date în sine. Am avut ocazia să alegem și să configuram, să accelerăm, pe ce DC-uri vom efectua calcule și pe care vom înregistra date, ne-am asigurat împotriva blocărilor atât ale nodurilor individuale, cât și ale DC-ului în ansamblu.

Aplicând arhitectura noastră la proiecte noi și având deja ceva experiență, aș dori să țin cont imediat de nuanțele descrise mai sus și să previn unele greșeli, să netezesc unele colțuri ascuțite care nu au putut fi evitate inițial.

De exemplu, ține evidența actualizărilor Cassandrei în timp utilpentru că destul de multe dintre problemele pe care le-am avut erau deja cunoscute și rezolvate.

Nu puneți atât baza de date în sine, cât și Spark pe aceleași noduri (sau împărțiți strict la cantitatea de utilizare permisă a resurselor), deoarece Spark poate mânca mai mult OP decât se aștepta și vom obține rapid problema numărul 1 din lista noastră.

Îmbunătățiți monitorizarea și competența operațională în etapa de testare a proiectului. Inițial, luați în considerare pe cât posibil toți potențialii consumatori ai soluției noastre, pentru că de asta va depinde în cele din urmă structura bazei de date.

Rotiți circuitul rezultat de mai multe ori pentru o posibilă optimizare. Selectați ce câmpuri pot fi serializate. Înțelegeți ce tabele suplimentare ar trebui să facem pentru a lua în considerare cel mai corect și optim, apoi furnizați informațiile solicitate la cerere (de exemplu, presupunând că putem stoca aceleași date în tabele diferite, ținând cont de diferite defalcări în funcție de diferite criterii, putem economisi semnificativ timp CPU pentru cererile de citire).

Nu-i rău Asigurați-vă imediat atașarea TTL și curățarea datelor învechite.

Când descărcați date de la Cassandra Logica aplicației ar trebui să funcționeze pe principiul FETCH, astfel încât nu toate rândurile să fie încărcate în memorie odată, ci să fie selectate în loturi.

Este recomandabil înainte de a transfera proiectul la soluția descrisă verificați toleranța la erori a sistemului efectuând o serie de teste de impact, cum ar fi pierderea de date într-un centru de date, restaurarea datelor deteriorate într-o anumită perioadă, întreruperea rețelei între centrele de date. Astfel de teste nu vor permite doar evaluarea avantajelor și dezavantajelor arhitecturii propuse, dar vor oferi și o bună practică de încălzire pentru inginerii care le conduc, iar abilitățile dobândite vor fi departe de a fi superflue dacă defecțiunile sistemului sunt reproduse în producție.

Dacă lucrăm cu informații critice (cum ar fi datele pentru facturare, calculul datoriilor abonaților), atunci merită să acordăm atenție instrumentelor care vor reduce riscurile care apar datorită caracteristicilor SGBD. De exemplu, utilizați utilitarul nodesync (Datastax), având dezvoltat o strategie optimă pentru utilizarea sa în ordine de dragul consistenței, nu creați o sarcină excesivă asupra Cassandrei și să-l folosească numai pentru anumite tabele într-o anumită perioadă.

Ce se întâmplă cu Cassandra după șase luni de viață? În general, nu există probleme nerezolvate. De asemenea, nu am permis accidente grave sau pierderi de date. Da, a trebuit să ne gândim să compensăm unele probleme care nu au apărut anterior, dar până la urmă acest lucru nu a întunecat foarte mult soluția noastră arhitecturală. Dacă doriți și nu vă este frică să încercați ceva nou și, în același timp, nu doriți să fiți prea dezamăgiți, atunci pregătiți-vă pentru faptul că nimic nu este gratuit. Va trebui să înțelegeți, să vă aprofundați în documentație și să vă asamblați propriul rake individual mai mult decât în ​​vechea soluție moștenită, și nicio teorie nu vă va spune dinainte care grebla vă așteaptă.

Sursa: www.habr.com

Adauga un comentariu