HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Ďalšia konferencia HighLoad++ sa bude konať 6. a 7. apríla 2020 v Petrohrade.
Podrobnosti a lístky по ссылке. HighLoad++ Sibír 2019. Hala "Krasnojarsk". 25. júna, 12:00. Tézy a predstavenie.

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Stáva sa, že praktické požiadavky sú v rozpore s teóriou, kde sa neberú do úvahy aspekty dôležité pre komerčný produkt. Táto prednáška predstavuje proces výberu a kombinovania rôznych prístupov k vytváraniu komponentov kauzálnej konzistencie na základe akademického výskumu založeného na požiadavkách komerčného produktu. Poslucháči sa dozvedia o existujúcich teoretických prístupoch k logickým hodinám, sledovaniu závislostí, bezpečnosti systému, synchronizácii hodín a prečo sa spoločnosť MongoDB rozhodla pre určité riešenia.

Michail Tyulenev (ďalej len MT): – Budem hovoriť o kauzálnej konzistencii – toto je funkcia, na ktorej sme pracovali v MongoDB. Pracujem v skupine distribuovaných systémov, robili sme to asi pred dvoma rokmi.

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

V tomto procese som sa musel zoznámiť s množstvom akademického výskumu, pretože táto funkcia bola celkom dobre študovaná. Ukázalo sa, že ani jeden článok nezapadá do toho, čo sa vyžaduje v produkčnej databáze, kvôli veľmi špecifickým požiadavkám, ktoré sú pravdepodobne prítomné v akejkoľvek produkčnej aplikácii.

Porozprávam o tom, ako z neho ako konzumenti akademického Výskumu pripravíme niečo, čo potom môžeme prezentovať našim používateľom ako hotové jedlo, ktoré je pohodlné a bezpečné na používanie.

Príčinná konzistencia. Definujme si pojmy

Na začiatok by som chcel vo všeobecnosti povedať, čo je kauzálna konzistencia. Existujú dve postavy - Leonard a Penny (televízny seriál "The Big Bang Theory"):

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Povedzme, že Penny je v Európe a Leonard jej chce usporiadať večierok s prekvapením. A nenapadá ho nič lepšie, ako ju vyhodiť zo svojho zoznamu priateľov a všetkým svojim priateľom poslať aktualizáciu na feed: „Urobme Penny šťastnou!“ (je v Európe, kým spí, toto všetko nevidí a nevidí, pretože tam nie je). Nakoniec tento príspevok vymaže, vymaže z informačného kanála a obnoví prístup, aby si nič nevšimla a nevznikol žiadny škandál.
To všetko je v poriadku, ale predpokladajme, že systém je distribuovaný a veci sa trochu pokazili. Môže sa napríklad stať, že k obmedzeniu prístupu Penny došlo po zobrazení tohto príspevku, ak udalosti nesúvisia medzi príčinami a následkami. V skutočnosti je to príklad toho, keď sa na vykonávanie obchodnej funkcie (v tomto prípade) vyžaduje kauzálna konzistentnosť.

V skutočnosti ide o celkom netriviálne vlastnosti databázy – podporuje ich len veľmi málo ľudí. Prejdime k modelom.

Modely konzistencie

Čo presne je model konzistencie v databázach? Toto sú niektoré zo záruk, ktoré distribuovaný systém poskytuje o tom, aké údaje môže klient prijímať av akom poradí.

V princípe všetky modely konzistencie vychádzajú z toho, nakoľko je distribuovaný systém podobný systému, ktorý beží napríklad na jednom uzle na notebooku. A takto je systém, ktorý beží na tisícoch geograficky distribuovaných „Nodes“, podobný notebooku, v ktorom sa všetky tieto vlastnosti v princípe vykonávajú automaticky.

Preto sa modely konzistencie aplikujú iba na distribuované systémy. Všetky systémy, ktoré predtým existovali a fungovali v rovnakom vertikálnom škálovaní, nemali takéto problémy. Bola tam jedna vyrovnávacia pamäť a z nej sa vždy čítalo všetko.

Model Strong

V skutočnosti je úplne prvým modelom Strong (alebo línia schopnosti vzostupu, ako sa často nazýva). Toto je konzistentný model, ktorý zabezpečuje, že každá zmena, keď sa potvrdí, že k nej došlo, je viditeľná pre všetkých používateľov systému.

Tým sa vytvorí globálne poradie všetkých udalostí v databáze. Ide o veľmi silnú konzistentnú vlastnosť a vo všeobecnosti je veľmi drahá. Je však veľmi dobre podporovaný. Len je to veľmi drahé a pomalé – len sa to používa málo. Toto sa nazýva schopnosť stúpania.

Existuje ďalšia, silnejšia vlastnosť, ktorá je podporovaná v Spanner - nazývaná Externá konzistencia. Povieme si o tom trochu neskôr.

kauzálny

Ďalším je Causal, presne o tom som hovoril. Medzi Strong a Causal je ešte niekoľko podúrovní, o ktorých nebudem hovoriť, ale všetky sa scvrkávajú na Causal. Toto je dôležitý model, pretože je najsilnejší zo všetkých modelov, najsilnejšia konzistencia v prítomnosti siete alebo oddielov.

Kauzality sú vlastne situácia, v ktorej sú udalosti spojené vzťahom príčiny a následku. Veľmi často sú z pohľadu klienta vnímané ako Read your on rights. Ak klient pozoroval nejaké hodnoty, nemôže vidieť hodnoty, ktoré boli v minulosti. Už začína vidieť predpony. Všetko vychádza z toho istého.
Kauzality ako konzistentný model je čiastočné usporiadanie udalostí na serveri, v ktorom sú udalosti od všetkých klientov pozorované v rovnakom poradí. V tomto prípade Leonard a Penny.

eventuálnej

Tretím modelom je Eventual Consistency. Toto podporujú absolútne všetky distribuované systémy, minimálny model, ktorý vôbec dáva zmysel. Znamená to nasledovné: keď máme nejaké zmeny v údajoch, v určitom bode sa stanú konzistentnými.

V takom momente nič nepovie, inak by sa zmenila na Vonkajšiu konzistentnosť – to by bol úplne iný príbeh. Napriek tomu ide o veľmi obľúbený model, najbežnejší. V predvolenom nastavení všetci používatelia distribuovaných systémov používajú Eventual Consistency.

Chcem uviesť niekoľko porovnávacích príkladov:

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Čo znamenajú tieto šípky?

  • Latencia. Ako sa zvyšuje sila konzistencie, zväčšuje sa zo zrejmých dôvodov: musíte vytvoriť viac záznamov, získať potvrdenie od všetkých hostiteľov a uzlov, ktoré sa zúčastňujú na klastri, že údaje už existujú. Eventual Consistency má teda najrýchlejšiu odpoveď, pretože tam si ju spravidla môžete uložiť aj do pamäte a to bude v zásade stačiť.
  • Dostupnosť. Ak to chápeme ako schopnosť systému reagovať na výpadky siete, oddiely alebo nejaký druh zlyhania, odolnosť voči chybám sa zvyšuje so znižovaním modelu konzistencie, pretože nám stačí, že jeden hostiteľ žije a súčasne čas vytvára nejaké údaje. Eventual Consistency nezaručuje o údajoch vôbec nič – môže to byť čokoľvek.
  • Anomálie. Zároveň sa samozrejme zvyšuje počet anomálií. V Silnej konzistencii by takmer vôbec nemali existovať, ale v Eventual Consistency môžu byť čímkoľvek. Vynára sa otázka: prečo si ľudia vyberajú prípadnú konzistenciu, ak obsahuje anomálie? Odpoveď je, že modely eventuálnej konzistencie sú použiteľné a anomálie existujú napríklad v krátkom časovom období; je možné použiť sprievodcu na čítanie a viac-menej čítanie konzistentných údajov; Často je možné použiť modely silnej konzistencie. V praxi to funguje a často je počet anomálií časovo obmedzený.

CAP veta

Keď vidíte slová konzistencia, dostupnosť – čo vám napadne? Správne – veta CAP! Teraz chcem vyvrátiť mýtus... To nie som ja – to je Martin Kleppmann, ktorý napísal úžasný článok, úžasnú knihu.

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Teorém CAP je princíp formulovaný v roku 2000, že konzistencia, dostupnosť, oddiely: vezmite si ľubovoľné dva a nemôžete si vybrať tri. Bol to istý princíp. Ako vetu to dokázali o niekoľko rokov neskôr Gilbert a Lynch. Potom sa to začalo používať ako mantra – systémy sa začali deliť na CA, CP, AP a pod.

Táto veta bola skutočne dokázaná pre nasledujúce prípady... Po prvé, dostupnosť sa nepovažovala za spojitú hodnotu od nuly do stoviek (0 – systém je „mŕtvy“, 100 – reaguje rýchlo; sme zvyknutí to takto považovať) , ale ako vlastnosť algoritmu, ktorý zaručuje, že pre všetky svoje vykonania vráti dáta.

Nie je tam ani slovo o dobe odozvy! Existuje algoritmus, ktorý vracia dáta po 100 rokoch – úplne úžasný dostupný algoritmus, ktorý je súčasťou vety CAP.
Po druhé: teorém bol dokázaný pre zmeny hodnôt toho istého kľúča, napriek tomu, že tieto zmeny možno meniť. To znamená, že v skutočnosti sa prakticky nepoužívajú, pretože modely sú rôzne Eventual Consistency, Strong Consistency (možno).

Načo to všetko je? Navyše teorém CAP presne v tej podobe, v akej bol dokázaný, je prakticky neaplikovateľný a používa sa len zriedka. V teoretickej forme to všetko akosi obmedzuje. Ukazuje sa určitý princíp, ktorý je intuitívne správny, ale vo všeobecnosti nebol dokázaný.

Kauzálna konzistencia je najsilnejší model

Teraz sa deje, že môžete získať všetky tri veci: Konzistenciu, dostupnosť pomocou oddielov. Najmä kauzálna konzistencia je najsilnejší model konzistencie, ktorý stále funguje v prítomnosti oddielov (prestávok v sieti). Preto je o ňu taký veľký záujem, a preto sme sa jej chopili.

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Po prvé, zjednodušuje prácu vývojárom aplikácií. Najmä prítomnosť veľkej podpory zo strany servera: keď všetky záznamy, ktoré sa vyskytujú v rámci jedného klienta, zaručene dorazia v rovnakom poradí na iného klienta. Po druhé, odolá priečkam.

Vnútorná kuchyňa MongoDB

Spomínajúc, že ​​je obed, presúvame sa do kuchyne. Poviem vám o modeli systému, konkrétne o tom, čo je MongoDB pre tých, ktorí o takejto databáze počujú prvýkrát.

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

MongoDB (ďalej len „MongoDB“) je distribuovaný systém, ktorý podporuje horizontálne škálovanie, teda sharding; a v rámci každého shardu podporuje aj redundanciu dát, teda replikáciu.

Zdieľanie v MongoDB (nie relačná databáza) vykonáva automatické vyvažovanie, to znamená, že každá zbierka dokumentov (alebo „tabuľka“ z hľadiska relačných údajov) je rozdelená na časti a server ich automaticky presúva medzi fragmenty.

Smerovač dotazov, ktorý distribuuje požiadavky pre klienta, je nejaký klient, prostredníctvom ktorého funguje. Už vie, kde a aké údaje sa nachádzajú a všetky požiadavky nasmeruje na správny shard.

Ďalší dôležitý bod: MongoDB je jediný majster. Existuje jeden primárny – môže prijímať záznamy, ktoré podporujú kľúče, ktoré obsahuje. Nemôžete písať multimaster.

Urobili sme vydanie 4.2 - objavili sa tam nové zaujímavé veci. Predovšetkým vložili Lucene - search - teda spustiteľnú javu priamo do Monga a tam bolo možné vykonávať vyhľadávanie cez Lucene, rovnako ako v Elastice.

A vytvorili nový produkt - Charts, je dostupný aj na Atlase (Mongov vlastný Cloud). Majú bezplatnú úroveň - môžete sa s ňou pohrať. Veľmi sa mi páčili Charts – vizualizácia dát, veľmi intuitívne.

Zloženie Príčinná konzistencia

Napočítal som asi 230 článkov, ktoré boli na túto tému publikované – od Leslie Lamperta. Teraz vám z mojej pamäti sprostredkujem niektoré časti týchto materiálov.

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Všetko to začalo článkom Leslieho Lamperta, ktorý bol napísaný v 1970. rokoch. Ako vidíte, nejaký výskum na túto tému stále prebieha. Kauzálna konzistencia teraz zažíva záujem v súvislosti s vývojom distribuovaných systémov.

Obmedzenie

Aké obmedzenia existujú? Toto je vlastne jeden z hlavných bodov, pretože obmedzenia, ktoré produkčný systém ukladá, sú veľmi odlišné od obmedzení, ktoré existujú v akademických článkoch. Často sú dosť umelé.

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

  • Po prvé, „MongoDB“ je jediný majster, ako som už povedal (toto značne zjednodušuje).
  • Domnievame sa, že systém by mal podporovať približne 10 tisíc shardov. Nemôžeme robiť žiadne architektonické rozhodnutia, ktoré túto hodnotu vyslovene obmedzia.
  • Máme cloud, ale predpokladáme, že človek by mal mať stále možnosť, keď si stiahne binárne, spustí to na svojom notebooku a všetko funguje skvele.
  • Predpokladáme niečo, čo Výskum len zriedka predpokladá: externí klienti si môžu robiť, čo chcú. MongoDB je open source. V súlade s tým môžu byť klienti tak inteligentní a nahnevaní - môžu chcieť všetko rozbiť. Predpokladáme, že byzantské Feilors môžu pochádzať.
  • Pre externých klientov, ktorí sú mimo perimetra, existuje dôležité obmedzenie: ak je táto funkcia zakázaná, nemalo by sa pozorovať žiadne zníženie výkonu.
  • Ďalší bod je vo všeobecnosti protiakademický: kompatibilita predchádzajúcich verzií a budúcich verzií. Staré ovládače musia podporovať nové aktualizácie a databáza musí podporovať staré ovládače.

Vo všeobecnosti to všetko ukladá obmedzenia.

Zložky príčinnej konzistencie

Teraz budem hovoriť o niektorých komponentoch. Ak vezmeme do úvahy kauzálnu konzistenciu vo všeobecnosti, môžeme vybrať bloky. Vyberali sme z diel, ktoré patria do určitého bloku: Dependency Tracking, výber hodín, ako sa tieto hodiny dajú navzájom synchronizovať a ako zabezpečíme bezpečnosť – to je hrubý náčrt toho, o čom budem hovoriť:

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Úplné sledovanie závislosti

Prečo je to potrebné? Aby pri replikácii údajov každý záznam, každá zmena údajov obsahovala informácie o tom, od ktorých zmien závisí. Úplne prvá a naivná zmena je, keď každá správa, ktorá obsahuje záznam, obsahuje informácie o predchádzajúcich správach:

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

V tomto príklade je číslo v zložených zátvorkách čísla záznamu. Niekedy sa tieto záznamy s hodnotami prenesú dokonca celé, niekedy sa prenesú niektoré verzie. Podstatou je, že každá zmena obsahuje informácie o predchádzajúcej (toto všetko samozrejme nesie v sebe).

Prečo sme sa rozhodli nepoužiť tento prístup (úplné sledovanie)? Je zrejmé, že tento prístup je nepraktický: akákoľvek zmena sociálnej siete závisí od všetkých predchádzajúcich zmien v tejto sociálnej sieti, povedzme od Facebooku alebo VKontakte pri každej aktualizácii. Napriek tomu existuje veľa výskumov o sledovaní úplnej závislosti – ide o predsociálne siete, v niektorých situáciách to naozaj funguje.

Explicitné sledovanie závislosti

Ďalšia je obmedzenejšia. Počíta sa tu aj s prenosom informácií, ale len s tým, čo je jednoznačne závislé. Čo závisí od čoho, spravidla určuje Aplikácia. Keď sú údaje replikované, dotaz vráti odpovede len vtedy, keď sú predchádzajúce závislosti splnené, to znamená, že sú zobrazené. Toto je podstata fungovania Kauzálnej konzistencie.

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Vidí, že záznam 5 závisí od záznamov 1, 2, 3, 4 - podľa toho čaká, kým klient získa prístup k zmenám vykonaným rozhodnutím o prístupe Penny, keď všetky predchádzajúce zmeny už prešli databázou.

To nám tiež nevyhovuje, pretože informácií je stále príliš veľa a veci sa spomalia. Existuje aj iný prístup...

Hodiny Lamport

Sú veľmi staré. Lamport Clock znamená, že tieto závislosti sú zložené do skalárnej funkcie, ktorá sa nazýva Lamport Clock.

Skalárna funkcia je nejaké abstraktné číslo. Často sa nazýva logický čas. S každou udalosťou sa toto počítadlo zvyšuje. Počítadlo, ktoré je v súčasnosti procesu známe, odošle každú správu. Je jasné, že procesy môžu byť nesynchronizované, môžu mať úplne iné časy. Napriek tomu systém nejakým spôsobom vyvažuje hodiny s takýmito správami. Čo sa stane v tomto prípade?

Rozdelil som ten veľký zlomok na dve časti, aby bolo jasné: Priatelia môžu žiť v jednom uzle, ktorý obsahuje časť zbierky, a Feed môže žiť v inom uzle, ktorý obsahuje časť tejto zbierky. Je jasné, ako môžu vybočiť z radu? Prvý kanál povie: „Replikované“ a potom Priatelia. Ak systém neposkytuje nejakú záruku, že sa Feed nezobrazí, kým nebudú doručené aj závislosti Friends v kolekcii Friends, potom budeme mať presne tú situáciu, ktorú som spomenul.

Vidíte, ako sa logicky zvyšuje čas počítadla na informačnom kanáli:

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Takže hlavná vlastnosť týchto Lamportových hodín a kauzálnej konzistencie (vysvetlená prostredníctvom Lamportových hodín) je toto: ak máme udalosti A a B a udalosť B závisí od udalosti A*, potom z toho vyplýva, že logický čas udalosti A je menší ako Logický čas z udalosti B.

* Niekedy sa tiež hovorí, že A sa stalo pred B, teda A stalo sa pred B - to je určitý vzťah, ktorý čiastočne riadi celý súbor udalostí, ktoré sa vo všeobecnosti stali.

Opak je nesprávny. To je vlastne jedna z hlavných nevýhod Lamport Clock – čiastočná objednávka. Existuje koncept o simultánnych udalostiach, to znamená udalostiach, v ktorých sa ani (A nestalo pred B) ani (A nestalo pred B). Príkladom môže byť Leonardovo paralelné pridanie niekoho iného ako priateľa (dokonca ani nie Leonarda, ale napríklad Sheldona).
Toto je vlastnosť, ktorá sa často používa pri práci s hodinami Lamport: pozerajú sa špecificky na funkciu a z toho vyvodzujú, že možno sú tieto udalosti závislé. Pretože jeden spôsob je pravdivý: ak je Logický čas A menší ako Logický čas B, potom B nemôže nastať pred A; a ak viac, tak možno.

Vektorové hodiny

Logickým vývojom Lamportových hodín sú vektorové hodiny. Líšia sa tým, že každý uzol, ktorý sa tu nachádza, obsahuje vlastné samostatné hodiny a tie sa prenášajú ako vektor.
V tomto prípade vidíte, že nultý index vektora je zodpovedný za Feed a prvý index vektora je za Friends (každý z týchto uzlov). A teraz sa zvýšia: nulový index „Feed“ sa pri písaní zvyšuje – 1, 2, 3:

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Prečo sú Vector Clock lepšie? Pretože vám umožňujú zistiť, ktoré udalosti sú simultánne a kedy sa vyskytujú na rôznych uzloch. To je veľmi dôležité pre systém sharding, akým je MongoDB. Toto sme si však nevybrali, hoci je to úžasná vec a funguje skvele a asi by sa nám aj hodila...

Ak máme 10 tisíc úlomkov, nemôžeme preniesť 10 tisíc komponentov, aj keď to komprimujeme alebo vymyslíme niečo iné - užitočné zaťaženie bude stále niekoľkonásobne menšie ako objem celého tohto vektora. Preto sme so zatínaním srdca a zubov tento prístup opustili a prešli na iný.

Spanner TrueTime. Atómové hodiny

Povedal som, že bude príbeh o Spannerovi. Toto je skvelá vec, priamo z XNUMX. storočia: atómové hodiny, synchronizácia GPS.

Aký je to nápad? „Spanner“ je systém Google, ktorý sa nedávno stal dostupným aj pre ľudí (pridali doň SQL). Každá transakcia tam má nejakú časovú pečiatku. Keďže čas je synchronizovaný*, každej udalosti môže byť priradený špecifický čas - atómové hodiny majú čakaciu dobu, po ktorej zaručene „nastane“ iný čas.

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Jednoduchým zápisom do databázy a čakaním na určitý čas je teda automaticky zaručená serializovateľnosť udalosti. Majú najsilnejší model konzistentnosti, aký si možno v princípe predstaviť – je to Externá konzistentnosť.

* Toto je hlavný problém s hodinami Lampart – v distribuovaných systémoch nikdy nie sú synchrónne. Môžu sa rozchádzať; dokonca aj s NTP stále nefungujú veľmi dobre. "Spanner" má atómové hodiny a synchronizácia, zdá sa, je mikrosekundová.

Prečo sme si nevybrali? Nepredpokladáme, že naši používatelia majú zabudované atómové hodiny. Keď sa objavia, budú zabudované do každého notebooku, bude tam nejaká super cool GPS synchronizácia - potom áno... Ale zatiaľ to najlepšie, čo je možné, je Amazon, Base Stations - pre fanatikov... Tak sme použili iné hodinky .

Hybridné hodiny

To je v skutočnosti to, čo v MongoDB funguje pri zabezpečovaní kauzálnej konzistencie. Ako sú hybridné? Hybrid je skalárna hodnota, ale má dve zložky:

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

  • Prvou je epocha Unixu (koľko sekúnd ubehlo od „začiatku počítačového sveta“).
  • Druhým je nejaký prírastok, tiež 32-bitový unsigned int.

To je vlastne všetko. Existuje tento prístup: časť, ktorá je zodpovedná za čas, je neustále synchronizovaná s hodinami; vždy, keď dôjde k aktualizácii, táto časť sa synchronizuje s hodinami a ukáže sa, že čas je vždy viac-menej správny a prírastok vám umožňuje rozlíšiť medzi udalosťami, ktoré nastali v rovnakom čase.

Prečo je to dôležité pre MongoDB? Pretože vám to umožňuje urobiť nejaký druh záložných reštaurácií v určitom čase, to znamená, že udalosť je indexovaná podľa času. To je dôležité, keď sú potrebné určité udalosti; Pre databázu sú udalosti zmeny v databáze, ktoré sa vyskytli v určitých časových intervaloch.

Najdôležitejší dôvod vám poviem iba vám (prosím, nikomu to nehovorte)! Urobili sme to, pretože takto vyzerajú organizované indexované údaje v MongoDB OpLog. OpLog je dátová štruktúra, ktorá obsahuje úplne všetky zmeny v databáze: najprv idú do OpLogu a potom sa aplikujú na samotný Storage v prípade, že ide o replikovaný dátum alebo zlomok.

Toto bol hlavný dôvod. Napriek tomu existujú aj praktické požiadavky na vývoj databázy, čo znamená, že by mala byť jednoduchá – málo kódu, čo najmenej rozbitých vecí, ktoré je potrebné prepisovať a testovať. Skutočnosť, že naše oplogy boli indexované hybridnými hodinami, veľmi pomohla a umožnila nám urobiť správnu voľbu. Naozaj sa to oplatilo a akosi magicky fungovalo hneď na prvom prototype. Bolo to veľmi cool!

Synchronizácia hodín

Vo vedeckej literatúre je opísaných niekoľko synchronizačných metód. Hovorím o synchronizácii, keď máme dva rôzne črepy. Ak existuje jedna súprava replík, nie je potrebná žiadna synchronizácia: ide o „jednotnú základňu“; máme OpLog, do ktorého spadajú všetky zmeny - v tomto prípade je už všetko sekvenčne usporiadané v samotnom “Oplogu”. Ale ak máme dva rôzne čriepky, dôležitá je tu synchronizácia času. Tu pomohli vektorové hodiny viac! Ale my ich nemáme.

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Druhý je vhodný - toto je „Heartbeats“. Je možné vymieňať niektoré signály, ktoré sa vyskytujú každú jednotku času. Ale tepy sú príliš pomalé, nášmu klientovi nemôžeme poskytnúť latenciu.

Skutočný čas je, samozrejme, úžasná vec. Ale to je asi budúcnosť... Aj keď sa to už dá urobiť v Atlase, už existujú rýchle synchronizátory času „Amazon“. Ale nebude dostupná pre každého.

Ohováranie je, keď všetky správy obsahujú čas. Toto je približne to, čo používame. Každá správa medzi uzlami, ovládač, smerovač dátového uzla, úplne všetko pre MongoDB je nejaký prvok, komponent databázy, ktorý obsahuje hodiny, ktoré bežia. Všade majú význam hybridného času, prenáša sa. 64 bitov? To umožňuje, to je možné.

Ako to všetko spolu funguje?

Tu sa pozerám na jednu sadu replík, aby som to trochu uľahčil. Existujú primárne a sekundárne. Sekundárny robí replikáciu a nie je vždy úplne synchronizovaný s primárnym.

Dostane sa vloženie do „Priméry“ s určitou časovou hodnotou. Táto vložka zvyšuje vnútorný počet o 11, ak je to maximum. Alebo skontroluje hodnoty hodín a synchronizuje sa s hodinami, ak sú hodnoty hodín vyššie. To vám umožní organizovať sa podľa času.

Po nahrávke nastáva dôležitý moment. Hodiny sú v "MongoDB" a zvyšujú sa iba v prípade zápisu do "Oplog". Toto je udalosť, ktorá mení stav systému. V absolútne všetkých klasických článkoch sa za udalosť považuje, keď správa zasiahne uzol: správa prišla, čo znamená, že systém zmenil svoj stav.

Je to spôsobené tým, že počas výskumu nie je celkom jasné, ako bude toto posolstvo interpretované. S istotou vieme, že ak sa to neprejaví v „Oplogu“, nebude to nijako interpretované a zmena stavu systému je len zápisom v „Oplogu“. To nám všetko zjednodušuje: model to zjednodušuje a umožňuje nám to usporiadať do jednej sady replík a mnoho ďalších užitočných vecí.

Hodnota, ktorá je už zapísaná do „Oplog“ je vrátená – vieme, že „Oplog“ už túto hodnotu obsahuje a jeho čas je 12. Teraz, povedzme, čítanie začína z iného uzla (sekundárneho) a vysiela po ClusterTime v správu. Hovorí: „Potrebujem všetko, čo sa stalo aspoň po dvanástej alebo dvanástej“ (pozri obrázok vyššie).

Toto sa nazýva kauzálny a konzistentný (CAT). V teórii existuje taká koncepcia, že ide o nejaký časový úsek, ktorý je sám osebe konzistentný. V tomto prípade môžeme povedať, že toto je stav systému, ktorý bol pozorovaný v čase 12.

Teraz tu ešte nič nie je, pretože tento druh simuluje situáciu, keď potrebujete sekundárny na replikáciu údajov z primárneho. Čaká... A teraz prišli dáta – vracia tieto hodnoty späť.

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Takto to celé funguje. Takmer.

Čo znamená "takmer"? Predpokladajme, že existuje niekto, kto čítal a pochopil, ako to celé funguje. Uvedomil som si, že zakaždým, keď sa vyskytne ClusterTime, aktualizuje vnútorné logické hodiny a potom sa ďalší záznam zvýši o jeden. Táto funkcia zaberá 20 riadkov. Povedzme, že táto osoba prenáša najväčšie 64-bitové číslo mínus jedna.

Prečo „mínus jedna“? Pretože interné hodiny budú nahradené touto hodnotou (samozrejme, je to najväčšia možná a väčšia ako aktuálny čas), potom sa v „Oplog“ objaví záznam a hodiny sa zvýšia o inú jednotku – a už budú byť maximálna hodnota (sú tam jednoducho všetky jednotky, už nie je kam ísť) , unsaint ints).

Je jasné, že po tomto sa systém stáva absolútne neprístupným pre čokoľvek. Dá sa len vyložiť a vyčistiť - veľa ručnej práce. Plná dostupnosť:

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Navyše, ak sa to replikuje niekde inde, potom celý klaster jednoducho spadne. Absolútne neprijateľná situácia, ktorú si každý dokáže zorganizovať veľmi rýchlo a jednoducho! Preto sme tento moment považovali za jeden z najdôležitejších. Ako tomu zabrániť?

Náš spôsob je podpísať clusterTime

Takto sa prenáša v správe (pred modrým textom). Ale začali sme generovať aj podpis (modrý text):

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Podpis je generovaný kľúčom, ktorý je uložený vo vnútri databázy, vnútri zabezpečeného perimetra; sa generuje a aktualizuje (používatelia o ňom nič nevidia). Vygeneruje sa hash a každá správa sa pri vytvorení podpíše a po prijatí sa overí.
V mysliach ľudí sa pravdepodobne vynára otázka: „Ako veľmi to spomaľuje veci? Povedal som vám, že by to malo fungovať rýchlo, najmä pri absencii tejto funkcie.

Čo v tomto prípade znamená použiť Kauzálnu konzistenciu? Toto má ukázať parameter afterClusterTime. Bez toho jednoducho prenesie hodnoty. Ohováranie od verzie 3.6 vždy funguje.

Ak opustíme neustále generovanie podpisov, spomalí to systém aj pri absencii funkcie, ktorá nespĺňa naše prístupy a požiadavky. Čo sme teda urobili?

Urob to rýchlo!

Je to pomerne jednoduchá vec, ale trik je zaujímavý – podelím sa o to, možno to niekoho zaujme.
Máme hash, ktorý ukladá podpísané údaje. Všetky údaje prechádzajú cez vyrovnávaciu pamäť. Cache nepodpisuje konkrétny čas, ale rozsah. Keď príde nejaká hodnota, vygenerujeme rozsah, zamaskujeme posledných 16 bitov a túto hodnotu podpíšeme:

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Prijatím takéhoto podpisu zrýchlime systém (relatívne) 65-tisíckrát. Funguje to skvele: keď sme vykonávali experimenty, čas sa v skutočnosti skrátil 10-tisíckrát, keď sme mali sekvenčnú aktualizáciu. Je jasné, že keď sú v rozpore, tak to nefunguje. Ale vo väčšine praktických prípadov to funguje. Kombinácia podpisu Range spolu s podpisom vyriešila bezpečnostný problém.

čo sme sa naučili?

Ponaučenia, ktoré sme sa z toho naučili:

  • Potrebujeme čítať materiály, príbehy, články, pretože máme veľa zaujímavých vecí. Keď pracujeme na nejakej funkcii (najmä teraz, keď sme robili transakcie atď.), musíme čítať a rozumieť. Vyžaduje si to čas, ale v skutočnosti je to veľmi užitočné, pretože je jasné, kde sa nachádzame. Zdá sa, že sme neprišli s ničím novým – len sme vzali ingrediencie.

    Vo všeobecnosti je určitý rozdiel v myslení, keď je akademická konferencia (napríklad Sigmon) – každý sa zameriava na nové myšlienky. Čo je nové na našom algoritme? Nie je tu nič mimoriadne nové. Novinka spočíva skôr v spôsobe, akým sme spojili existujúce prístupy. Preto je prvou vecou prečítať si klasiku, počnúc Lampartom.

  • Vo výrobe sú požiadavky úplne iné. Som si istý, že mnohí z vás sa nestretávajú so „sférickými“ databázami v abstraktnom vákuu, ale s normálnymi, skutočnými vecami, ktoré majú problémy s dostupnosťou, latenciou a odolnosťou voči chybám.
  • Posledná vec je, že sme sa museli pozrieť na rôzne nápady a spojiť niekoľko úplne odlišných článkov do jedného prístupu, spoločne. Myšlienka podpisu napríklad vo všeobecnosti pochádzala z článku, ktorý uvažoval o protokole Paxos, ktorý je pre nebyzantských neúspešných vo vnútri autorizačného protokolu, pre byzantských - mimo autorizačného protokolu... Vo všeobecnosti je to presne to, čo skončil robiť.

    Nie je tu absolútne nič nové! Ale len čo sme to všetko zmiešali... Je to to isté, ako keby sme povedali, že recept na Olivierov šalát je nezmysel, pretože vajcia, majonéza a uhorky už boli vynájdené... Je to o tom istom príbehu.

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Skončím s týmto. Ďakujem!

otázky

Otázka z publika (ďalej len B): – Ďakujem, Michail, za správu! Téma o čase je zaujímavá. Používate ohováranie. Hovorili, že každý má svoj čas, každý pozná svoj miestny čas. Ako som pochopil, máme vodiča - môže byť veľa klientov s ovládačmi, tiež plánovačov dopytov, tiež črepiny... A na čo sa systém zrúti, ak máme zrazu nezrovnalosť: niekto sa rozhodne, že je pre minútu dopredu, niekto minútu pozadu? Kde skončíme?

MT: – Naozaj skvelá otázka! Chcel som len hovoriť o črepinách. Ak správne rozumiem otázke, máme nasledujúcu situáciu: existuje črep 1 a črep 2, čítanie prebieha z týchto dvoch črepov - majú nesúlad, neinteragujú medzi sebou, pretože čas, ktorý poznajú, je iný, najmä čas, ktorý existujú v oplogoch.
Povedzme, že črep 1 urobil milión záznamov, črep 2 neurobil vôbec nič a požiadavka prišla na dva črepy. A prvý má afterClusterTime viac ako milión. V takejto situácii, ako som vysvetlil, črep 2 nikdy nebude reagovať.

in: – Chcel som vedieť, ako sa synchronizujú a vyberajú jeden logický čas?

MT: - Veľmi jednoduchá synchronizácia. Shard, keď k nemu príde afterClusterTime a nenájde si čas v „Oplog“, iniciuje žiadne schválenie. To znamená, že zdvihne svoj čas rukami na túto hodnotu. To znamená, že nemá žiadne udalosti zodpovedajúce tejto požiadavke. Túto udalosť vytvára umelo a stáva sa tak Kauzálnym konzistentným.

in: – Čo ak mu potom prídu ďalšie udalosti, ktoré sa stratili niekde v sieti?

MT: – Shard je navrhnutý tak, aby sa už nevrátili, keďže ide o jedného pána. Ak sa už prihlásil, tak neprídu, ale prídu neskôr. Nemôže sa stať, že sa niekde niečo zasekne, potom nepíše a potom prídu tieto udalosti – a príčinná konzistencia je narušená. Keď nenapíše, mali by prísť na rad všetci (bude na nich čakať).

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

in: – Mám niekoľko otázok týkajúcich sa čakacích radov. Kauzálna konzistencia predpokladá, že existuje špecifický rad akcií, ktoré je potrebné vykonať. Čo sa stane, ak jeden z našich balíkov zmizne? Prichádza 10., 11.... 12. zmizol a všetci ostatní čakajú, kedy sa to splní. A zrazu nám zomrelo auto, nemôžeme nič robiť. Existuje maximálna dĺžka fronty, ktorá sa nahromadí pred vykonaním? Aké fatálne zlyhanie nastane, keď sa stratí jeden štát? Navyše, ak si napíšeme, že existuje nejaký predchádzajúci stav, tak by sme z neho mali nejako vychádzať? Ale neodstrčili ho!

MT: – Tiež skvelá otázka! Čo robíme? MongoDB má koncept kvóra zapisuje, kvórum číta. V akých prípadoch môže dôjsť k strate správy? Keď zápis nie je kvórum alebo keď čítanie nie je uznášaniaschopné (môže sa nalepiť aj nejaký odpad).
Čo sa týka kauzálnej konzistencie, bol vykonaný veľký experimentálny test, ktorého výsledkom bolo, že v prípade, keď zápisy a čítania nie sú uznášaniaschopné, dochádza k narušeniu kauzálnej konzistencie. Presne to, čo hovoríte!

Naša rada: pri používaní kauzálnej konzistencie používajte aspoň čítanie kvóra. V tomto prípade sa nič nestratí, aj keď sa stratí záznam kvóra... Toto je ortogonálna situácia: ak používateľ nechce, aby sa údaje stratili, musí použiť záznam o kvóre. Príčinná konzistencia nezaručuje trvanlivosť. Trvanlivosť je zaručená replikáciou a mechanizmom spojeným s replikáciou.

in: – Keď vytvoríme inštanciu, ktorá za nás vykoná sharding (nie master, ale slave), spolieha sa na čas Unixu vlastného stroja alebo na čas „mastera“; Synchronizuje sa prvýkrát alebo pravidelne?

MT: – teraz to vysvetlím. Shard (t.j. horizontálna prepážka) – tam je vždy Primárny. A črep môže mať „majstra“ a môžu existovať repliky. Úlomok však vždy podporuje nahrávanie, pretože musí podporovať nejakú doménu (úlomok má Primárnu).

in: – Všetko teda závisí čisto od „pána“? Používa sa vždy majstrovský čas?

MT: - Áno. Obrazne sa dá povedať: hodiny tikajú, keď dôjde k vstupu do „master“, do „Oplog“.

in: – Máme klienta, ktorý sa pripojí a nepotrebuje vedieť nič o čase?

MT: — Nemusíte vedieť vôbec nič! Ak hovoríme o tom, ako to funguje na klientovi: keď chce klient použiť kauzálnu konzistenciu, potrebuje otvoriť reláciu. Teraz je tam všetko: transakcie v relácii a načítanie práv... Relácia je zoradenie logických udalostí vyskytujúcich sa u klienta.

Ak otvorí túto reláciu a povie tam, že chce Kauzálnu konzistenciu (ak relácia štandardne podporuje Kauzálnu konzistenciu), všetko funguje automaticky. Vodič si tento čas zapamätá a pri prijatí novej správy ho zvýši. Pamätá si, akú odpoveď vrátila predchádzajúca odpoveď zo servera, ktorý vrátil údaje. Ďalšia požiadavka bude obsahovať afterCluster("čas väčší ako tento").

Klient nemusí vedieť absolútne nič! Toto je pre neho úplne nepriehľadné. Ak ľudia používajú tieto funkcie, čo môžu robiť? Po prvé, môžete bezpečne čítať sekundárne položky: môžete zapisovať do primárnych a čítať z geograficky replikovaných sekundárnych súborov a byť si istí, že to funguje. Relácie, ktoré boli zaznamenané na primárnom, je zároveň možné preniesť do sekundárneho, t. j. môžete použiť nie jednu reláciu, ale niekoľko.

in: – Nová vrstva výpočtovej vedy – dátové typy CRDT (bezkonfliktné replikované dátové typy) – úzko súvisí s témou eventuálnej konzistencie. Uvažovali ste o integrácii týchto typov údajov do databázy a čo na to môžete povedať?

MT: - Dobrá otázka! CRDT má zmysel pre konflikty zápisu: v MongoDB, single master.

in: – Mám otázku od devopsov. V skutočnom svete existujú také jezuitské situácie, keď dôjde k byzantskému zlyhaniu a zlí ľudia vo vnútri chráneného perimetra sa začnú hrabať do protokolu, posielať remeselné balíčky špeciálnym spôsobom?

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

MT: – Zlí ľudia vo vnútri perimetra sú ako trójsky kôň! Zlí ľudia vo vnútri perimetra môžu urobiť veľa zlých vecí.

in: – Je jasné, že zanechanie, zhruba povedané, diery v serveri, cez ktorú môžete pretlačiť zoologickú záhradu slonov a celý klaster navždy zrútiť... Ručné obnovenie si vyžaduje čas... Toto, mierne povedané, je nesprávne. Na druhej strane je to zaujímavé: v reálnom živote, v praxi, existujú situácie, keď sa prirodzene vyskytujú podobné vnútorné útoky?

MT: – Keďže sa v reálnom živote stretávam s narušeniami bezpečnosti len zriedka, nemôžem povedať, či k nim dôjde. Ale ak hovoríme o filozofii rozvoja, uvažujeme takto: máme perimeter, ktorý poskytuje chlapom, ktorí robia bezpečnosť – toto je hrad, múr; a vo vnútri obvodu si môžete robiť, čo chcete. Je jasné, že existujú používatelia s možnosťou iba prezerania a sú používatelia s možnosťou vymazať adresár.

V závislosti od práv môže byť škoda, ktorú môžu používatelia spôsobiť, myš alebo slon. Je jasné, že používateľ s plnými právami môže robiť vôbec čokoľvek. Používateľ s obmedzenými právami môže spôsobiť podstatne menšie škody. Najmä nemôže rozbiť systém.

in: – V chránenom obvode sa niekto pokúsil vytvoriť neočakávané protokoly pre server, aby server úplne zničil, a ak budete mať šťastie, celý klaster... Bude to niekedy také „dobré“?

MT: "Nikdy som o takých veciach nepočul." Skutočnosť, že týmto spôsobom môžete zrútiť server, nie je žiadnym tajomstvom. Zlyhať vo vnútri, byť z protokolu, byť oprávneným používateľom, ktorý môže niečo také napísať do správy... V skutočnosti je to nemožné, pretože sa to ešte overí. Pre používateľov, ktorí si to neželajú, je možné túto autentifikáciu zakázať – potom je to ich problém; oni, zhruba povedane, sami znicili steny a mozes tam strcit slona, ​​ktory bude dupat... Ale vseobecne sa mozes prezliect za opravara, prides to vytiahnut!

in: – Ďakujem za správu. Sergej (Yandex). V Mong je konštanta, ktorá obmedzuje počet hlasujúcich členov v sade replík, a táto konštanta je 7 (sedem). Prečo je to konštanta? Prečo to nie je nejaký parameter?

MT: – Máme súpravy replík so 40 uzlami. Vždy existuje väčšina. Neviem aka verzia...

in: – V Replica Set môžete prevádzkovať nehlasujúcich členov, ale hlasujúcich členov je maximálne 7. Ako môžeme v tomto prípade prežiť odstávku, ak je naša Replica Set rozmiestnená v 3 dátových centrách? Jedno dátové centrum sa môže ľahko vypnúť a ďalšie zariadenie môže vypadnúť.

MT: – Toto už trochu presahuje rámec správy. Toto je všeobecná otázka. Možno ti o tom poviem neskôr.

HighLoad++, Michail Tyulenev (MongoDB): Príčinná konzistencia: od teórie k praxi

Nejaké inzeráty 🙂

Ďakujeme, že ste zostali s nami. Páčia sa vám naše články? Chcete vidieť viac zaujímavého obsahu? Podporte nás zadaním objednávky alebo odporučením priateľom, cloud VPS pre vývojárov od 4.99 USD, jedinečný analóg serverov základnej úrovne, ktorý sme pre vás vymysleli: Celá pravda o VPS (KVM) E5-2697 v3 (6 jadier) 10GB DDR4 480GB SSD 1Gbps od 19 USD alebo ako zdieľať server? (k dispozícii s RAID1 a RAID10, až 24 jadier a až 40 GB DDR4).

Dell R730xd 2 krát lacnejší v dátovom centre Equinix Tier IV v Amsterdame? Len tu 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6 GHz 14C 64 GB DDR4 4 x 960 GB SSD 1 Gbps 100 TV od 199 USD v Holandsku! Dell R420 – 2x E5-2430 2.2 GHz 6C 128 GB DDR3 2 x 960 GB SSD 1 Gb/s 100 TB – od 99 USD! Čítať o Ako vybudovať infraštruktúru spol. triedy s využitím serverov Dell R730xd E5-2650 v4 v hodnote 9000 XNUMX eur za cent?

Zdroj: hab.com

Pridať komentár