{"id":37956,"date":"2019-10-31T22:20:47","date_gmt":"2019-10-31T19:20:47","guid":{"rendered":"https:\/\/prohoster.info\/blog\/newsql-nosql-acid\/"},"modified":"2019-10-31T22:20:47","modified_gmt":"2019-10-31T19:20:47","slug":"newsql-nosql-acid","status":"publish","type":"post","link":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/newsql-nosql-acid","title":{"rendered":"NewSQL = NoSQL+ACID","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"NewSQL = NoSQL+ACID\" src=\"\/wp-content\/uploads\/2019\/09\/973145efa566bca10ffe7ba95733a1d5.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nKuni hiljuti hoiti Odnoklassnikovis umbes 50 TB reaalajas t\u00f6\u00f6deldud andmeid SQL Serveris. Sellise mahuga kiire ja usaldusv\u00e4\u00e4rse, veelgi enam, t\u00f5rgetekindla andmekeskuse juurdep\u00e4\u00e4su tagamine, kasutades SQL andmebaasi, on peaaegu v\u00f5imatu. Tavaliselt kasutatakse sellistes olukordades \u00fchte NoSQL-andmehoidlatest, kuid mitte k\u00f5ike ei saa \u00fcle viia NoSQL-i: m\u00f5ned \u00fcksused n\u00f5uavad ACID-tehingute garantiisi. <\/p>\n<p>See viis meid NewSQL-andmehoidla kasutamiseni, st andmebaasi, mis pakub t\u00f5rketaluvust, skaleeritavust ja NoSQL-s\u00fcsteemide kiirus, kuid s\u00e4ilitab samas klassikaliste s\u00fcsteemide ACID-garantii. T\u00f6\u00f6stuslikke s\u00fcsteeme selle uue klassi jaoks on v\u00e4he, seega rakendasime sellise s\u00fcsteemi ise ja k\u00e4ivitasime selle t\u00f6\u00f6stuslikuks kasutamiseks. <\/p>\n<p>Kuidas see toimib ja mis v\u00e4lja tuli \u2014 loe edasi.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nT\u00e4na on \u201eOdnoklassnikovite\u201d kuine publik \u00fcle 70 miljoni unikaalse k\u00fclastaja. Me <noindex><a rel=\"nofollow\" href=\"https:\/\/www.similarweb.com\/top-websites\/category\/internet-and-telecom\/social-network\">oleme viie<\/a><\/noindex> suurima sotsiaalmeedia platvormi seas maailmas ja kahek\u00fcmne hulgas veebisaitide seas, kus kasutajad veedavad k\u00f5ige rohkem aega. \u201eOK\u201d infrastruktuur t\u00f6\u00f6tleb v\u00e4ga suuri koormusi: \u00fcle miljjoni HTTP-p\u00e4ringu sekundis frontides. \u00dcle 8000 serveri moodustavad serveripargi, mis asuvad \u00fcksteise l\u00e4hedal \u2013 neljas Moskva andmekeskuses, mis v\u00f5imaldab tagada v\u00f5rgu latentsuse alla 1 ms nende vahel.<\/p>\n<p>Oleme Cassandra't kasutanud alates 2010. aastast, alustades versioonist 0.6. T\u00e4na on kasutuses mituk\u00fcmmend klastrit. Kiireim klaster t\u00f6\u00f6tleb \u00fcle 4 miljoni operatsiooni sekundis, samas kui suurim salvestab 260 TB. <\/p>\n<p>Kuid k\u00f5ik need on tavalised NoSQL-klastrid, mida kasutatakse <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A1%D0%BE%D0%B3%D0%BB%D0%B0%D1%81%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C_%D0%B2_%D0%BA%D0%BE%D0%BD%D0%B5%D1%87%D0%BD%D0%BE%D0%BC_%D1%81%D1%87%D1%91%D1%82%D0%B5\">madala koosk\u00f5lastatuse<\/a><\/noindex> andmete s\u00e4ilitamiseks. Soovisime aga asendada p\u00f5hikoosk\u00f5lastatud andmehoidla, Microsoft SQL Serveri, mida on kasutatud \u201eOdnoklassnikovite\u201d loomise hetkest. Andmehoidla koosnes rohkem kui 300 SQL Server Standard Edition masinast, millel oli 50 TB andmeid \u2013 \u00e4rilisi entiteete. Need andmed muudetakse ACID-tehingute k\u00e4igus ja n\u00f5uavad <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/ACID\">k\u00f5rget koosk\u00f5lastatust.<\/a><\/noindex>.<\/p>\n<p>SQL Serveri andmete jaotamiseks s\u00f5lmedesse kasutasime nii vertikaalset kui ka horisontaalset <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Partition_(database)\">partitsioneerimist.<\/a><\/noindex> (sharding). Ajalooliselt oleme kasutanud lihtsat andmete \u0161ardimise skeemi: igale \u00fcksusele m\u00e4\u00e4rati token - funktsioon \u00fcksuse ID-st. \u00dcksused, millel on sama token, pandi \u00fchele SQL-serverile. Master-detail t\u00fc\u00fcpi suhe rakendati nii, et p\u00f5hikirje ja selle aluskirje tokenid olid alati samad ja paiknesid samal serveril. Sotsiaalv\u00f5rgustikus genereeritakse peaaegu k\u00f5ik kirjed kasutaja nime alt - see t\u00e4hendab, et k\u00f5iki kasutaja andmeid hoitakse \u00fche funktsionaalsete s\u00fcsteemide raames \u00fchel serveril. Seega osalesid \u00e4ritehingutes peaaegu alati sama SQL-serveri tabelid, mis v\u00f5imaldas andmete j\u00e4rjepidevust tagada kohalike ACID-tehingute kaudu, ilma vajaduseta kasutada <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Two-phase_commit_protocol\">aeglaseid ja ebaturvalisi<\/a><\/noindex> jaotatud ACID-tehinguid.<\/p>\n<p>\u0160ardingu ja SQL-i t\u00f6\u00f6 kiirendamiseks:<\/p>\n<ul>\n<li>Ei kasuta v\u00e4lismaiseid v\u00f5tme piiranguid, kuna \u0161ardimise puhul v\u00f5ib \u00fcksuse ID olla teisel serveril.<\/li>\n<li>Ei kasuta salvestatud protseduure ega trikke, kuna need koormavad andmebaasi CPU-d.<\/li>\n<li>Ei kasuta JOIN-e eelnevatel p\u00f5hjustel ja paljusid juhuslikke lugemisi ketast.<\/li>\n<li>V\u00e4lise tehingu puhul v\u00e4hendame ummikute riski, kasutades Read Uncommitted isolatsiooni taset.<\/li>\n<li>Teostame ainult l\u00fchikesi tehinguid (keskmiselt alla 100 ms).<\/li>\n<li>Ei kasuta mitmerealisi UPDATE ja DELETE, kuna need p\u00f5hjustavad palju ummikuid \u2014 uuendame ainult \u00fchte kirjet.<\/li>\n<li>K\u00fcsimused teostame alati ainult indeksite kaudu - k\u00fcsimus, mille plaan n\u00e4eb ette t\u00e4ieliku tabeli vaatamist, t\u00e4hendab meie jaoks andmebaasi \u00fclekoormust ja selle riket.<\/li>\n<\/ul>\n<p>\nNeed sammud on v\u00f5imaldanud SQL-serveritest peaaegu maksimumv\u00f5imsust v\u00e4lja pigistada. Kuid probleeme tuli \u00fcha rohkem ja rohkem. Vaatame neid l\u00e4hemalt.<\/p>\n<h2>SQL-i probleemid<\/h2>\n<p><\/p>\n<ul>\n<li>Kuna kasutasime isekirjutatud \u0161ardimist, viidi uute \u0161ardide lisamine manuaalselt l\u00e4bi administraatorite poolt. Kogu selle aja v\u00e4ltel ei teeninud skaleeritavad andmete koopiad p\u00e4ringuid. <\/li>\n<li>Kuna andmete arv tabelis suureneb, v\u00e4heneb lisamise ja muutmise kiirus, olemasoleva tabeli indeksite lisamisel kiirus langeb kordades, indeksite loomine ja uuesti loomine toimub seiskumisega.<\/li>\n<li>Toodangu v\u00e4ikese arvu Windowsi SQL Serverite olemasolu raskendab infrastruktuuri haldamist<\/li>\n<\/ul>\n<p>\nKuid k\u00f5ige suurem probleem on \u2014 <\/p>\n<h2>Talitluskatkestustunne<\/h2>\n<p>\nKlassikalise SQL-serveri talitlush\u00e4ired on halvad. Oletame, et teil on ainult \u00fcks andmebaasi server ja see eba\u00f5nnestub \u00fcks kord iga kolme aasta j\u00e4rel. Sel ajal ei t\u00f6\u00f6ta veebisait 20 minutit, mis on aktsepteeritav. Kui teil on 64 serverit, ei t\u00f6\u00f6ta veebisait juba kord iga kolme n\u00e4dala j\u00e4rel. Ja kui teil on 200 serverit, ei t\u00f6\u00f6ta veebisait iga n\u00e4dal. See on probleem. <\/p>\n<p>Mida saab teha SQL-serveri talitlush\u00e4irete t\u00f5statamiseks? Wikipedia soovitab meil luua <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/High-availability_cluster\">k\u00f5rge k\u00e4ttesaadavuse klaster<\/a><\/noindex>: kus igasuguse komponendi t\u00f5rke korral on olemas duplikaat.<\/p>\n<p>See n\u00f5uab kallite seadmete parki: ulatuslikud duplikaadid, kiudoptiline kaabeldus, jagatud salvestus ja ka varu sissel\u00fclitamine ei toimi usaldusv\u00e4\u00e4rselt: umbes 10% sissel\u00fclitamistest l\u00f5ppeb varu s\u00f5lme rikke t\u00f5ttu, mis j\u00e4rgneb p\u00f5hikliendile. <\/p>\n<p>Kuid sellise k\u00f5rge k\u00e4ttesaadavusega klastrite peamine puudus on nullk\u00e4ttesaadavus andmekeskuse t\u00f5rke korral, kus see asub. \"Odnoklassniki\" omab nelja andmekeskust ning me peame tagama, et see t\u00f6\u00f6tab t\u00e4ieliku rikke korral \u00fches neist.<\/p>\n<p>Selle probleemi lahendamiseks v\u00f5iksime kasutada <noindex><a rel=\"nofollow\" href=\"https:\/\/technet.microsoft.com\/en-us\/library\/ms151196.aspx\">Multi-Master<\/a><\/noindex> replikatsiooni, mis on integreeritud SQL Serverisse. See lahendus on m\u00e4rkimisv\u00e4\u00e4rselt kallim tarkvara maksumuse t\u00f5ttu ja kannatab h\u00e4sti tuntud replikatsiooniga seotud probleemide all \u2014 ettearvamatud tehingu viivitused s\u00fcnkroonses replikatsioonis ning viivitused replikatsioonide rakendamisel (ja seega ka kadunud muudatused) as\u00fcnkroonse puhul. Eeldatav <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/relational-databases\/replication\/transactional\/peer-to-peer-conflict-detection-in-peer-to-peer-replication\">k\u00e4sitsi konfliktide lahendamine<\/a><\/noindex> teeb selle valiku meie jaoks t\u00e4ielikult kasutamatuks.<\/p>\n<p>K\u00f5ik need probleemid n\u00f5udsid radikaalset lahendust ja me alustasime nende \u00fcksikasjalikku anal\u00fc\u00fcsi. Siin peame tutvuma sellega, mida SQL Server p\u00f5him\u00f5tteliselt teeb \u2014 tehingud.<\/p>\n<h2>Lihtne tehing<\/h2>\n<p>\nVaatame k\u00f5ige lihtsamat tehingut, vaatenurgast rakenduslikku SQL-programmeerijat: foto lisamine albumisse. Albumid ja fotod on salvestatud erinevatesse tabelitesse. Albumil on avalike fotode loend. Siis jaguneb selline tehing j\u00e4rgnevateks sammudeks: <\/p>\n<ol>\n<li>Lukustame albumi selle v\u00f5tme j\u00e4rgi.<\/li>\n<li>Loome kirje fotode tabelis. <\/li>\n<li>Kui fotol on avalik staatuse, siis suurendame albumis avalike fotode loendit, uuendame kirjet ja kinnitame tehingu.<\/li>\n<\/ol>\n<p>\nV\u00f5i pseudokoodina:<\/p>\n<pre><code>TX.start(\"Albums\", id);\nAlbum album = albums.lock(id);\nPhoto photo = photos.create(\u2026);\n\nif (photo.status == PUBLIC ) {\n    album.incPublicPhotosCount();\n}\nalbum.update();\n\nTX.commit();<\/code><\/pre>\n<p>\nN\u00e4eme, et k\u00f5ige levinum \u00e4ritehingu stsenaarium on andmete lugemine andmebaasist rakendusserveri m\u00e4llu, millegi muutmine ja uute v\u00e4\u00e4rtuste salvestamine tagasi andmebaasi. Tavaliselt v\u00e4rskendame sellises tehingus mitu \u00fcksust, mitu tabelit. <\/p>\n<p>Tehingu k\u00e4igus v\u00f5ib tekkida konkurentsiaalne muutmine sama andmebaasi andmete osas teises s\u00fcsteemis. N\u00e4iteks v\u00f5ib antispam otsustada, et kasutaja on kahtlane ja seet\u00f5ttu ei tohi k\u00f5ik kasutaja fotod enam avalikud olla, need tuleb saata modereerimisele, mis t\u00e4hendab, et photo.status tuleb muuta m\u00f5neks muuks v\u00e4\u00e4rtuseks ja vastavad loendurid tuleb tagasi keerata. Ilmselgelt, kui see operatsioon toimub ilma atomaarse rakendamise ja konkurentide muudatuste isoleerimise garantiideta, nagu <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/ACID\">ACID<\/a><\/noindex>, ei ole tulemus see, mis on vajalik - kas fotode loendur n\u00e4itab vale v\u00e4\u00e4rtust v\u00f5i ei saadeta k\u00f5ik fotod modereerimisele. <\/p>\n<p>Sarnast koodi, mis manipuleerib erinevate \u00e4rielementidega sama tehingu raames, on kogu Odnoklassniki eksisteerimise ajal kirjutatud v\u00e4ga palju. Kogemuse p\u00f5hjal NoSQL-i migreerimisel <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Eventual_consistency\">Eventual Consistency<\/a><\/noindex> teame, et suurimad raskused (ja ajakulu) tekivad vajadusest arendada koodi, mis tagab andmete j\u00e4rjepidevuse. Seet\u00f5ttu pidasime uue andmebaasi peamiseks n\u00f5udeks ACID-tehingute reaalset tagamist rakendusloogika jaoks. <\/p>\n<p>Muud, mitte v\u00e4hem t\u00e4htsad n\u00f5uded olid:<\/p>\n<ul>\n<li>Andmekeskuse t\u00f5rke korral peavad nii lugemine kui kirjutamine uude andmebaasi olema v\u00f5imalikud.<\/li>\n<li>Praeguse arenduskiirus j\u00e4\u00e4tmine. See t\u00e4hendab, et uue andmebaasiga t\u00f6\u00f6tades peaks koodihulk olema ligikaudu sama, ei tohi tekkida vajadust koguda andmebaasi, arendada konfliktide lahendamise algoritme, s\u00e4ilitada teise astme indekseid jne. <\/li>\n<li>Uue andmebaasi t\u00f6\u00f6kiirus peab olema piisavalt k\u00f5rge nii andmete lugemisel kui tehingute t\u00f6\u00f6tlemisel, mis t\u00f5husalt t\u00e4hendab, et akadeemiliselt rangeid, universaalseid, kuid aeglaseid lahendusi, nagu n\u00e4iteks <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Two-phase_commit_protocol\">kahefsaalset kinnitamist<\/a><\/noindex>.<\/li>\n<li>Automaatne skaleerimine reaalajas. <\/li>\n<li>Tavap\u00e4raste odavate serverite kasutamine ilma eksootiliste seadmete ostmise vajaduseta. <\/li>\n<li>Andmehoidla arendamise v\u00f5imalus ettev\u00f5tte arendajate poolt. Teisis\u00f5nu, eelistasime oma v\u00f5i avatud l\u00e4htekoodiga lahendusi, eelistatult Java platvormil.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Lahendused, lahendused<\/h2>\n<p>\nAnal\u00fc\u00fcsides v\u00f5imalikke lahendusi, j\u00f5udsime kahe arhitektuuri valiku juurde:<\/p>\n<p>Esimene \u2014 v\u00f5tta mistahes SQL-server ja rakendada vajalikud vigadetaluvus, skaleerimise mehhanism, vigadetaluv klaster, konfliktide lahendamine ning jaotatud, usaldusv\u00e4\u00e4rsed ja kiired ACID-tehingud. Hinnasime seda valikut kui pigem keerulist ja aegan\u00f5udvat.<\/p>\n<p>Teine variant \u2014 kasutada valmis NoSQL-andehoidlat, milles on rakendatud skaleerimine, vigadetaluv klaster ja konfliktide lahendamine ja rakendada tehingud ning SQL ise. Esmapilgul tundub isegi SQL-i rakendamine, r\u00e4\u00e4kimata ACID-tehingutest, aastaid kestev \u00fclesanne. Kuid hiljem m\u00f5istsime, et nende SQL-i v\u00f5imaluste kogum, mida me praktikas kasutame, on kaugel ANSI SQL-ist nii kaugel kui <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Apache_Cassandra#Cassandra_Query_Language\">Cassandra CQL<\/a><\/noindex> on ANSI SQL-ist. L\u00e4hemalt uurides CQL-i, j\u00f5udsime j\u00e4reldusele, et see on piisavalt l\u00e4hedal sellele, mida me vajame.<\/p>\n<h2>Cassandra ja CQL<\/h2>\n<p>\nNii et, mis on Cassandra huvitav, millised v\u00f5imalused tal on?<\/p>\n<p>Esiteks saab siin luua tabeleid, mis toetavad erinevaid andmet\u00fc\u00fcpe, v\u00f5ib teha SELECT v\u00f5i UPDATE p\u00e4ringuid primaarv\u00f5tme j\u00e4rgi.<\/p>\n<pre><code>CREATE TABLE photos (id bigint KEY, owner bigint,\u2026);\nSELECT * FROM photos WHERE id=?;\nUPDATE photos SET \u2026 WHERE id=?;<\/code><\/pre>\n<p>\nReplikate andmete j\u00e4rjepidevuse tagamiseks kasutab Cassandra <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Quorum_(distributed_computing)\">kvoorumi l\u00e4henemist<\/a><\/noindex>K\u00f5ige lihtsamas juhus t\u00e4hendab see, et kolme \u00fche ja sama rea koopiat, mis asuvad klastris erinevates noodes, peetakse salvestamise operatsiooni edukaks, kui enamus nodes (st kaks kolmest) on kinnitanud, et see operatsioon \u00f5nnestus. Rida andmeid loetakse koosk\u00f5lastatuks, kui lugemise ajal on suur enamus noode k\u00fcsitud ja need on oma kinnitused andnud. Nii tagatakse kolme koopia olemasolul andmete t\u00e4ielik ja kohene koosk\u00f5lastamine \u00fche node'i rikke korral. See l\u00e4henemine lubas meil rakendada veelgi usaldusv\u00e4\u00e4rsemat skeemi: alati saata p\u00e4ringud k\u00f5ikidele kolmele koopiale, oodates vastust kahest kiireimast. H\u00e4iritud kolmanda koopia vastus j\u00e4etakse sellisel juhul t\u00e4helepanuta. Probleeme v\u00f5ib tekkida aeglaselt vastavaks muutuvast node'ist - n\u00e4iteks viivitustest, JVM-i pr\u00fcgikoristusest, Linuxi kerneli otsesest m\u00e4lukoristusest, riistvara riketest v\u00f5i v\u00f5rgu katkemisest. Kuid see ei m\u00f5juta kliendi operatsioone ega andmeid.<\/p>\n<p>L\u00e4henemist, kus p\u00f6\u00f6rdume kolme node'i poole ja saame vastuse kahest, nimetatakse <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Speculative_execution\">spekulatsiooniks<\/a><\/noindex>: p\u00e4ring \u00fclearustele koopiatele saadetakse enne, kui need \"maha kukuvad\". <\/p>\n<p>Cassandra \u00fcheks teiste eelisteks on Batchlog - mehhanism, mis garanteerib kas paketi t\u00e4ieliku rakendamise v\u00f5i t\u00e4ieliku rakendamata j\u00e4tmise. See v\u00f5imaldab meil lahendada A ACID-is - atomuaarsuse pakend.<\/p>\n<p>\u0421\u0430\u043c\u043e\u0435 \u0431\u043b\u0438\u0437\u043a\u043e\u0435 \u043a \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c \u0432 Cassandra \u2014 \u044d\u0442\u043e \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0435 &#171;<noindex><a rel=\"nofollow\" href=\"https:\/\/docs.datastax.com\/en\/cql\/3.3\/cql\/cql_using\/useInsertLWT.html\">kergekaalulised tehingud<\/a><\/noindex>&#171;. \u041d\u043e \u043e\u0442 \u00ab\u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0445\u00bb ACID-\u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439 \u043e\u043d\u0438 \u0434\u0430\u043b\u0435\u043a\u0438: \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Compare-and-swap\">CAS<\/a><\/noindex> ainult \u00fche kirje andmetega, kasutades raskealuslike Paxose protokolli konsensust. Seet\u00f5ttu ei ole nende tehingute kiirus suur. <\/p>\n<h2>Mida me Cassandra'st puudu tundsime<\/h2>\n<p>\nNii olid meil plaanis rakendada Cassandra's t\u00f5elisi ACID-tehinguid. Mille abil v\u00f5iksime h\u00f5lpsasti saavutada kaks muud mugavat omadust traditsioonilistes andmebaasihalduss\u00fcsteemides: j\u00e4rjepidevad kiired indeksid, mis v\u00f5imaldaksid meil teha andmevalimisi mitte ainult esmase v\u00f5tme ja tavalise monotone autonoomse ID generaatori p\u00f5hjal.<\/p>\n<h4>C*One<\/h4>\n<p>\nNii s\u00fcndis uus andmebaasis\u00fcsteem <b>C*One<\/b>, mis koosneb kolmest t\u00fc\u00fcpi serverinode'ist:<\/p>\n<ul>\n<li>Salvestused - (peaaegu) standardsed Cassandra serverid, mis vastutavad andmete s\u00e4ilitamise eest kohalikest k\u00f5vaketastest. Koormuse ja andmemahtu suurenedes on nende arvu lihtne suurendada k\u00fcmnetest ja sadadest.<\/li>\n<li>Tehingute koordineerimine \u2013 tagab tehingute t\u00e4itmise. <\/li>\n<li>Kliendid \u2013 rakenduste serverid, mis viivad ellu \u00e4riprotsesse ja k\u00e4ivitavad tehingud. Selliseid kliente v\u00f5ib olla tuhandeid.<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"NewSQL = NoSQL+ACID\" src=\"\/wp-content\/uploads\/2019\/09\/f3809d89404ae596c62b642dbdb9e431.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nK\u00f5ik serverid, olenemata t\u00fc\u00fcbist, kuuluvad \u00fchisesse klastrisse, kasutavad omavaheliseks suhtlemiseks sisemist s\u00f5numite protokolli Cassandra ja <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Gossip_protocol\">gossip<\/a><\/noindex> klastri teabe vahetamiseks. Heartbeat'i abil saavad serverid teineteise rikkeid teada, s\u00e4ilitavad \u00fchtse andmeskeemi \u2013 tabelid, nende struktuur ja replikatsioon; partitsioneerimise skeem, klastrite topoloogia jne.<\/p>\n<h4>Kliendid<\/h4>\n<p>\n<img decoding=\"async\" alt=\"NewSQL = NoSQL+ACID\" src=\"\/wp-content\/uploads\/2019\/09\/80f83358f215cf59db3b657ba1083420.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nStandardsete draiverite asemel kasutatakse Fat Client re\u017eiimi. Selline s\u00f5lm ei salvesta andmeid, kuid v\u00f5ib toimida p\u00e4ringute t\u00e4itmise koordinaatorina. See t\u00e4hendab, et klient t\u00e4idab ise oma p\u00e4ringute koordineerimise funktsiooni: k\u00fcsib salvestuste koopiaid ja lahendab konflikte. See ei ole mitte ainult usaldusv\u00e4\u00e4rsem ja kiirem kui standardne draiver, mis n\u00f5uab suhtlemist kaugkoordinatsiooniga, vaid v\u00f5imaldab ka p\u00e4ringute edastamise haldamist. Avatud tehingu korral suunatakse p\u00e4ringud salvestusse. Kui klient on tehingu avanud, suunatakse k\u00f5ik tehingu raames tehtud p\u00e4ringud tehingute koordinaatorisse.<br \/>\n<img decoding=\"async\" alt=\"NewSQL = NoSQL+ACID\" src=\"\/wp-content\/uploads\/2019\/09\/709bf227eeb8f71abeff703a72780efd.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h2>Tehingute koordinaator C*One<\/h2>\n<p>\nKoordinaator \u2013 see, mille me C*One jaoks nullist v\u00e4lja t\u00f6\u00f6tasime. Selle \u00fclesanne on tehingute, lukustuste ja tehingute rakendamise j\u00e4rjekorra haldamine.<\/p>\n<p>Iga teenindatava tehingu jaoks genereerib koordinaator ajatempli: iga j\u00e4rgneva aeg on suurem kui eelmise tehingu oma. Kuna Cassandras p\u00f5hineb konfliktide lahendamise s\u00fcsteem ajatemplitel (kahest konflikti allikast loetakse kehtivamaks see, millel on hilisem ajatempli v\u00e4\u00e4rtus), lahendatakse konflikt alati j\u00e4rgneva tehingu kasuks. Nii oleme me realiseerinud <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A7%D0%B0%D1%81%D1%8B_%D0%9B%D1%8D%D0%BC%D0%BF%D0%BE%D1%80%D1%82%D0%B0\">Lamporti kellad<\/a><\/noindex> \u2013 odav viis konfliktide lahendamiseks jaotatud s\u00fcsteemis.<\/p>\n<h2>Lukustused<\/h2>\n<p>\nIsolatsiooni tagamiseks otsustasime kasutada k\u00f5ige lihtsamat meetodit \u2013 pessimistlikke lukustusi kirje primaarv\u00f5tme j\u00e4rgi. Teisis\u00f5nu, tehingu raames tuleb kirje esmalt lukustada, seej\u00e4rel lugeda, muuta ja salvestada. Ainult p\u00e4rast edukat kinnitamist v\u00f5ib kirje lukust vabastada, et konkurentsiv\u00f5imelised tehingud saaksid seda kasutada.<\/p>\n<p>Sellise lukustuse rakendamine on lihtne mittejaotatud keskkonnas. Jaotatud s\u00fcsteemis on kaks peamist teed: kas rakendada jaotatud lukustust klastris v\u00f5i jaotada tehingud nii, et tehingud, mis h\u00f5lmavad \u00fchte kirjet, teenindab alati sama koordinaator.<\/p>\n<p>Kuna meie juhul on andmed juba jaotatud kohalike tehingute gruppides SQL-is, otsustati siduda iga kohaliku tehingu grupiga koordinaatorid: \u00fcks koordinaator teostab k\u00f5ik tehingud, mille token on 0-9, teine - 10-19, ja nii edasi. Tulemuseks on, et iga koordinaatori eksemplar muutub tehingute grupi valitsejaks. <\/p>\n<p>Siis saavad lukustused olla rakendatud nagu tavaline HashMap koordinaatori m\u00e4lus.<\/p>\n<h2>Koordinaatorite rikke<\/h2>\n<p>\nKuna \u00fcks koordinaator teenindab eriliselt tehingute gruppi, on v\u00e4ga oluline kiiresti kindlaks teha tema rike, et tehingu uuesti t\u00e4itmine mahtuks ajavahemikku. Selleks, et see oleks kiire ja usaldusv\u00e4\u00e4rne, rakendasime t\u00e4ielikult \u00fchendatud kvoorumi heartbeat protokolli:<\/p>\n<p>Iga andmekeskuse kohta paikneb v\u00e4hemalt kaks koordinaatori s\u00f5lme. Aeg-ajalt saadab iga koordinaator teistele koordinaatoritele heartbeat-s\u00f5numi ja teavitab neid oma toimimisest, samuti sellest, milliseid heartbeat-s\u00f5numeid ta viimati teistelt koordinaatoritelt klastris sai. <\/p>\n<p><img decoding=\"async\" alt=\"NewSQL = NoSQL+ACID\" src=\"\/wp-content\/uploads\/2019\/09\/5c337e53815cad0a2071b160d98d42fa.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSaades sarnast teavet teistelt oma heartbeat-s\u00f5numites, otsustab iga koordinaator, millised klastri s\u00f5lmed t\u00f6\u00f6tavad ja millised mitte, j\u00e4rgides kvoorumi p\u00f5him\u00f5tet: kui s\u00f5lm X sai enamiku klastri s\u00f5lmedelt teavet, et s\u00f5lm Y on s\u00f5numid normaalselt saanud, siis Y t\u00f6\u00f6tab. Ja vastupidi, niipea, kui enamus teatab s\u00f5numite kadumisest s\u00f5lmelt Y, siis Y on rikutud. Huvitav on see, et kui kvoorum teatab s\u00f5lmele X, et ta ei saa temalt enam s\u00f5numeid, arvab see iseend, et on rikutud.<\/p>\n<p>Heartbeat-\u00f5nnes\u00f5numid saadetakse suure sagedusega, umbes 20 korda sekundis, 50 ms intervalliga. Java-s on raske tagada rakenduse vastust 50 ms jooksul, kuna pr\u00fcgikorjaja tekitab v\u00f5rdse pikkusega pause. \u00d5nnestus saavutada selline vastus G1 pr\u00fcgikorjajaga, mis v\u00f5imaldab m\u00e4\u00e4rata GC peatuste kestuse eesm\u00e4rgi. Siiski, harva, v\u00f5ivad pr\u00fcgikorjaja pausid \u00fcletada 50 ms, mis v\u00f5ib viia vale riketeavitamiseni. Selle v\u00e4ltimiseks ei teata koordinaator koheselt kaugnoodi t\u00f5rke kohta, kui esimene heartbeat-s\u00f5num l\u00e4heb kaduma, vaid ainult siis, kui mitu j\u00e4rjestikust on kadunud. N nii \u00f5nnestus saavutada koordinaatori noodi rikete avastamine 200 ms jooksul. <\/p>\n<p>Kuid v\u00e4he on lihtsalt aru saada, milline nool on lakanud toimimast. Peame midagi ette v\u00f5tma. <\/p>\n<h2>Varustamine<\/h2>\n<p>\nKlassikaline skeem eeldab, et juhendi rikke korral k\u00e4ivitame uue valimise \u00fchega<noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_Raft\"> moes<\/a><\/noindex> <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9F%D0%B0%D0%BA%D1%81%D0%BE%D1%81\">\u00fcldiselt<\/a><\/noindex> algoritmidest. Sellistel algoritmidel on aga h\u00e4sti teada probleemid konvergentsiga ajas ja valimiste protsessi kestuse osas. Kuigi nende lisaviivitustega oleme suutnud v\u00e4ltida, kasutades koordinaatorite asendamise skeemi t\u00e4ielikus \u00fchenduses olevas v\u00f5rgus:<\/p>\n<p><img decoding=\"async\" alt=\"NewSQL = NoSQL+ACID\" src=\"\/wp-content\/uploads\/2019\/09\/5e2db258fa2200026390a73a414dfe81.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOletame, et soovime teostada tehingut r\u00fchmas 50. M\u00e4\u00e4rame eelnevalt asendamise skeemi, st millised noodid viivad r\u00fchmas 50 tehingud ellu, juhul kui peamine koordinaator peaks eba\u00f5nnestuma. Meie eesm\u00e4rk on s\u00e4ilitada s\u00fcsteemi t\u00f6\u00f6kindlus andmekeskuse t\u00f5rke korral. M\u00e4\u00e4rame, et esmakordne varu on nool teisest andmekeskusest, ja teiseks varuks \u2014 nool kolmandast. See skeem valitakse \u00fcks kord ja ei muutu, kuni klastrite topoloogia ei muutu, st kuni ei liitu uusi noode (mis juhtub v\u00e4ga harva). Uue aktiivse juhendi valimise j\u00e4rjestus vanade t\u00f5rke korral on alati j\u00e4rgmine: aktiivseks juhiks saab esimene varu ning kui ka see enam ei toimi \u2014 siis teine varu. <\/p>\n<p>See skeem on usaldusv\u00e4\u00e4rsem kui universaalne algoritm, kuna uue juhendi aktiveerimiseks piisab vana t\u00f5rke tuvastamisest.<\/p>\n<p>Kuid kuidas saavad kliendid aru, kes meistritest hetkel t\u00f6\u00f6tab? 50 ms jooksul ei ole v\u00f5imalik teavet saata tuhandetele klientidele. V\u00f5ib juhtuda, et klient saadab p\u00e4ringu tehingu avamiseks, teadmata, et see meister ei t\u00f6\u00f6ta enam, ja p\u00e4ring l\u00fckatakse ajakavale. Selle v\u00e4ltimiseks saadavad kliendid spekulatiivselt p\u00e4ringu tehingu avamiseks kohe grupi meistrile ja tema kahe reservmeistrile, kuid vastab sellele p\u00e4ringule ainult see, kes on hetkel aktiivne meister. Kogu hilisem suhtlus tehingu raames toimub ainult aktiivse meistriga.<\/p>\n<p>Reservmeistrid, kes saavad p\u00e4ringud mitte enda tehingute kohta, paigutavad need s\u00fcndimata tehingute j\u00e4rjekorda, kus nad hoiustatakse m\u00f5nda aega. Kui aktiivne meister sureb, siis uus meister t\u00f6\u00f6tleb p\u00e4ringud tehingute avamiseks oma j\u00e4rjekorrast ja vastab kliendile. Kui klient on juba suutnud avada tehingu vana meistriga, siis teine vastus j\u00e4etakse t\u00e4helepanuta (ja ilmset ei saa selline tehing l\u00f5pule viidud ning klient peab seda kordama).<\/p>\n<h2>Kuidas tehing t\u00f6\u00f6tab<\/h2>\n<p>\nOletame, et klient saatis koordinaatorile p\u00e4ringu tehingu avamiseks sellise entiteedi jaoks, millel on selline p\u00f5hiv\u00f5ti. Koordinaator blokeerib selle entiteedi ja paigutab selle m\u00e4lus blokeerimislauda. Vajadusel loeb koordinaator selle entiteedi salvestusest ja salvestab saadud andmed tehingu olekusse koordinaatori m\u00e4llu.<\/p>\n<p><img decoding=\"async\" alt=\"NewSQL = NoSQL+ACID\" src=\"\/wp-content\/uploads\/2019\/09\/246b4a5c68a4cc886b87af784c16b9dc.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKui klient soovib tehingus andmeid muuta, saadab ta koordinaatorile p\u00e4ringu entiteedi muutmiseks, mille puhul koordinaator paigutab uued andmed tehingute olekute tabelisse m\u00e4llu. Sellega on kirjutamine l\u00f5petatud \u2014 salvestusse kirjutamine ei toimu.<\/p>\n<p><img decoding=\"async\" alt=\"NewSQL = NoSQL+ACID\" src=\"\/wp-content\/uploads\/2019\/09\/4400a91af30eb71134978ff27474f745.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKui klient k\u00fcsib aktiivse tehingu raames enda muudetud andmeid, k\u00e4itub koordinaator j\u00e4rgmiselt: <\/p>\n<ul>\n<li>kui ID on tehingus juba olemas, siis andmed v\u00f5etakse m\u00e4lust; <\/li>\n<li>kui ID m\u00e4lus puudub, siis loetakse puuduvad andmed s\u00f5lme salvestustest, \u00fchendatakse need juba olemasolevate andmetega m\u00e4lus ning tulemus antakse kliendile. <\/li>\n<\/ul>\n<p>\nNii saab klient lugeda enda muudatusi, kuid teised kliendid neid muudatusi ei n\u00e4e, sest need on talletatud ainult koordinaatori m\u00e4lus, s\u00f5lmedes Cassandra\u2019s neid veel ei ole.<\/p>\n<p><img decoding=\"async\" alt=\"NewSQL = NoSQL+ACID\" src=\"\/wp-content\/uploads\/2019\/09\/c93fd7e8393f431a976f1f56b95e227c.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKui klient saadab commit'i, salvestab koordinaator teenuse m\u00e4lus olnud oleku logged batch'i, ja see juba logged batch'ina saadetakse Cassandra ladustamisse. Ladustamine teeb k\u00f5ik vajaliku, et see pakett oleks aatomaarne (t\u00e4ielikult) rakendatud, ja tagastab vastuse koordinaatorile, kes vabastab lukud ja kinnitab tehingu edukuse kliendile.<\/p>\n<p><img decoding=\"async\" alt=\"NewSQL = NoSQL+ACID\" src=\"\/wp-content\/uploads\/2019\/09\/ab20487ba53ed88e2f560a2249b5d6f9.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJa juhul, kui tuleb tagasiv\u00f5tt, piisab koordinaatorist, et lihtsalt vabastada m\u00e4lu, mis sisaldab tehingu olekut.<\/p>\n<p>\u00dclaltoodud t\u00e4iendustega oleme rakendanud ACID p\u00f5him\u00f5tteid:<\/p>\n<ul>\n<li><b>Aatomaarusus<\/b>. See tagab, et \u00fckski tehing ei salvestata s\u00fcsteemi osaliselt, kas k\u00f5ik selle alamoperatsioonid t\u00e4idetakse v\u00f5i ei t\u00e4ideta \u00fchtegi. Meie puhul s\u00e4ilitatakse see p\u00f5him\u00f5te logged batch'i kaudu Casandsas.<\/li>\n<li><b>J\u00e4rjepidevus<\/b>. Iga edukas tehing fikseerib m\u00e4\u00e4ratletud tulemused. Kui p\u00e4rast tehingu avamist ja osa operatsioonide t\u00e4itmist leitakse, et tulemus on mittesobiv, tehakse tagasiv\u00f5tt.<\/li>\n<li><b>Isolatsioon<\/b>. Tehingu t\u00e4itmise ajal ei tohiks parallel-tehingud m\u00f5jutada selle tulemust. Konkurentsiv\u00f5imelised tehingud on isoleeritud koordinaatori pessimistlike lukustustega. V\u00e4listehingute lugemise korral j\u00e4rgime isoleerituse p\u00f5him\u00f5tet Read Committed tasandil.<\/li>\n<li><b>P\u00fcsivus<\/b>. \u00dcksk\u00f5ik millised probleemid alumistel tasanditel \u2014 s\u00fcsteemi voolukatkestus, seadmete t\u00f5rge \u2014, edukalt l\u00f5petatud tehingu muudatused peavad j\u00e4\u00e4ma alles p\u00e4rast s\u00fcsteemi taasfunktsioneerimist. <\/li>\n<\/ul>\n<p><\/p>\n<h2>Lugemine indeksite kaudu<\/h2>\n<p>\nV\u00f5tame lihtsa tabeli: <\/p>\n<pre><code>CREATE TABLE photos (\nid bigint primary key,\nowner bigint,\nmodified timestamp,\n\u2026)<\/code><\/pre>\n<p>\nSellest tabelist on ID (esmane v\u00f5ti), omanik ja muutmise kuup\u00e4ev. Peame tegema v\u00e4ga lihtsa p\u00e4ringu \u2014 valima andmed omaniku j\u00e4rgi, kelle muudatuse kuup\u00e4ev on \"viimase 24 tunni\" jooksul. <\/p>\n<pre><code>SELECT *\nWHERE owner=?\nAND modified&gt;?<\/code><\/pre>\n<p>\nSelle taolise p\u00e4ringu kiireks t\u00f6\u00f6tlemiseks peab klassikalises SQL andmebaasis ehitama indeksid veergudele (owner, modified). Me saame seda teha piisavalt lihtsalt, kuna n\u00fc\u00fcd on meil ACID garantii!<\/p>\n<h2>Indeksid C*One<\/h2>\n<p>\nOlemas on fotosid sisaldav algne tabel, mille kande ID on esmane v\u00f5ti. <\/p>\n<p><img decoding=\"async\" alt=\"NewSQL = NoSQL+ACID\" src=\"\/wp-content\/uploads\/2019\/09\/9f5d7c5f66882666a7ae8219f710beeb.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIndeksi jaoks loob C*One uue tabeli, mis on algse koopia. V\u00f5ti on sama, mis indeksile vastav v\u00e4ljend, samal ajal sisaldab see ka algse tabeli esmast v\u00f5tit:<\/p>\n<p><img decoding=\"async\" alt=\"NewSQL = NoSQL+ACID\" src=\"\/wp-content\/uploads\/2019\/09\/ce6df1c8407bca7ddc61fd88141455e6.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nN\u00fc\u00fcd saab p\u00e4ringu \u201eomanik viimase 24 tunni jooksul\u201c \u00fcmber kirjutada valiku kaudu teiselt tabelilt:<\/p>\n<pre><code>SELECT * FROM i1_test\nWHERE owner=?\nAND modified&gt;?<\/code><\/pre>\n<p>\nAlgse tabeli fotosid ja indeksit i1 koosk\u00f5lastatakse automaatselt koordinaatori poolt. Ainu\u00fcksi andmeskeemi alusel genereerib ja salvestab koordinaator muudatuse mitte ainult p\u00f5hiteabesse, vaid ka koopiate muudatused. T\u00e4iendavaid toiminguid indeksitabeliga ei tehta, logisid ei loeta, lukustusi ei kasutata. See t\u00e4hendab, et indeksite lisamine tarbib peaaegu mitte mingeid ressursse ja ei m\u00f5juta oluliselt muudatuste rakendamise kiirus.<\/p>\n<p>ACID-i abil oleme suutnud rakendada indekseid \u201enagu SQL-is\u201c. Need on koosk\u00f5lastatud, skaleeritavad, t\u00f6\u00f6tavad kiiresti, v\u00f5ivad olla koostatud ja sisseehitatud CQL-p\u00e4ringu keelde. Indeksite toetamiseks ei ole vaja rakenduskoodi muuta. K\u00f5ik on lihtne, nagu SQL-is. Ja mis k\u00f5ige t\u00e4htsam, indeksid ei m\u00f5juta algse tehingute tabeli muudatuste t\u00e4itmise kiirus.<\/p>\n<h2>Mis v\u00e4lja tuli<\/h2>\n<p>\nMe arendasime C*One v\u00e4lja kolm aastat tagasi ja k\u00e4ivitasime selle t\u00f6\u00f6stuslikuks kasutuseks. <\/p>\n<p>Mida me l\u00f5puks saime? Hinnake seda meie fotode t\u00f6\u00f6tlemise ja salvestamise alams\u00fcsteemi n\u00e4itel, mis on sotsiaalv\u00f5rgustikus \u00fcks olulisemaid andmete t\u00fc\u00fcpe. R\u00e4\u00e4gime mitte ainult fotode tegelikest kehade, vaid ka erinevatest metaandmetest. Praegu on \u201eOdnoklassnikites\u201c umbes 20 miljardit sellist salvestust, s\u00fcsteem t\u00f6\u00f6tleb 80 tuhat lugemisep\u00e4ringut sekundis ja kuni 8 tuhat ACID-tehingut sekundis, mis on seotud andmete muutmisega. <\/p>\n<p>Kui kasutasime SQL-i replikatsiooni teguriga = 1 (aga RAID 10. puhul), hoiti fotode metaandmed k\u00f5rge k\u00e4ttesaadavusega klastris, mis koosneb 32 masinast Microsoft SQL Serveriga (pluss 11 varukoopiat). Samuti oli eraldatud 10 serverit varukoopiate hoidmiseks. Kokku 50 kulukat masinat. Sel ajal t\u00f6\u00f6tas s\u00fcsteem nominaalsel koormusel, ilma varu.<\/p>\n<p>P\u00e4rast \u00fcleminekut uuele s\u00fcsteemile saime replikatsiooni teguri = 3 \u2014 iga andmekeskuse kohta \u00fcks koopia. S\u00fcsteem koosneb 63 Cassandra salvestusnode'ist ja 6 masinast koordinaatoreid, kokku 69 serverit. Kuid need masinad on oluliselt odavamad, nende koguhind on umbes 30% SQL-i s\u00fcsteemi hinnast. Samal ajal j\u00e4\u00e4b koormus 30% tasemele.<\/p>\n<p>C*One rakendamisega v\u00e4henesid ka viivitused: SQL-i kirjutamise operatsioon kestis umbes 4,5 ms. C*One-s \u2014 umbes 1,6 ms. Tehingu kestus on keskmiselt alla 40 ms, kinnitamine toimub 2 ms jooksul, lugemise ja kirjutamise kestus \u2014 keskmiselt 2 ms. 99. percentiili jaoks \u2014 vaid 3\u20133,1 ms, ajakulu v\u00e4henes 100 korda \u2014 k\u00f5ik t\u00e4nu spekulatsioonide laialdasele kasutamisele. <\/p>\n<p>K\u00e4esolevaks ajaks on suurem osa SQL Serveri s\u00f5lmedest v\u00e4lja v\u00f5etud, uusi tooteid arendatakse ainult C*One kasutades. Oleme kohandanud C*One meie pilve t\u00f6\u00f6ks. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/odnoklassniki\/blog\/346868\/\">one-cloud<\/a><\/noindex>, mis v\u00f5imaldas kiirendada uute klastrite loomist, lihtsustada konfiguratsiooni ja automateerida hooldust. Ilma l\u00e4htekoodita oleks seda palju keerulisem ja k\u00e4t\u0161iaduslikum teha. <\/p>\n<p>K\u00e4esolevalt t\u00f6\u00f6tame teiste meie salvestuss\u00fcsteemide pilve \u00fcleviimise kallal \u2014 kuid see on juba hoopis teine lugu.<br \/>\n<br \/>Allikas: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/odnoklassniki\/blog\/417593\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0414\u043e \u043d\u0435\u0434\u0430\u0432\u043d\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432 \u041e\u0434\u043d\u043e\u043a\u043b\u0430\u0441\u0441\u043d\u0438\u043a\u0430\u0445 \u043e\u043a\u043e\u043b\u043e 50 \u0422\u0411 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0445\u0440\u0430\u043d\u0438\u043b\u043e\u0441\u044c \u0432 SQL Server. \u0414\u043b\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043c\u0430 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u0438 \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439, \u0434\u0430 \u0435\u0449\u0435 \u0438 \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u043a \u043e\u0442\u043a\u0430\u0437\u0443 \u0426\u041e\u0414 \u0434\u043e\u0441\u0442\u0443\u043f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f SQL \u0421\u0423\u0411\u0414, \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e. \u041e\u0431\u044b\u0447\u043d\u043e \u0432 \u0442\u0430\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043e\u0434\u043d\u043e \u0438\u0437 NoSQL-\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449, \u043d\u043e \u043d\u0435 \u0432\u0441\u0451 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0432 NoSQL: \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":28484,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-37956","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0414\u043e \u043d\u0435\u0434\u0430\u0432\u043d\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432 \u041e\u0434\u043d\u043e\u043a\u043b\u0430\u0441\u0441\u043d\u0438\u043a\u0430\u0445 \u043e\u043a\u043e\u043b\u043e 50 \u0422\u0411 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0445.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/newsql-nosql-acid\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"et_EE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47NewSQL = NoSQL+ACID | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0414\u043e \u043d\u0435\u0434\u0430\u0432\u043d\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432 \u041e\u0434\u043d\u043e\u043a\u043b\u0430\u0441\u0441\u043d\u0438\u043a\u0430\u0445 \u043e\u043a\u043e\u043b\u043e 50 \u0422\u0411 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0445.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/newsql-nosql-acid\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:20:47+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:20:47+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47NewSQL = NoSQL+ACID | ProHoster","description":"Hiljuti t\u00f6\u00f6tas Odnoklassnikites umbes 50 TB andmeid.","canonical_url":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/newsql-nosql-acid","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"et_EE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47NewSQL = NoSQL+ACID | ProHoster","og:description":"\u0414\u043e \u043d\u0435\u0434\u0430\u0432\u043d\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432 \u041e\u0434\u043d\u043e\u043a\u043b\u0430\u0441\u0441\u043d\u0438\u043a\u0430\u0445 \u043e\u043a\u043e\u043b\u043e 50 \u0422\u0411 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0445.","og:url":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/newsql-nosql-acid","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:20:47+00:00","article:modified_time":"2019-10-31T19:20:47+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"37956","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-23 19:55:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:17:23","updated":"2026-01-23 19:55:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/37956","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/comments?post=37956"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/37956\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media\/28484"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media?parent=37956"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/categories?post=37956"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/tags?post=37956"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}