Către baze de date fără server - cum și de ce

Salutare tuturor! Numele meu este Golov Nikolay. Anterior, am lucrat la Avito și am gestionat Data Platform timp de șase ani, adică am lucrat pe toate bazele de date: analitice (Vertica, ClickHouse), streaming și OLTP (Redis, Tarantool, VoltDB, MongoDB, PostgreSQL). În acest timp, m-am ocupat cu un număr mare de baze de date - foarte diferite și neobișnuite, și cu cazuri nestandard de utilizare a acestora.

În prezent lucrez la ManyChat. În esență, acesta este un startup - nou, ambițios și în creștere rapidă. Și când m-am alăturat pentru prima dată în companie, a apărut o întrebare clasică: „Ce ar trebui să ia acum un tânăr startup de pe piața DBMS și a bazelor de date?”

În acest articol, pe baza raportului meu la festival online RIT++2020, voi răspunde la această întrebare. O versiune video a raportului este disponibilă la YouTube.

Către baze de date fără server - cum și de ce

Baze de date cunoscute în mod obișnuit 2020

Este 2020, m-am uitat în jur și am văzut trei tipuri de baze de date.

primul tip - baze de date OLTP clasice: PostgreSQL, SQL Server, Oracle, MySQL. Au fost scrise cu mult timp în urmă, dar sunt încă relevante pentru că sunt atât de familiare comunității de dezvoltatori.

Al doilea tip - baze de la "zero". Au încercat să se îndepărteze de tiparele clasice, abandonând SQL, structurile tradiționale și ACID, prin adăugarea de fragmentare încorporată și alte caracteristici atractive. De exemplu, aceasta este Cassandra, MongoDB, Redis sau Tarantool. Toate aceste soluții au vrut să ofere pieței ceva fundamental nou și și-au ocupat nișa pentru că s-au dovedit a fi extrem de convenabile pentru anumite sarcini. Voi desemna aceste baze de date cu termenul umbrelă NOSQL.

„Zerourile” s-au terminat, ne-am obișnuit cu bazele de date NOSQL și lumea, din punctul meu de vedere, a făcut următorul pas - să baze de date gestionate. Aceste baze de date au același nucleu ca bazele de date OLTP clasice sau cele noi NoSQL. Dar nu au nevoie de DBA și DevOps și rulează pe hardware gestionat în cloud. Pentru un dezvoltator, aceasta este „doar o bază” care funcționează undeva, dar nimănui nu îi pasă cum este instalat pe server, cine a configurat serverul și cine îl actualizează.

Exemple de astfel de baze de date:

  • AWS RDS este un wrapper gestionat pentru PostgreSQL/MySQL.
  • DynamoDB este un analog AWS al unei baze de date bazate pe documente, similar cu Redis și MongoDB.
  • Amazon Redshift este o bază de date analitică gestionată.

Acestea sunt practic baze de date vechi, dar ridicate într-un mediu gestionat, fără a fi nevoie să lucrezi cu hardware.

Notă. Exemplele sunt luate pentru mediul AWS, dar analogii lor există și în Microsoft Azure, Google Cloud sau Yandex.Cloud.

Către baze de date fără server - cum și de ce

Ce e nou în asta? În 2020, nimic din toate acestea.

Conceptul fără server

Ceea ce este cu adevărat nou pe piață în 2020 sunt soluțiile serverless sau serverless.

Voi încerca să explic ce înseamnă acest lucru folosind exemplul unui serviciu obișnuit sau al unei aplicații backend.
Pentru a implementa o aplicație backend obișnuită, cumpărăm sau închiriem un server, copiem codul pe acesta, publicăm punctul final în exterior și plătim în mod regulat chiria, electricitatea și serviciile centrului de date. Aceasta este schema standard.

Există vreo altă cale? Cu servicii fără server puteți.

Care este punctul central al acestei abordări: nu există server, nici măcar nu există închirierea unei instanțe virtuale în cloud. Pentru a implementa serviciul, copiați codul (funcțiile) în depozit și publicați-l la punctul final. Apoi plătim pur și simplu pentru fiecare apel la această funcție, ignorând complet hardware-ul în care este executată.

Voi încerca să ilustrez această abordare cu imagini.
Către baze de date fără server - cum și de ce

Desfăşurare clasică. Avem un serviciu cu o anumită sarcină. Ridicăm două instanțe: servere fizice sau instanțe în AWS. Solicitările externe sunt trimise la aceste instanțe și procesate acolo.

După cum puteți vedea în imagine, serverele nu sunt eliminate în mod egal. Una este utilizată 100%, există două solicitări, iar una este doar 50% - parțial inactiv. Dacă nu sosesc trei solicitări, ci 30, atunci întregul sistem nu va putea face față sarcinii și va începe să încetinească.

Către baze de date fără server - cum și de ce

Implementare fără server. Într-un mediu fără server, un astfel de serviciu nu are instanțe sau servere. Există un anumit grup de resurse încălzite - containere Docker mici pregătite cu cod de funcție implementat. Sistemul primește solicitări externe și pentru fiecare dintre ele framework-ul fără server ridică un mic container cu cod: procesează această solicitare particulară și omoara containerul.

O cerere - un container ridicat, 1000 de cereri - 1000 de containere. Iar implementarea pe servere hardware este deja opera furnizorului de cloud. Este complet ascuns de cadrul fără server. În acest concept plătim pentru fiecare apel. De exemplu, un apel a venit pe zi - am plătit pentru un apel, a venit un milion pe minut - am plătit pentru un milion. Sau într-o secundă se întâmplă și asta.

Conceptul de publicare a unei funcții fără server este potrivit pentru un serviciu fără stat. Și dacă aveți nevoie de un serviciu complet (de stat), atunci adăugăm o bază de date la serviciu. În acest caz, când vine vorba de lucrul cu starea, fiecare funcție cu stare plină pur și simplu scrie și citește din baza de date. Mai mult, dintr-o bază de date cu oricare dintre cele trei tipuri descrise la începutul articolului.

Care este limitarea comună a tuturor acestor baze de date? Acestea sunt costurile unui server cloud sau hardware utilizat în mod constant (sau mai multor servere). Nu contează dacă folosim o bază de date clasică sau gestionată, dacă avem Devops și un administrator sau nu, plătim în continuare hardware, electricitate și închiriere de centre de date 24/7. Dacă avem o bază clasică, plătim pentru stăpân și sclav. Dacă este o bază de date fragmentată foarte încărcată, plătim pentru 10, 20 sau 30 de servere și plătim în mod constant.

Prezența serverelor rezervate permanent în structura costurilor era percepută anterior ca un rău necesar. Bazele de date convenționale au și alte dificultăți, precum limitele numărului de conexiuni, restricțiile de scalare, consensul geo-distribuit - pot fi rezolvate cumva în anumite baze de date, dar nu toate odată și nu în mod ideal.

Baza de date fără server - teorie

Întrebare din 2020: este posibil să faci și o bază de date fără server? Toată lumea a auzit despre backend-ul fără server... să încercăm să facem baza de date fără server?

Acest lucru sună ciudat, deoarece baza de date este un serviciu cu stat, nu foarte potrivit pentru infrastructura fără server. În același timp, starea bazei de date este foarte mare: gigabytes, terabytes, iar în bazele de date analitice chiar petabytes. Nu este atât de ușor să-l ridici în containere Docker ușoare.

Pe de altă parte, aproape toate bazele de date moderne conțin o cantitate imensă de logică și componente: tranzacții, coordonarea integrității, proceduri, dependențe relaționale și multă logică. Pentru destul de multă logică a bazei de date, o stare mică este suficientă. Gigabytes și Terabytes sunt utilizați direct doar de o mică parte din logica bazei de date implicată în executarea directă a interogărilor.

În consecință, ideea este: dacă o parte a logicii permite execuția fără stat, de ce să nu împărțiți baza în părți Stateful și Stateless.

Serverless pentru soluții OLAP

Să vedem cum ar putea arăta tăierea unei baze de date în părți Stateful și Stateless folosind exemple practice.

Către baze de date fără server - cum și de ce

De exemplu, avem o bază de date analitică: date externe (cilindrul roșu în stânga), un proces ETL care încarcă date în baza de date și un analist care trimite interogări SQL în baza de date. Aceasta este o schemă clasică de operare a depozitului de date.

În această schemă, ETL este efectuat condiționat o dată. Apoi trebuie să plătiți constant pentru serverele pe care rulează baza de date cu date pline cu ETL, astfel încât să existe ceva la care să trimiteți interogări.

Să ne uităm la o abordare alternativă implementată în AWS Athena Serverless. Nu există hardware dedicat permanent pe care să fie stocate datele descărcate. In loc de asta:

  • Utilizatorul trimite o interogare SQL către Athena. Optimizatorul Athena analizează interogarea SQL și caută în depozitul de metadate (Metadate) datele specifice necesare pentru a executa interogarea.
  • Optimizatorul, pe baza datelor colectate, descarcă datele necesare din surse externe în stocarea temporară (bază de date temporară).
  • O interogare SQL de la utilizator este executată în stocare temporară și rezultatul este returnat utilizatorului.
  • Stocarea temporară este șters și resursele sunt eliberate.

În această arhitectură, plătim doar pentru procesul de executare a cererii. Fără solicitări - fără costuri.

Către baze de date fără server - cum și de ce

Aceasta este o abordare de lucru și este implementată nu numai în Athena Serverless, ci și în Redshift Spectrum (în AWS).

Exemplul Athena arată că baza de date Serverless funcționează pe interogări reale cu zeci și sute de Terabytes de date. Sute de Terabytes vor necesita sute de servere, dar nu trebuie să plătim pentru ele - plătim pentru solicitări. Viteza fiecărei solicitări este (foarte) mică în comparație cu bazele de date analitice specializate precum Vertica, dar nu plătim pentru perioadele de nefuncționare.

O astfel de bază de date este aplicabilă pentru interogări ad-hoc analitice rare. De exemplu, când decidem spontan să testăm o ipoteză pe o cantitate gigantică de date. Athena este perfectă pentru aceste cazuri. Pentru cererile obișnuite, un astfel de sistem este costisitor. În acest caz, stocați în cache datele într-o soluție specializată.

Serverless pentru soluții OLTP

Exemplul anterior a analizat sarcinile OLAP (analitice). Acum să ne uităm la sarcinile OLTP.

Să ne imaginăm PostgreSQL sau MySQL scalabil. Să ridicăm o instanță gestionată obișnuită PostgreSQL sau MySQL cu resurse minime. Când instanța primește mai multă încărcare, vom conecta replici suplimentare cărora le vom distribui o parte din sarcina de citire. Dacă nu există solicitări sau încărcare, oprim replicile. Prima instanță este masterul, iar restul sunt replici.

Această idee este implementată într-o bază de date numită Aurora Serverless AWS. Principiul este simplu: cererile din aplicațiile externe sunt acceptate de flota de proxy. Văzând că sarcina crește, alocă resurse de calcul din instanțe minime preîncălzite - conexiunea se realizează cât mai repede posibil. Dezactivarea instanțelor are loc în același mod.

În cadrul Aurora există conceptul de Aurora Capacity Unit, ACU. Aceasta este (condițional) o instanță (server). Fiecare ACU specific poate fi un master sau un slave. Fiecare unitate de capacitate are propriul său RAM, procesor și disc minim. În consecință, unul este maestru, restul sunt replici doar pentru citire.

Numărul acestor unități de capacitate Aurora care rulează este un parametru configurabil. Cantitatea minimă poate fi una sau zero (în acest caz, baza de date nu funcționează dacă nu există solicitări).

Către baze de date fără server - cum și de ce

Când baza primește solicitări, flota de proxy ridică Aurora CapacityUnits, crescând resursele de performanță ale sistemului. Capacitatea de a crește și reduce resursele permite sistemului să „jongleze” cu resurse: să afișeze automat ACU-urile individuale (înlocuindu-le cu altele noi) și să lanseze toate actualizările curente ale resurselor retrase.

Baza Aurora Serverless poate scala sarcina de citire. Dar documentația nu spune acest lucru în mod direct. S-ar putea să simtă că pot ridica un multi-master. Nu există magie.

Această bază de date este potrivită pentru a evita cheltuirea unor sume uriașe de bani pe sisteme cu acces imprevizibil. De exemplu, când creăm MVP sau site-uri de marketing pentru cărți de vizită, de obicei nu ne așteptăm la o încărcare stabilă. În consecință, dacă nu există acces, nu plătim pentru instanțe. Când apare o încărcare neașteptată, de exemplu după o conferință sau o campanie publicitară, mulțimi de oameni vizitează site-ul și încărcarea crește dramatic, Aurora Serverless preia automat această încărcare și conectează rapid resursele lipsă (ACU). Apoi, conferința trece, toată lumea uită de prototip, serverele (ACU) se întunecă, iar costurile scad la zero - convenabil.

Această soluție nu este potrivită pentru încărcare mare stabilă, deoarece nu scalează sarcina de scriere. Toate aceste conexiuni și deconectări de resurse au loc la așa-numitul „punct de scară” - un moment în timp în care baza de date nu este suportată de o tranzacție sau de tabele temporare. De exemplu, în decurs de o săptămână, punctul de scară poate să nu se întâmple, iar baza funcționează pe aceleași resurse și pur și simplu nu se poate extinde sau contracta.

Nu există magie - este PostgreSQL obișnuit. Dar procesul de adăugare și deconectare a mașinilor este parțial automatizat.

Fără server prin design

Aurora Serverless este o bază de date veche rescrisă pentru cloud pentru a profita de unele dintre beneficiile Serverless. Și acum vă voi spune despre baza, care a fost scrisă inițial pentru cloud, pentru abordarea serverless - Serverless-by-design. A fost dezvoltat imediat fără a presupune că va rula pe servere fizice.

Această bază se numește Fulg de zăpadă. Are trei blocuri cheie.

Către baze de date fără server - cum și de ce

Primul este un bloc de metadate. Acesta este un serviciu rapid în memorie care rezolvă problemele legate de securitate, metadate, tranzacții și optimizarea interogărilor (prezentat în ilustrația din stânga).

Al doilea bloc este un set de clustere de calcul virtuale pentru calcule (în ilustrație există un set de cercuri albastre).

Al treilea bloc este un sistem de stocare a datelor bazat pe S3. S3 este stocarea de obiecte fără dimensiuni în AWS, un fel de Dropbox fără dimensiuni pentru afaceri.

Să vedem cum funcționează Snowflake, presupunând o pornire la rece. Adică există o bază de date, datele sunt încărcate în ea, nu există interogări care rulează. În consecință, dacă nu există solicitări către baza de date, atunci am ridicat serviciul rapid de metadate în memorie (primul bloc). Și avem stocare S3, unde sunt stocate datele din tabel, împărțite în așa-numitele micropartiții. Pentru simplitate: dacă tabelul conține tranzacții, atunci micropartițiile sunt zilele tranzacțiilor. Fiecare zi este o micropartiție separată, un fișier separat. Și când baza de date funcționează în acest mod, plătești doar pentru spațiul ocupat de date. Mai mult, rata pe loc este foarte scăzută (mai ales ținând cont de compresia semnificativă). Serviciul de metadate funcționează și el în mod constant, dar nu aveți nevoie de multe resurse pentru a optimiza interogările, iar serviciul poate fi considerat shareware.

Acum să ne imaginăm că un utilizator a venit la baza noastră de date și a trimis o interogare SQL. Interogarea SQL este trimisă imediat serviciului de metadate pentru procesare. În consecință, la primirea unei solicitări, acest serviciu analizează cererea, datele disponibile, permisiunile utilizatorului și, dacă totul este bine, întocmește un plan de procesare a cererii.

Apoi, serviciul inițiază lansarea clusterului de calcul. Un cluster de calcul este un cluster de servere care efectuează calcule. Adică acesta este un cluster care poate conține 1 server, 2 servere, 4, 8, 16, 32 - câte doriți. Lansați o solicitare și lansarea acestui cluster începe imediat. Chiar durează câteva secunde.

Către baze de date fără server - cum și de ce

Apoi, după ce clusterul a pornit, micropartițiile necesare procesării cererii încep să fie copiate în cluster din S3. Adică, să ne imaginăm că pentru a executa o interogare SQL aveți nevoie de două partiții dintr-un tabel și una din al doilea. În acest caz, numai cele trei partiții necesare vor fi copiate în cluster și nu toate tabelele în întregime. De aceea, și tocmai pentru că totul este situat într-un singur centru de date și conectat prin canale foarte rapide, întregul proces de transfer are loc foarte rapid: în secunde, foarte rar în minute, cu excepția cazului în care vorbim de niște solicitări monstruoase. În consecință, micropartițiile sunt copiate în clusterul de calcul și, la finalizare, interogarea SQL este executată pe acest cluster de calcul. Rezultatul acestei solicitări poate fi o linie, mai multe rânduri sau un tabel - acestea sunt trimise extern utilizatorului, astfel încât acesta să o poată descărca, să le afișeze în instrumentul său BI sau să le folosească într-un alt mod.

Fiecare interogare SQL poate citi nu numai agregate din datele încărcate anterior, ci și încărca/genera date noi în baza de date. Adică, poate fi o interogare care, de exemplu, inserează înregistrări noi într-un alt tabel, ceea ce duce la apariția unei noi partiții pe clusterul de calcul, care, la rândul său, este salvată automat într-o singură stocare S3.

Scenariul descris mai sus, de la sosirea utilizatorului până la ridicarea clusterului, încărcarea datelor, executarea interogărilor, obținerea rezultatelor, se plătește la tariful pentru minute de utilizare a clusterului de calcul virtual ridicat, depozit virtual. Rata variază în funcție de zona AWS și dimensiunea clusterului, dar în medie este de câțiva dolari pe oră. Un grup de patru mașini este de două ori mai scump decât un grup de două mașini, iar un grup de opt mașini este încă de două ori mai scump. Sunt disponibile optiuni de 16, 32 de masini, in functie de complexitatea solicitarilor. Dar plătești doar pentru acele minute în care clusterul rulează efectiv, pentru că atunci când nu există solicitări, îți cam iei mâinile jos, iar după 5-10 minute de așteptare (un parametru configurabil) se va opri de la sine, eliberați resurse și deveniți liberi.

Un scenariu complet realist este atunci când trimiteți o solicitare, clusterul apare, relativ vorbind, într-un minut, contează încă un minut, apoi cinci minute pentru a se închide și ajungeți să plătiți pentru șapte minute de funcționare a acestui cluster și nu de luni si ani.

Primul scenariu descris folosind Snowflake într-o setare pentru un singur utilizator. Acum să ne imaginăm că există mulți utilizatori, ceea ce este mai aproape de scenariul real.

Să presupunem că avem o mulțime de analiști și rapoarte Tableau care ne bombardează în mod constant baza de date cu un număr mare de interogări SQL analitice simple.

În plus, să presupunem că avem Data Scientist inventivi care încearcă să facă lucruri monstruoase cu date, operează cu zeci de Terabytes, analizează miliarde și trilioane de rânduri de date.

Pentru cele două tipuri de încărcătură de lucru descrise mai sus, Snowflake vă permite să creați mai multe grupuri de calcul independente cu capacități diferite. Mai mult, aceste clustere de calcul funcționează independent, dar cu date comune consistente.

Pentru un număr mare de interogări ușoare, puteți ridica 2-3 grupuri mici, cu aproximativ 2 mașini fiecare. Acest comportament poate fi implementat, printre altele, folosind setări automate. Deci spui: „Fulg de zăpadă, ridică un grup mic. Dacă sarcina asupra acestuia crește peste un anumit parametru, ridicați o secundă similară, a treia. Când sarcina începe să scadă, stingeți excesul.” Pentru ca oricât de mulți analiști vin și încep să se uite la rapoarte, toată lumea are suficiente resurse.

În același timp, dacă analiștii dorm și nimeni nu se uită la rapoarte, clusterele se pot întuneca complet și nu mai plătiți pentru ele.

În același timp, pentru interogări grele (de la Data Scientists), puteți crea un cluster foarte mare pentru 32 de mașini. Acest cluster va fi, de asemenea, plătit numai pentru acele minute și ore în care cererea dvs. gigantică rulează acolo.

Oportunitatea descrisă mai sus vă permite să împărțiți nu doar 2, ci și mai multe tipuri de încărcătură de lucru în clustere (ETL, monitorizare, materializare raport,...).

Să rezumam Fulgul de zăpadă. Baza combină o idee frumoasă și o implementare viabilă. La ManyChat, folosim Snowflake pentru a analiza toate datele pe care le avem. Nu avem trei grupuri, ca în exemplu, ci de la 5 la 9, de dimensiuni diferite. Avem cele convenționale cu 16 mașini, 2 mașini și, de asemenea, cele super-mici cu 1 mașină pentru unele sarcini. Ele distribuie cu succes sarcina și ne permit să economisim mult.

Baza de date scalează cu succes sarcina de citire și scriere. Aceasta este o diferență uriașă și o descoperire uriașă în comparație cu aceeași „Aurora”, care a suportat doar sarcina de citire. Snowflake vă permite să vă scalați volumul de lucru de scriere cu aceste clustere de calcul. Adică, așa cum am menționat, folosim mai multe clustere în ManyChat, clusterele mici și super-mici sunt folosite în principal pentru ETL, pentru încărcarea datelor. Și analiștii trăiesc deja pe clustere medii, care nu sunt absolut afectate de încărcarea ETL, așa că funcționează foarte repede.

În consecință, baza de date este potrivită pentru sarcini OLAP. Cu toate acestea, din păcate, nu este încă aplicabil pentru sarcinile de lucru OLTP. În primul rând, această bază de date este coloană, cu toate consecințele care decurg. În al doilea rând, abordarea în sine, când pentru fiecare cerere, dacă este necesar, ridicați un cluster de calcul și îl inundați cu date, din păcate, nu este încă suficient de rapidă pentru încărcările OLTP. Este normal să așteptați câteva secunde pentru sarcinile OLAP, dar pentru sarcinile OLTP este inacceptabil; 100 ms ar fi mai bine sau 10 ms ar fi chiar mai bine.

Total

O bază de date fără server este posibilă prin împărțirea bazei de date în părți Stateless și Stateful. Poate că ați observat că în toate exemplele de mai sus, partea Stateful este, relativ vorbind, stocarea micro-partițiilor în S3, iar Stateless este optimizatorul, lucrând cu metadate, gestionând problemele de securitate care pot fi ridicate ca servicii independente ușoare Stateless.

Executarea interogărilor SQL poate fi percepută și ca servicii în stare ușoară care pot apărea în modul fără server, cum ar fi clusterele de calcul Snowflake, descarcă numai datele necesare, execută interogarea și „ieși”.

Bazele de date la nivel de producție fără server sunt deja disponibile pentru utilizare, funcționează. Aceste baze de date fără server sunt deja pregătite pentru a gestiona sarcini OLAP. Din păcate, pentru sarcinile OLTP sunt folosite... cu nuanțe, deoarece există limitări. Pe de o parte, acesta este un minus. Dar, pe de altă parte, aceasta este o oportunitate. Poate că unul dintre cititori va găsi o modalitate de a face o bază de date OLTP complet fără server, fără limitările Aurora.

Sper că l-ai găsit interesant. Serverless este viitorul :)

Sursa: www.habr.com

Adauga un comentariu