Prečo možno budete potrebovať semisynchrónnu replikáciu?

Ahojte všetci. Vladislav Rodin je v kontakte. V súčasnosti vediem kurzy softvérovej architektúry a vysokostresovej softvérovej architektúry na OTUS. V očakávaní začiatku nového prúdu kurzu "architekt vysokého zaťaženia" Rozhodol som sa napísať krátky kúsok originálneho materiálu, o ktorý sa chcem s vami podeliť.

Prečo možno budete potrebovať semisynchrónnu replikáciu?

Úvod

Vzhľadom na to, že HDD dokáže vykonať len okolo 400-700 operácií za sekundu (čo je neporovnateľné s typickými rps na vysoko zaťaženom systéme), je klasická disková databáza prekážkou architektúry. Preto je potrebné venovať osobitnú pozornosť vzorom škálovania tohto úložiska.

V súčasnosti existujú 2 vzory škálovania databázy: replikácia a sharding. Zdieľanie vám umožňuje škálovať operáciu zápisu a v dôsledku toho znížiť rýchlosť otáčok na zápis na server vo vašom klastri. Replikácia vám umožňuje robiť to isté, ale s operáciami čítania. Práve tomuto vzoru je venovaný tento článok.

Replikácia

Ak sa pozriete na replikáciu na veľmi vysokej úrovni, je to jednoduchá vec: mali ste jeden server, boli na ňom údaje a tento server už nezvládal záťaž čítania týchto údajov. Pridáte niekoľko ďalších serverov, zosynchronizujete údaje na všetkých serveroch a používateľ môže čítať z ľubovoľného servera vo vašom klastri.

Napriek zjavnej jednoduchosti existuje niekoľko možností klasifikácie rôznych implementácií tejto schémy:

  • Podľa rolí v klastri (master-master alebo master-slave)
  • Podľa odoslaných objektov (riadkové, príkazové alebo zmiešané)
  • Podľa mechanizmu synchronizácie uzlov

Dnes sa budeme zaoberať bodom 3.

Ako dôjde k potvrdeniu transakcie?

Táto téma priamo nesúvisí s replikáciou, dá sa o nej napísať samostatný článok, ale keďže ďalšie čítanie je zbytočné bez pochopenia mechanizmu potvrdenia transakcie, dovoľte mi pripomenúť najzákladnejšie veci. Potvrdenie transakcie prebieha v 3 fázach:

  1. Zaznamenávanie transakcie do denníka databázy.
  2. Použitie transakcie v databázovom stroji.
  3. Vrátenie potvrdenia klientovi, že transakcia bola úspešne použitá.

V rôznych databázach môže mať tento algoritmus nuansy: napríklad v motore InnoDB databázy MySQL sú 2 protokoly: jeden na replikáciu (binárny protokol) a druhý na udržiavanie ACID (protokol späť/znova), zatiaľ čo v PostgreSQL existuje jeden protokol, ktorý vykonáva obe funkcie (zápis dopredu = WAL). Ale to, čo je uvedené vyššie, je presne všeobecný koncept, ktorý umožňuje, aby sa takéto nuansy nezohľadňovali.

Synchrónna (synchronizovaná) replikácia

Pridajme logiku na replikáciu prijatých zmien do algoritmu potvrdenia transakcie:

  1. Zaznamenávanie transakcie do denníka databázy.
  2. Použitie transakcie v databázovom stroji.
  3. Odosielanie údajov do všetkých replík.
  4. Prijímanie potvrdenia od všetkých kópií, že transakcia na nich bola dokončená.
  5. Vrátenie potvrdenia klientovi, že transakcia bola úspešne použitá.

S týmto prístupom máme niekoľko nevýhod:

  • klient čaká, kým sa zmeny aplikujú na všetky repliky.
  • so zvyšujúcim sa počtom uzlov v klastri znižujeme pravdepodobnosť, že operácia zápisu bude úspešná.

Ak je s 1. bodom všetko viac-menej jasné, tak dôvody 2. bodu stoja za vysvetlenie. Ak počas synchrónnej replikácie nedostaneme odpoveď aspoň z jedného uzla, transakciu vrátime späť. Zvýšením počtu uzlov v klastri teda zvýšite pravdepodobnosť, že operácia zápisu zlyhá.

Môžeme čakať na potvrdenie len od určitého percenta uzlov, napríklad od 51 % (kvórum)? Áno, môžeme, ale v klasickej verzii je potrebné potvrdenie zo všetkých uzlov, pretože takto vieme zabezpečiť úplnú konzistenciu dát v klastri, čo je nepochybnou výhodou tohto typu replikácie.

Asynchrónna (asynchrónna) replikácia

Upravme predchádzajúci algoritmus. Údaje do kópií pošleme „niekedy neskôr“ a „niekedy neskôr“ sa zmeny použijú na repliky:

  1. Zaznamenávanie transakcie do denníka databázy.
  2. Použitie transakcie v databázovom stroji.
  3. Vrátenie potvrdenia klientovi, že transakcia bola úspešne použitá.
  4. Odosielanie údajov do kópií a uplatňovanie zmien v nich.

Tento prístup vedie k tomu, že klaster funguje rýchlo, pretože klienta nenecháme čakať, kým sa dáta dostanú k replikám a dokonca sa zaviažu.

Ale podmienka uloženia údajov na repliky „niekedy neskôr“ môže viesť k strate transakcie a k strate transakcie potvrdenej používateľom, pretože ak údaje nestihli replikovať, potvrdenie pre klienta o úspešnosti operácie bola odoslaná a uzol, do ktorého prišli zmeny, havaroval HDD, stratíme transakciu, čo môže viesť k veľmi nepríjemným následkom.

Polosynchronizovaná replikácia

Nakoniec sa dostávame k semisynchrónnej replikácii. Tento typ replikácie nie je veľmi známy alebo veľmi bežný, ale je veľmi zaujímavý, pretože môže kombinovať výhody synchrónnej aj asynchrónnej replikácie.

Skúsme spojiť 2 predchádzajúce prístupy. Klienta si nenecháme dlho, ale budeme vyžadovať, aby boli údaje replikované:

  1. Zaznamenávanie transakcie do denníka databázy.
  2. Použitie transakcie v databázovom stroji.
  3. Odosielanie údajov do replík.
  4. Prijatie potvrdenia z repliky, že zmeny boli prijaté (aplikujú sa „niekedy neskôr“).
  5. Vrátenie potvrdenia klientovi, že transakcia bola úspešne použitá.

Upozorňujeme, že s týmto algoritmom dôjde k strate transakcie iba vtedy, ak zlyhá uzol prijímajúci zmeny aj uzol repliky. Pravdepodobnosť takéhoto zlyhania sa považuje za nízku a tieto riziká sa akceptujú.

Ale pri tomto prístupe existuje možné riziko fantómového čítania. Predstavme si nasledujúci scenár: v kroku 4 sme nedostali potvrdenie od žiadnej repliky. Túto transakciu musíme vrátiť späť a nevracať klientovi potvrdenie. Keďže údaje boli aplikované v kroku 2, medzi koncom kroku 2 a vrátením transakcie je časová medzera, počas ktorej môžu paralelné transakcie vidieť zmeny, ktoré by nemali byť v databáze.

Polosynchrónna replikácia bez straty

Ak trochu premýšľate, môžete jednoducho obrátiť kroky algoritmu a vyriešiť problém fantómového čítania v tomto scenári:

  1. Zaznamenávanie transakcie do denníka databázy.
  2. Odosielanie údajov repliky.
  3. Prijatie potvrdenia z repliky, že zmeny boli prijaté (aplikujú sa „niekedy neskôr“).
  4. Použitie transakcie v databázovom stroji.
  5. Vrátenie potvrdenia klientovi, že transakcia bola úspešne použitá.

Teraz vykonáme zmeny, iba ak boli replikované.

Výkon

Ako vždy neexistujú ideálne riešenia, existuje súbor riešení, z ktorých každé má svoje výhody a nevýhody a je vhodné na riešenie rôznych tried problémov. To platí absolútne pre výber mechanizmu na synchronizáciu údajov v replikovanej databáze. Sada výhod, ktoré má semisynchrónna replikácia, je dostatočne solídna a zaujímavá, že ju možno považovať za hodnú pozornosti, napriek jej nízkej prevalencii.

To je všetko. Vidíme sa na kurz!

Zdroj: hab.com

Pridať komentár