Tere kõigile! Minu nimi on Nikolai Golov. Varem töötasin Avitos ja juhtisin kuus aastat Data Platformi, tegeledes kõigi andmebaasidega: analüütiliste (Vertica, ClickHouse), voogedastuse ning OLTP (Redis, Tarantool, VoltDB, MongoDB, PostgreSQL). Selle aja jooksul sain tuttavaks suure hulga andmebaasidega — igasuguste ja ebatavaliste ning nende mitte-standardsete kasutusjuhtumitega.
Praegu töötan ManyChats. Tegelikult on see idufirma — uus, ambitsioonikas ja kiiresti kasvav. Ja kui ma alles ettevõttesse tulin, tõusis klassikaline küsimus: "Mida peaks noor idufirma praegu andmebaaside ja andmebaasisüsteemide turult valima?".
Selles artiklis, mis põhineb minu ettekandel , vastan sellele küsimusele. Ettekande videosilmus on saadaval .

Tuntud andmebaasid 2020. aastal
Aastal 2020 vaatasin ringi ja märkasin kolme tüüpi andmebaase.
Esimene tüüp — klassikalised OLTP andmebaasid: PostgreSQL, SQL Server, Oracle, MySQL. Need on kirjutatud ammu, kuid on endiselt asjakohased, kuna on arendajate seas hästi tuntud.
Teine tüüp — andmebaasid 2000ndatest. Nad üritasid kõrvale hiilida klassikalistest lahendustest, loobudes SQL-st, traditsioonilistest struktuuridest ja ACID-ist, lisades samas sisseehitatud jagamisfunktsioone ja muid atraktiivseid omadusi. Näiteks Cassandra, MongoDB, Redis või Tarantool. Kõik need lahendused soovisid turule pakkuda midagi põhimõtteliselt uut ja leidsid oma nishi, kuna need osutusid teatud ülesannete puhul äärmiselt mugavaks. Nende andmebaase võib nimetada katuseterminiks NOSQL.
«Nullaastad» on möödas, NOSQL andmebaasidega on harjutud, ja maailm, minu arvates, tegi järgmise sammu — managed andmebaasid. Nende andmebaaside tuum on sama, mis klassikalistel OLTP andmebaasidel või uutel NoSQL lahendustel. Kuid neil puudub vajadus DBA ja DevOps-i järele ning nad töötavad hallatavates serverites pilves. Arendaja jaoks on see «lihtsalt andmebaas», mis kuskil töötab, ja nagu see serveris paigaldatud on, kes serverit seadistab ja seda uuendab, ei huvita kedagi.
Näited sellistest andmebaasidest:
- AWS RDS — hallatav kattekiht PostgreSQL/i üle.
- DynamoDB — AWS-i analoog dokumentide põhist andmebaasi, sarnane Redis-i ja MongoDB-ga.
- Amazon Redshift — hallatav analüütiline andmebaas.
Põhjaks on need vanad andmebaasid, kuid proovitud hallatavas keskkonnas, ilma vajaduseta riistvaraga tegeleda.
Märkus. Näidised on võetud AWS keskkonnast, kuid need on saadaval ka Microsoft Azure'is, Google Cloud'is või Yandex.Cloud'is.

Mis selles uut on? 2020. aastal polnud sellest midagi uut.
Serverless kontseptsioon
Tõeliselt uus asi turul 2020. aastal on serverless või serveriteta lahendused.
Püüan selgitada, mida see tähendab tavalise teenuse või tagaplaanirakenduse näite kaudu.
Tavalise tagaplaanirakenduse juurutamiseks ostame või rentime serveri, kopeerime koodi sellele, avaldame välisele endpoint'ile ja maksame regulaarselt renti, elektrit ja andmekeskuse teenuseid. See on standardne skeem.
Kas on võimalik kuidagi teisiti? Serveriteta teenustega on see võimalik.
Mis on selle lähenemise fookus: ei ole serverit, isegi mitte virtuaalse instantsi rendile võtmist pilves. Teenuse juurutamiseks kopeerime koodi (funktsioonid) repertuaari ja avaldame välisele endpoint'ile. Edasi maksame lihtsalt iga selle funktsiooni kutsumise eest, täielikult ignoreerides riistvara, kus see täidetakse.
Püüan seda lähenemist illustreerida piltide kaudu.

Klassikaline juurutamine. Meil on teenus, millel on teatud koormus. Käivitame kaks instantsi: füüsilised serverid või instantsid AWS-is. Nendele instantsidele suunatakse välised päringud, mida seal töödeldakse.
Nagu pildilt näha, on serverid erinevalt ära kasutatud. Üks on kasutatud 100% ulatuses, seal on kaks päringut, ja üks ainult 50% ulatuses — osaliselt seiskunud. Kui tuleb mitte kolm päringut, vaid 30, siis kogu süsteem ei suuda koormust taluda ja hakkab aeglustuma.

Serverivaba juurutus. Serverivabas keskkonnas ei ole sellisel teenusel instantsid ega servereid. On mõningane kuumendatud ressursside hulk — väikesed ettevalmistatud Docker-konteinerid koos funktsiooni koodiga. Süsteem saab välised päringud ja igaühe jaoks serverivaba raamistik tõstab väikese konteineri koodiga: töötleb just selle päringu ja lõpetab konteineri.
Üks päring — üks käivitatud konteiner, 1000 päringut — 1000 konteinerit. Ja juurutamine raua serverites on juba pilveteenuse pakkuja töö. See on täielikult peidetud serverivaba raamistikuga. Selle kontseptsiooni raames maksame iga väljakutse eest. Näiteks, kui tuleb üks väljakutse päevas — maksame ühe väljakutse eest, tuleb miljon minutis — maksame miljoni eest. Või sekundis, nii ka juhtub.
Serverivaba funktsiooni avaldamise kontseptsioon sobib stateeless teenusele. Aga kui vajate (state) statefull teenust, siis lisame teenusele andmebaasi. Sellisel juhul, kui jõuame state'iga töötamiseni, kirjutab iga statefull funktsioon lihtsalt andmebaasi ja loeb sealt. Ja seejuures võib olla ühe kolmest tüübi andmebaasist, millest me artikli alguses rääkisime.
Milline on kõigi nende andmebaaside üldine piirang? See on pidevalt kasutatava pilve- või riistvaraserveri (või mitme serveri) kulud. Olgu need klassikalised andmebaasid või hallatud, olgu DevOps ja administraator olemas või mitte, maksame ikkagi 24/7 riistvara, elektri ja andmekeskuse üüri eest. Kui meil on klassikaline andmebaas, maksame masteri ja slave'i eest. Kui meil on kõrgelt koormatud jagatud andmebaas, maksame 10, 20 või 30 serveri eest ning maksame pidevalt.
Pidevalt reserveeritud serverite olemasolu kulustruktuuris peeti varem vältimatuks kurjuseks. Tavalistel andmebaasidel on ka muid raskusi, nagu ühenduste piirangud, skaleerimise piirangud ja geograafiline konsensus — neid saab teatud andmebaasides lahendada, kuid mitte kõiki korraga ja mitte ideaalselt.
Serverless andmebaas — teooria
Küsimus 2020. aastast: kas andmebaas võidakse ka serverless'iks muuta? Kõik on kuulnud serverless'ist tagaplaanist ... aga proovime ka andmebaasi serverless'iks muuta?
See kõlab kummaliselt, sest andmebaas on stateful teenus, mis ei sobi eriti serveriteta infrastruktuuri. Samuti on andmebaasi olek väga suur: gigabaitidest, terabaitidest, kuni analüüsibaasides isegi petabaitideni. Sellist ei saa lihtsalt kergetesse Docker-konteineritesse tõsta.
Teiselt poolt on peaaegu kõik kaasaegsed andmebaasid tohutu hulga loogikast ja komponentidest: tehingud, konsistentsi tagamine, protseduurid, suhtelised sõltuvused ja palju loogikat. Suure osa andmebaasi loogikast vajab suhteliselt väikest olekut. Gigabaitidest ja terabaitidest kasutatakse otse ainult vähest osa andmebaasi loogikast, mis on seotud päringute otse täitmisega.
Seega on idee, et kui osa loogikast lubab stateless täitmist, miks mitte jagada andmebaasi stateful ja stateless osadeks.
Serveriteta lahendused OLAP-i jaoks
Vaadakem, milline võiks välja näha andmebaaside jagamine stateful ja stateless osadeks praktiliste näidete kaudu.

Näiteks meil on analüüsibaas: välised andmed (punane silindril vasakul), ETL-protsess, mis laadib andmed andmebaasi, ja analüütik, kes esitab andmebaasile SQL-küsitlusi. See on klassikaline andmehoidla töö skeem.
Selles skeemis, tinglikult, täidetakse ETL üks kord. Edasi tuleb pidevalt maksta serverite eest, kus andmebaas töötab, kuhu on ETL-iga andmeid laaditud, et oleks, kuhu küsitlusi esitada.
Vaatame alternatiivset lähenemist, mida rakendab AWS Athena Serverless andmebaas. Siin pole pidevalt määratud riistvara, millel andmed on salvestatud. Selle asemel:
- Kasutaja esitab SQL-küsitluse Athendale. Athena optimeerija analüüsib SQL-küsitlust ja otsib metainformatsiooni (Metadata) salvestusest konkreetseid andmeid, mis on vajalikud küsitluse täitmiseks.
- Optimeerija, tuginedes kogutud andmetele, laadib vajalikud andmed välisest allikast ajutisse ladustamisse (ajutisse andmebaasi).
- Ajutises ladustamises täidetakse kasutaja SQL-küsitlus, tulemused tagastatakse kasutajale.
- Ajutine ladustamine tühjendatakse, ressursid vabastatakse.
Selles arhitektuuris maksame ainult küsitluse täitmise protsessi eest. Pole küsitlusi — pole kulusid.

See on töömeetod, mis rakendub mitte ainult Athena Serverlessis, vaid ka Redshift Spectrumis (AWS-is).
Athena näite põhjal on Serverless andmebaas tõeliselt töödelda päringuid, mis sisaldavad kümneid ja sadu terabaitide suuruseid andmeid. Sada terabaiti andmeid vajab sadu serveereid, kuid me ei pea nende eest maksma — me maksame päringute eest. Iga päringu kiirus on võrreldamatult madalam spetsialiseeritud analüütiliste andmebaaside, nagu Vertica, seas, ent me ei maksa ka seisakute eest.
Selline andmebaas sobib haruldaste analüütiliste ad-hoc päringute jaoks. Näiteks, kui otsustame spontaanselt kontrollida hüpoteesi mõne hiiglasliku andmemahu kohta. Nendes olukordades sobib Athena ideaalselt. Regulaarsete päringute puhul on see süsteem kallis. Sellisel juhul salvestage andmed mõnes spetsialiseeritud lahenduses.
Serverless OLTP lahenduste jaoks
Eelnevas näites käsitlesime OLAP-ülesandeid (analüütilised). Nüüd vaatleme OLTP-ülesandeid.
Esitame skaleeritavat PostgreSQL või MySQL. Alustame tavalise hallatava PostgreSQL või MySQL instantsi seadistamisega minimaalsete ressursside abil. Kui instantsile tuleb suurem koormus, ühendame täiendavad koopiad, millele jagame osa lugemisekoormusest. Kui päringute ja koormuse ei ole, lülitame koopiad välja. Esimene instants on meister ja ülejäänud on koopiad.
Seda ideed ellu viib andmebaas nimega Aurora Serverless AWS. Põhimõte on lihtne: välistest rakendustest tulevad päringud võtab vastu proxy fleet. Näha koormuse suurenemist, eraldab ta arvutusressursse eelsoojendatud minimaalsetest instantsidest — ühendamine toimub maksimaalselt kiiresti. Instantside väljalülitamine toimub samuti.
Aurora raames on mõisted Aurora Capacity Unit, ACU. See on (tinglikult) instants (server). Iga konkreetselt ACU võib olla meister või orjand. Igal Capacity Unit'il on oma töömälu, protsessor ja minimaalne ketas. Seega on üks meister ja ülejäänud on ainult lugemiseks mõeldud koopiad.
Needlike töötavate Aurora mahtuvuse üksuste arv on kohandatav parameeter. Miinimum võib olla üks või null (siis andmebaas ei tööta, kui päringuid pole).

Kui andmebaas saab päringud, tõstab proxy fleet Aurora mahtuvuse üksusi, suurendades süsteemi tootmisressursse. Ressursside suurendamise ja vähendamise võimalus võimaldab süsteemil ressursse 'pöörlevat' — automaatselt välja lülitada üksikud ACU-d (asendades need uutega) ja rakendada välja lülitatud ressurssidele kõik aktuaalsed uuendused.
Aurora Serverless andmebaas suudab skaleerida lugemise koormust. Kuid selles ei ole dokumentatsioonis otseselt öeldud. Võib tekkida tunne, et nad saavad tõsta multi-masteri. Kuid mingit imet ei ole.
See andmeid sobivad hästi, et mitte investeerida suuri summasid süsteemidesse, mille kättesaadavus on ettearvamatu. Näiteks MVP või turunduslike visiitkaartide loomisel ei oota me tavaliselt stabiilset koormust. Vastavalt sellele, kui juurdepääs puudub, ei maksa me instantside eest. Kui ootamatult tekib koormus, näiteks pärast konverentsi või reklaamikampaaniat, voolab suures koguses inimesi veebisaidile ja koormus tõuseb järsult, siis Aurora Serverless võtab selle koormuse automaatselt üle ja kiiresti liidab vajalikke ressursse (ACU). Pärast konverentsi unustatakse prototüüp ja serverid (ACU) kustutatakse, kulud langevad nulli — mugav.
See lahendus ei sobi stabiilsete kõrge koormusega olukordade jaoks, kuna see ei oska skaleerida kirjutamiskoormust. Kõik need ressursside ühendamised ja lahutamised toimuvad nn 'scale point'-i hetkel — ajal, mil andmebaasi ei hoia tehing ega ajutised tabelid. Näiteks võib scale point'i nädalas mitte toimuda, ja andmebaas töötab ühel ja samal ressursil ning ei suuda ei laieneda ega kokku tõmbuda.
Minge pole, see on tavaline PostgreSQL. Kuid masinate lisamise ja eemaldamise protsess on osaliselt automatiseeritud.
Serverless disainiga
Aurora Serverless on vana andmebaas, ümber kirjutatud pilvetoetamiseks, et kasutada serverless lähenemise eripära. Räägin nüüd andmebaasist, mis on algselt loodud pilve jaoks, serverless lähenemist silmas pidades — Serverless-by-design. Seda arendati kohe, arvestamata, et see töötab füüsilistel serveritel.
See andmebaas on nimega Snowflake. Selles on kolm olulist komponenti.

Esimene on metaandmete plokk. See on kiire in-memory teenus, mis lahendab turvalisuse, metaandmete, tehingute ja päringute optimeerimise küsimusi (vasakul illustratsioonil).
Teine plokk on hulk virtuaalseid arvutusklastreid arvutuste jaoks (illustratsioonil — rida siniseid ringe).
Kolmas plokk on andmete salvestamise süsteem S3 põhjal. S3 on AWS-is paisumatu objektipank, midagi nagu piiramatud Dropboxi lahendused ettevõtetele.
Vaatame, kuidas Snowflake töötab, eeldades külma käivitust. See tähendab, et baas on olemas, andmed on laaditud, kuid töövalmiduse päringud puuduvad. Seega, kui andmebaasile päringuid ei ole, tõstame kiire in-memory metadata teenuse (esimene plokk). Meil on ka S3 salvestus, kuhu on salvestatud tabeli andmed, jagatud nn mikropartiidesse. Lihtsuse huvides: kui tabelis on tehingud, siis mikropartiid on tehingute päevad. Iga päev on eraldi mikropartii, eraldi fail. Ja kui andmebaas töötab sellises režiimis, maksate ainult andmete ocuparitud koha eest. Samuti on koha hind väga madal (eriti arvestades suurt tihendust). Metadata teenus töötab pidevalt, kuid päringute optimeerimiseks ei ole palju ressursse vaja, seega võib teenust pidada tingimuslikult tasuta.
Kujutame nüüd ette, et meie andmebaasi tuli kasutaja ja esitas SQL päringu. SQL päring saadetakse kohe töötlemiseks metadata teenusele. Seega, pärast päringu saamist analüüsib see teenus päringut, saadaval olevaid andmeid, kasutaja õigusi ja kui kõik on korras, koostab päringutöötluse plaani.
Seejärel teenus käivitab arvutusklötši. Arvutusklöts koosneb serveritest, mis teostavad arvutusi. See tähendab, et klöts võib sisaldada 1 serverit, 2 serverit, 4, 8, 16, 32 — palju iganes soovite. Te esitate päringu ja selle alusel algab koheselt klötsi käivitamine. See tõesti võtab sekundeid.

Pärast klastrite käivitamist hakkavad S3-st klastrisse kopeerima mikropartiid, mis on vajalikud just teie päringu töötlemiseks. Oletame, et SQL-päringu täitmiseks on vaja kahte partiid ühest tabelist ja ühte teiselt. Sellisel juhul kopeeritakse klastrisse vaid need kolm vajalikku partiid, mitte kõik tabelid tervikuna. Just seetõttu, et kõik asub ühes andmekeskuses ja on ühendatud väga kiirete kanalitega, toimub kogu ülekandeprotsess väga kiiresti: sekundi jooksul, harva — minutitega, kui tegemist ei ole mõningate tohutute päringutega. Seega kopeeritakse mikropartiid arvutusklastrisse ja pärast selle lõpetamist täidetakse SQL-päring selles arvutusklastris. Selle päringu tulemuseks võib olla üks rida, mitu rida või tabel — need saadetakse kasutajale, et ta saaks need alla laadida, kuvada oma BI-otsingus või muul moel kasutada.
Iga SQL päring suudab mitte ainult arvutada aggregaatandmeid varasemalt laaditud andmetest, vaid ka laadida ja/või luua uusi andmeid andmebaasis. See tähendab, et tegemist võib olla päringuga, mis näiteks sisestab teise tabelisse uusi kirjeid, mis toob kaasa uue pariti moodustumise arvutusklastris, mis omakorda salvestatakse automaatselt ühte S3 salvestusse.
Ülaltoodud stsenaarium, alates kasutaja sisenemisest kuni klastrite loomise, andmete laadimise, päringute täitmise ja tulemuste saamiseni, arvestatakse virtuaalse arvutusklaastri, virtuaalse andmehoidla tunnitasu alusel. Tasu varieerub vastavalt AWS tsoonile ja klastrite suurusele, kuid keskmiselt on see paar dollarit tunnis. Neli masinat maksab kaks korda rohkem kui kaks masinat, kaheksa masinat maksab veel kaks korda rohkem. Saadaval on ka variandid 16 ja 32 masinat, olenevalt päringute keerukusest. Kuid maksate ainult nende minutite eest, mil klaster tõeliselt töötab, kuna päringute puudumisel eemaldatakse käed ja pärast 5-10 minutit ootamist (kohandatav parameeter) lülitub see ise välja, vabastab ressursid ja muutub tasuta.
On täiesti reaalne stsenaarium, kus teete päringu, klaster tõuseb, ütleme, minutiga, veel minut kalkuleerib, seejärel viis minutit väljalülitamiseks, ja kokku maksate seitsme minuti töö eest, mitte kuude ja aastate eest.
Esimene stsenaarium kirjeldas Snowflake'i kasutamist ühe kasutaja variandina. Nüüd kujutame ette, et kasutajaid on palju, mis on lähemal reaalsele stsenaariumile.
Oletame, et meil on palju analüütikuid ja Tableau aruandeid, mis pidevalt pommitavad meie andmebaasi suure hulga lihtsate analüütiliste SQL-päringutega.
Lisaks eeldame, et meil on leidlikud and teadlased, kes püüavad andmetega teha keerulisi asju, hallates kümneid terabaiti, analüüsides miljardeid ja triljoneid andmerekke.
Ülaltoodud kahe koormuse tüübi jaoks võimaldab Snowflake tõsta mitmeid sõltumatuid arvutusklastreid erineva jõudlusega. Need arvutusklastrid töötavad iseseisvalt, kuid jagavad ühte ja sama kooskõlastatud andmebaasi.
Palju lihtsate päringute jaoks on võimalik luua 2-3 väikest klastrit, igaühes umbes 2 seadet. Selline toimimine on teostatav ka automaatsete seadistuste kaudu. Toimimiseks võite öelda: "Snowflake, tõsta üles väike klaster. Kui koormus sellele ületab teatud väärtuse, tõsta üles sarnane teine või kolmas klaster. Kui koormus hakkab langema, lülita liigne välja." Nii tagate, et olenemata sellest, kui palju analüütikuid tuleb ja alustab aruannete vaatamist, jätkub kõigile piisavalt ressursse.
Kui aga analüütikud magavad ja keegi ei vaata aruandeid, võivad klastrid täielikult välja lülituda ning te lõpetate nende eest maksmise.
Raskete päringute korral (andmete teadlased) võite tõsta üles ühe väga suure klastrit, kus on tinglikult 32 seadet. Ka selle klastriga maksate ainult nende minutite ja tundide eest, mil teie tohutu päring seal töötab.
Ülaltoodud võimalus võimaldab jagada klastreid mitte ainult kahe, vaid ka rohkemate koormustüüpide vahel (ETL, jälgimine, aruannete materialiseerimine,…).
Teeme kokkuvõtte Snowflake'ist. Platvorm ühendab kauni idee ja toimiva rakenduse. Meie ManyChat'is kasutame Snowflake'i kõigi olemasolevate andmete analüüsiks. Meil on klastreid mitte kolm, nagu näites, vaid viiest kuni üheksast, erineva suurusega. Meil on kuue masinaga, kaheteist masinaga ja superväikse ühe masinaga teatud ülesannete jaoks. Need jagavad koormust edukalt ja võimaldavad meil palju säästa.
Platvorm suudab edukalt skaleerida lugemis- ja kirjutamiskoormust. See on tohutu erinevus ja suur läbimurre võrreldes näiteks 'Aurora'ga, mis said vaid lugemisekoormust hoidma. Snowflake võimaldab nende arvutusklastrite abil skaleerida ka kirjutamiskoormust. Nagu ma mainisin, kasutatakse ManyChat's mitmeid klastreid, väikseid ja superväikseid klastreid, peamiselt ETL-ide jaoks, andmete laadimiseks. Analüütikud töötavad juba keskmistes klastrites, mis ei ole ETL-koormusest mõjutatud, seega töötavad nad väga kiiresti.
Seega sobib andmebaas hästi OLAP ülesannete jaoks. Kahjuks ei ole see siiski veel rakendatav OLTP koormustele. Esiteks on see kolonniline andmebaas, koos kõikide sellest tulenevate tagajärgedega. Teiseks, lähenemine, kus tõstate iga päringu korral vajadusel üles arvutusklastri ja voolutate sinna andmed, ei ole kahjuks OLTP koormuste jaoks piisavalt kiire. Sekundite ootamine OLAP ülesannete puhul on normaalne, aga OLTP koormuste puhul on see vastuvõetamatu, pigem peaks olema 100 ms, veel parem — 10 ms.
Kokkuvõte
Serverless andmebaas on võimalik tänu andmebaasi jagamisele venituseta ja olekuga osadeks. Olete kindlasti märganud, et kõikides toodud näidetes on olekuga osa — tinglikult öeldes, mikropartiide säilitamine S3-s, samas kui venituseta on optimeerija, töö metaandmetega, turvaküsimuste käsitlemine, mida saab tõsta iseseisvate kergete venituseta teenustena.
SQL-päringute täitmist võib samuti mõista kui kerge olekuga teenuseid, mis võivad ilmuda serverivabas režiimis, nagu Snowflake arvutusklastrid, laadides alla ainult vajalikud andmed, tehes päringu ja "sammutades" end.
Serverless tootetase on nüüd saadaval ja töötab. Need serverless andmebaasid on juba valmis OLAP-ülesannete täitmiseks. Kahjuks kasutatakse neid OLTP-ülesannete jaoks… teatud piirangutega, mis on keeruline teema. Ühest küljest on see miinus. Kuid teiselt poolt on see võimalus. Võib-olla leiab mõni lugeja viisi, kuidas teha OLTP-andmebaas täiesti serverless, ilma piiranguteta Aurora.
Loodan, et see oli teile huvitav. Serverless tuleviku nimel 🙂
Allikas: habr.com
