Moderní distribuované systémy jsou o kompromisech. Výkon, spolehlivost, škálovatelnost a konzistence nejsou zadarmo – vždy někde platíte cenu. Zde přichází na řadu teorém CAP: je to výchozí bod pro pochopení nevyhnutelných kompromisů v distribuovaném návrhu.
Proč je teorém CAP pravdivý? Co to vlastně vysvětluje? A hlavně, stačí to? V tomto příspěvku prozkoumáme teorém CAP, jeho omezení, kritiku, s níž se setkal, a jak novější nápady, jako je PACELC, posouvají konverzaci kupředu. Pojďme se ponořit.
První verze teorému CAP začala jako debata mezi ACID vs. BASE . Postupem času se však vyvinul, získal formální důkaz a vygradoval, aby se stal teorémem CAP, jak jej známe dnes.
CAP teorém říká, že distribuovaný systém může uspokojit maximálně dvě ze tří vlastností současně :
Toto omezení nutí inženýry k tvrdým kompromisům v závislosti na cílech systému a realitě jejich distribuovaných prostředí.
Konzistence v CAP není stejná jako konzistence v ACID transakcích . V CAP teorému to odkazuje na linearizovatelnost nebo silnou konzistenci . To znamená, že všechny uzly v distribuovaném systému musí vždy poskytovat jediný aktuální pohled na data , bez ohledu na to, který uzel požadavek zpracovává. To znamená, že každá operace čtení odráží poslední zápis bez ohledu na to, na který uzel se dotazujete.
💡 Konzistence v ACID se na druhou stranu zaměřuje na zajištění toho, aby transakce přenesla databázi z jednoho platného stavu do jiného platného podle pravidel definovaných schématem databáze. Jde spíše o vynucení omezení integrity (jako jsou cizí klíče, jedinečná omezení atd.) a zajištění, aby databáze nezůstala v neplatném stavu, a to ani v případě selhání.
Dostupnost v CAP znamená, že každý neselhávající uzel musí vrátit odpověď na každý požadavek, který obdrží, bez ohledu na síťové oddíly . Jinými slovy, pokud zdravý uzel obdrží požadavek, musí jej zpracovat a odpovědět na něj. CAP však nezaručuje, že odpověď bude vždy „správná“ nebo aktuální – pouze zajišťuje, že uzel neselže tiše (například v systému AP mohou uzly reagovat zastaralými daty během oddílu, aby byla zajištěna dostupnost ).
💡 Eric Brewer (původní autor CAP) tuto vlastnost původně popsal trochu flexibilněji jako: "téměř všechny dotazy by měly dostat odpověď". Ve formálním důkazu CAP však byla dostupnost přísnější a vyžadovala „odpověď na každý dotaz, pokud je uzel, který jej zpracovává, zdravý“.
V praxi však dostupnost není absolutní zárukou – často závisí na omezeních specifických pro daný systém, například jak dlouho jste ochotni čekat na odpověď. U systémů v reálném světě hraje doba odezvy (nebo časové limity) zásadní roli při utváření vaší SLA (smlouva o úrovni služeb), i když samotná CAP nezohledňuje latenci. Více o tom v tomto příspěvku na blogu .
Tolerance oddílu je o přežití selhání sítě. Pokud uzly nemohou komunikovat kvůli rozdělení sítě (oddílu), systém musí stále splňovat své záruky konzistence nebo dostupnosti v závislosti na volbě návrhu. K oddílu dochází, když uzly nemohou komunikovat kvůli zahozeným paketům, časovým limitům nebo rozdělením sítě.
Distribuované systémy nežijí v pohádkovém světě s dokonalými sítěmi. Pakety jsou zahazovány, dochází k vypršení časového limitu a špičkám latence se nelze vyhnout. Z tohoto důvodu je tolerance oddílů nesmlouvavá v žádném distribuovaném systému – k oddílům dříve nebo později dojde, takže si nemůžete "rozhodnout" ignorovat to, bez ohledu na to, jak lákavě to může znít.
V CAP tolerance oddílů neznamená, že systém běží, jako by se nic nestalo. Znamená to, že systém se musí rozhodnout, zda upřednostní dostupnost (AP) nebo konzistenci (CP) během rozdělení. Pokud byste ignorovali toleranci oddílů, v podstatě byste budovali nedistribuovaný monolitický systém.
Nejjednodušší způsob, jak porozumět CAP, je zvážit síťový oddíl – situaci, kdy dvě části distribuovaného systému spolu nemohou komunikovat. V takovém scénáři má systém tři možné výsledky:
Během rozdělení tedy může systém uspokojit pouze dvě ze tří vlastností (C, A nebo P) . Jakmile je rozdělení vyřešeno (tj. uzly opět interagují), systém může znovu získat všechny tři vlastnosti, ale během samotného rozdělení jsou kompromisy nevyhnutelné.
Důsledkem teorému pro asynchronní systémy je, že jsou možné pouze tři kombinace konzistence, dostupnosti a tolerance oddílů:
Systémy tohoto typu odpovídají na dotazy, ale vrácená data nemusí být vždy aktuální, s pomalejšími aktualizacemi dat, ale „vždy“ dostupnými. Příklady takového systému jsou DNS, DynamoDB a Cassandra.
Systémy tohoto typu vždy vracejí aktuální data, ale některé nebo dokonce všechny uzly v systému nemusí reagovat, pokud jsou rozděleny. Poskytuje atomické aktualizace, ale může vést k vypršení časového limitu. NoSQL databáze jako Google BigTable, MongoDB, HBase a Redis jsou systémy tohoto typu.
Systémy tohoto typu vždy vracejí aktuální data, když nejsou žádné oddíly. Kvůli poslednímu omezení se takové systémy obvykle používají pouze v rámci jednoho stroje. Příkladem jsou klasické relační databáze.
Ve skutečnosti volíme mezi CP a AP, protože CA je v podstatě monolit bez oddílů. U rozsáhlých systémů nemohou návrháři opustit P, a proto mají obtížnou volbu mezi C a A.
V CA selhání uzlu znamená úplnou nedostupnost služby. To však nezakazuje škálovatelnost, protože můžeme klonovat nezávislé monolity a rozložit na ně zátěž
Teorém CAP byl základním konceptem v distribuovaných systémech, ale není bez omezení. Přes veškerou svou jasnost při prezentaci myšlenky kompromisů byl teorém SZP často kritizován za přílišné zjednodušování složité reality, což vedlo k nedorozuměním a nesprávným aplikacím.
Jednou z nejběžnějších kritik je, že kompromisy teorému CAP – výběr mezi konzistencí (C) a dostupností (A) – platí pouze tehdy, když skutečně dojde k rozdělení sítě (P) . V normálním provozu, kdy je síť stabilní a neexistují žádné oddíly, neexistuje žádný vlastní kompromis mezi konzistencí a dostupností.
Navíc tyto kompromisy nejsou univerzální v celém systému. V rámci stejného distribuovaného systému:
Tato nuance se často ztrácí v diskusích o CAP na vysoké úrovni, což vede k příliš zjednodušené klasifikaci systémů jako „CP“ nebo „AP“.
Další důležitou kritikou je, že teorém CAP nebere v úvahu latenci , i když jsou latence a dělení v praxi hluboce propojeny. Například:
V distribuovaných systémech v reálném světě, když dojde k rozdělení nebo vysoké latenci, musí systém učinit rozhodnutí během časového limitu : upřednostnit dostupnost vrácením pravděpodobně zastaralého výsledku nebo upřednostnit konzistenci delším čekáním (a potenciálně selháním odpovědi). Binární pohled CAP nezachycuje složitost těchto rozhodnutí.
Teorém CAP představuje konzistenci, dostupnost a toleranci oddílů jako binární vlastnosti – buď je máte, nebo ne. Ale v praxi všechny tři vlastnosti existují na spektru :
Díky této nepřetržité povaze vlastností je CAP příliš zjednodušující pro modelování složitosti moderních distribuovaných systémů.
Přestože CAP způsobila revoluci v našem chápání kompromisů v distribuovaných systémech, není to poslední slovo na toto téma. PACELCova věta popsaná Danielem J. Abadim je považována za alternativní přístup k návrhu distribuovaných systémů. Je založen na modelu CAP, ale kromě konzistence, dostupnosti a tolerance oddílů zahrnuje také latenci a logické vyloučení mezi kombinacemi těchto konceptů.
PACELC zavádí dva odlišné režimy provozu pro distribuované systémy:
Zatímco oddíly jsou v distribuovaných systémech nevyhnutelné, jsou vzácné ve srovnání s problémy, které se objevují během normálního provozu. V moderních distribuovaných systémech je latence často větším úzkým hrdlem než síťové oddíly, zejména u aplikací v globálním měřítku. To je oblast, na kterou se PACELC zaměřuje – řešením kompromisů, ke kterým dochází, když systém funguje bez oddílů. Na rozdíl od CAP, která se zaměřuje výhradně na chování během scénářů selhání, PACELC zdůrazňuje rozhodnutí, která musí architekti každý den učinit, aby vyvážili latenci (L) a konzistenci (C) :
Rozšířením konverzace mimo oddíly tak, aby zahrnovala běžný provoz, PACELC zajišťuje, že s každodenním výkonem distribuovaných systémů bude zacházeno s takovou důležitostí, jakou si zaslouží.
Formulace teorému CAP byla významnou událostí v komunitě a studie jeho dopadu na návrh distribuovaných systémů ukázaly, že návrháři distribuovaných systémů by neměli omezovat systém na dvě vlastnosti – měli by se snažit maximalizovat záruky požadované v každé z nich. konkrétní případ. Za tímto účelem je rozumné rozdělit systém na segmenty, z nichž každý má své vlastní požadavky, a navrhnout systém na základě požadavků každého ze segmentů.
Teorém CAP byl po desetiletí základním kamenem myšlení o distribuovaných systémech. Poskytlo nám to rámec pro uvažování o inherentních kompromisech konzistence, dostupnosti a tolerance rozdělení. Ale v mnoha ohledech je to zjednodušení reality, za předpokladu binárních voleb a ignorování kritických faktorů, jako je latence.
PACELC staví na CAP a uznává, že:
CAP i PACELC jsou cenné nástroje, ale ani jeden z nich není receptem na budování systémů krok za krokem. Místo toho poskytují mentální modely pro vyhodnocování kompromisů a pochopení limitů distribuovaných architektur.
Děkuji za přečtení!
Zajímá vás něco nebo máte nápady, o které se chcete podělit? Zanechte svůj komentář níže! Podívejte se na můj blog nebo mě sledujte přes LinkedIn , Substack nebo Telegram .