Programování

Kdy použít databázi založenou na CRDT

Roshan Kumar je vedoucí produktový manažer ve společnosti Redis Labs.

Ohýbání konzistence a dostupnosti popsané teorémem CAP bylo velkou výzvou pro architekty geo-distribuovaných aplikací. Síťový oddíl je nevyhnutelný. Vysoká latence mezi datovými centry vždy vede k určitému odpojení mezi datovými centry na krátkou dobu. Tradiční architektury pro geodistribuované aplikace jsou tedy navrženy tak, aby buď vzdaly konzistenci dat, nebo zasáhly dostupnost.

Bohužel si nemůžete dovolit obětovat dostupnost interaktivních uživatelských aplikací. V nedávné době architekti udělali pokus o konzistenci a přijali případný model konzistence. V tomto modelu závisí aplikace na systému správy databází, aby sloučily všechny místní kopie dat, aby byly nakonec konzistentní.

S případným modelem konzistence vypadá všechno dobře, dokud nedojde ke konfliktům dat. Několik modelů případné konzistence slibuje nejlepší úsilí k vyřešení konfliktů, ale nedosahují zaručení silné konzistence. Dobrou zprávou je, že modely postavené na bezkonfliktních replikovaných datových typech (CRDT) poskytují silnou případnou konzistenci.

CRDT dosahují silné případné konzistence prostřednictvím předem stanovené sady pravidel a sémantiky řešení konfliktů. Aplikace postavené na databázích založených na CRDT musí být navrženy tak, aby vyhovovaly sémantice řešení konfliktů. V tomto článku prozkoumáme, jak navrhovat, vyvíjet a testovat geodistribuované aplikace pomocí databáze založené na CRDT. Budeme také zkoumat čtyři ukázkové případy použití: čítače, distribuované ukládání do mezipaměti, sdílené relace a příjem dat z více oblastí.

Můj zaměstnavatel, Redis Labs, nedávno ohlásil podporu CRDT v Redis Enterprise, přičemž bezkonfliktní replikované datové typy se připojily k bohatému portfoliu datových struktur - Strings, Hashes, Lists, Sets, Sorted Sets, Bitfields, Geo, Hyperloglog a Streams - in náš databázový produkt. Následující diskuse se však vztahuje nejen na Redis Enterprise, ale na všechny databáze založené na CRDT.

Databáze pro geodistribuované aplikace

U geograficky distribuovaných aplikací je běžné spouštět služby lokálně pro klienty. To snižuje síťový provoz a latenci způsobenou zpáteční cestou. V mnoha případech architekti navrhnou služby pro připojení k místní databázi. Pak přichází otázka, jak udržujete konzistentní data napříč všemi databázemi. Jednou z možností je to řešit na úrovni aplikace - můžete napsat periodický proces úlohy, který synchronizuje všechny databáze. Nebo se můžete spolehnout na databázi, která bude synchronizovat data mezi databázemi.

U zbytku článku předpokládáme, že půjdete s druhou možností - nechte práci provést databázi. Jak je znázorněno na obrázku 1 níže, vaše geograficky distribuovaná aplikace spouští služby ve více oblastech, přičemž každá služba se připojuje k místní databázi. Základní systém správy databází synchronizuje data mezi databázemi nasazenými v regionech.

Redis Labs

Modely konzistence dat

Model konzistence je smlouva mezi distribuovanou databází a aplikací, která definuje, jak čistá jsou data mezi operacemi zápisu a čtení.

Například v silném modelu konzistence databáze zaručuje, že aplikace budou vždy číst poslední zápis. Se sekvenční konzistencí databáze zajišťuje, že pořadí dat, která čtete, je konzistentní s pořadím, ve kterém byla zapsána do databáze. V případném modelu konzistence distribuovaná databáze slibuje synchronizaci a konsolidaci dat mezi replikami databáze v zákulisí. Pokud tedy zapisujete data do jedné repliky databáze a čtete je z jiné, je možné, že si nebudete přečíst nejnovější kopii dat.

Silná konzistence

Dvoufázové potvrzení je běžná technika k dosažení silné konzistence. Tady pro každou operaci zápisu (přidání, aktualizace, odstranění) v místním uzlu databáze šíří uzel databáze změny do všech uzlů databáze a čeká na potvrzení všech uzlů. Místní uzel poté odešle potvrzení všem uzlům a čeká na další potvrzení. Aplikace bude moci číst data až po druhém potvrzení. Distribuovaná databáze nebude k dispozici pro operace zápisu, když se síť odpojí mezi databázemi.

Případná konzistence

Hlavní výhodou modelu případné konzistence je, že databáze vám bude k dispozici k provádění operací zápisu, i když dojde k poruše síťového připojení mezi replikami distribuované databáze. Obecně se tento model vyhýbá době zpáteční cesty vzniklé dvoufázovým potvrzením, a proto podporuje mnohem více operací zápisu za sekundu než ostatní modely. Jedním problémem, který musí eventuální konzistence řešit, jsou konflikty - současné zápisy na stejnou položku na dvou různých místech. Na základě toho, jak se vyhýbají nebo řeší konflikty, jsou nakonec konzistentní databáze dále klasifikovány do následujících kategorií:

  1. Poslední autor vyhrává (LWW). V této strategii se distribuované databáze spoléhají na synchronizaci časových značek mezi servery. Databáze si vyměňují časové razítko každé operace zápisu spolu se samotnými daty. Pokud dojde ke konfliktu, vyhraje operace zápisu s nejnovější časovou značkou.

    Nevýhodou této techniky je, že předpokládá synchronizaci všech systémových hodin. V praxi je synchronizace všech systémových hodin obtížná a nákladná.

  2. Případná konzistence založená na kvoru: Tato technika je podobná dvoufázovému potvrzení. Místní databáze však nečeká na potvrzení ze všech databází; jen čeká na potvrzení od většiny databází. Uznání většiny zakládá usnášeníschopnost. V případě konfliktu vyhrává operace zápisu, která stanovila usnášeníschopnost.

    Na druhou stranu tato technika přidává latenci sítě k operacím zápisu, což činí aplikaci méně škálovatelnou. Místní databáze také nebude k dispozici pro zápisy, pokud bude izolována od ostatních replik databáze v topologii.

  3. Sloučit replikaci: V tomto tradičním přístupu, který je běžný mezi relačními databázemi, centralizuje sloučený agent všechna data. Tato metoda také nabízí určitou flexibilitu při implementaci vlastních pravidel pro řešení konfliktů.

    Sloučení replikace je příliš pomalé na to, aby podporovalo poutavé aplikace v reálném čase. Má také jediný bod selhání. Protože tato metoda nepodporuje přednastavená pravidla pro řešení konfliktů, často vede k chybovým implementacím pro řešení konfliktů.

  4. Bezkonfliktní replikovaný datový typ (CRDT): O CRDT se dozvíte podrobně v několika následujících částech. Stručně řečeno, databáze založené na CRDT podporují datové typy a operace, které přinášejí případnou konzistenci bez konfliktů. Databáze založené na CRDT jsou k dispozici, i když si repliky distribuované databáze nemohou vyměňovat data. Vždy dodávají místní latenci operacím čtení a zápisu.

    Omezení? Ne všechny případy použití databáze těží z CRDT. Sémantika řešení konfliktů pro databáze založené na CRDT je ​​také předdefinována a nelze ji přepsat.

Co jsou CRDT?

CRDT jsou speciální datové typy, které konvergují data ze všech replik databáze. Populární CRDT jsou G-čítače (čítače pouze pro růst), čítače PN (kladně-záporné čítače), registry, G-sady (sady pouze pro růst), sady 2P (dvoufázové sady), sady OR ( pozorované-odstranit sady) atd. V zákulisí se při konvergenci dat spoléhají na následující matematické vlastnosti:

  1. Komutativní vlastnost: a ☆ b = b ☆ a
  2. Asociativní vlastnost: a ☆ (b ☆ c) = (a ☆ b) ☆ c
  3. Idempotence: a ☆ a = a

Počítadlo G je dokonalým příkladem funkčního CRDT, který slučuje operace. Zde a + b = b + a a + (b + c) = (a + b) + c. Repliky si navzájem vyměňují pouze aktualizace (doplňky). CRDT sloučí aktualizace jejich přidáním. Sada G například používá idempotenci ({a, b, c} U {c} = {a, b, c}) ke sloučení všech prvků. Idempotence zamezuje duplikaci prvků přidaných do datové struktury při jejich cestování a konvergenci různými cestami.

Datové typy CRDT a jejich sémantika řešení konfliktů

Konfliktní datové struktury: G-čítače, PN-čítače, G-sady

Všechny tyto datové struktury jsou záměrně bezkonfliktní. Níže uvedené tabulky ukazují, jak jsou data synchronizována mezi replikami databáze.

Redis Labs Redis Labs

G-počitadla a PN-počitadla jsou populární pro případy použití, jako je globální dotazování, počty streamů, sledování aktivity atd. G-sady se často používají k implementaci technologie blockchain. Například bitcoiny používají blockchainové položky pouze pro přidání.

Registry: Strings, Hashes

Registry nejsou ze své podstaty bezkonfliktní. Obvykle dodržují zásady řešení konfliktů na základě LWW nebo kvora. Obrázek 4 ukazuje příklad toho, jak registr řeší konflikt podle zásad LWW.

Redis Labs

Registry se používají hlavně k ukládání dat do mezipaměti a relací, informací o uživatelských profilech, katalogu produktů atd.

2P sady

Dvoufázové sady udržují dvě sady G-sad - jednu pro přidané položky a druhou pro odstraněné položky. Repliky si při synchronizaci vyměňují doplňky G-setu. Konflikt vzniká, když je v obou sadách nalezen stejný prvek. V některých databázích založených na CRDT, jako je Redis Enterprise, je toto zpracováno zásadou „Přidat vyhraje nad odstraněním.“

Redis Labs

Sada 2P je dobrá datová struktura pro ukládání dat sdílených relací, jako jsou nákupní vozíky, sdílený dokument nebo tabulka.

Jak vytvořit architekturu pro použití databáze založené na CRDT

Připojení vaší aplikace k databázi založené na CRDT se neliší od připojení vaší aplikace k jakékoli jiné databázi. Kvůli zásadám případné konzistence však vaše aplikace musí dodržovat určitou sadu pravidel, aby poskytla konzistentní uživatelské prostředí. Tři klíče: 

  1. Udělejte svou aplikaci bez státní příslušnosti. Bezstavová aplikace je obvykle řízena API. Každé volání API má za následek rekonstrukci úplné zprávy od nuly. Tím je zajištěno, že v každém okamžiku vytáhnete čistou kopii dat. Nízká místní latence, kterou nabízí databáze založená na CRDT, umožňuje rychlejší a snadnější rekonstrukci zpráv. 

  2. Vyberte správný CRDT, který odpovídá vašemu případu použití. Počítadlo je nejjednodušší z CRDT. Lze jej použít pro případy použití, jako je globální hlasování, sledování aktivních relací, měření atd. Pokud však chcete sloučit stav distribuovaných objektů, musíte vzít v úvahu i jiné datové struktury. Například pro aplikaci, která umožňuje uživatelům upravovat sdílený dokument, můžete chtít zachovat nejen úpravy, ale také pořadí, ve kterém byly provedeny. V takovém případě by uložení úprav do seznamu založeného na CRDT nebo datové struktuře fronty bylo lepším řešením než jejich uložení do registru. Je také důležité, abyste porozuměli sémantice řešení konfliktů vynucené CRDT a aby vaše řešení vyhovovalo pravidlům.
  3. CRDT není univerzální řešení. Zatímco CRDT je ​​opravdu skvělý nástroj pro mnoho případů použití, nemusí být nejlepší pro všechny případy použití (například transakce ACID). Databáze založené na CRDT obecně dobře zapadají do architektury mikroslužeb, kde máte vyhrazenou databázi pro každou mikroslužbu.

Hlavní výhodou je, že vaše aplikace by se měla zaměřit na logiku a delegovat složitost správy dat a synchronizace na podkladovou databázi.

Testování aplikací s distribuovanou databází více hlavních serverů

Chcete-li dosáhnout rychlejšího uvedení na trh, doporučujeme vám mít konzistentní vývoj, testování, pracovní a výrobní nastavení. Mimo jiné to znamená, že vaše vývojové a testovací nastavení musí mít miniaturizovaný model vaší distribuované databáze. Zkontrolujte, zda je vaše databáze založená na CRDT dostupná jako kontejner Dockeru nebo virtuální zařízení. Nasaďte repliky databáze do různých podsítí, abyste mohli simulovat připojené a odpojené nastavení clusteru.

Testování aplikací s distribuovanou databází více masterů může znít komplexně. Většinu času však budete testovat pouze konzistenci dat a dostupnost aplikací ve dvou situacích: Když jsou distribuované databáze připojeny a když je mezi databázemi síťový oddíl.

Nastavením distribuované databáze se třemi uzly ve vývojovém prostředí můžete pokrýt (a dokonce automatizovat) většinu testovacích scénářů v testování jednotky. Zde jsou základní pokyny pro testování vašich aplikací: