Nejen zpracování: Jak jsme vytvořili distribuovanou databázi z Kafka Streams a co z toho vzešlo

Čau Habr!

Připomínáme, že po knize o Kafka jsme vydali neméně zajímavou práci o knihovně Kafka Streams API.

Nejen zpracování: Jak jsme vytvořili distribuovanou databázi z Kafka Streams a co z toho vzešlo

Komunita se zatím jen učí limity tohoto mocného nástroje. Nedávno tedy vyšel článek, s jehož překladem bychom vás rádi seznámili. Autor z vlastní zkušenosti vypráví, jak proměnit Kafka Streams v distribuované úložiště dat. Příjemné čtení!

Knihovna Apache Kafkovy proudy používá se po celém světě v podnicích pro distribuované zpracování datových proudů nad Apache Kafka. Jedním z nedoceněných aspektů tohoto rámce je, že vám umožňuje ukládat místní stav vytvořený na základě zpracování vláken.

V tomto článku vám řeknu, jak se naší společnosti podařilo tuto příležitost výhodně využít při vývoji produktu pro zabezpečení cloudových aplikací. Pomocí Kafka Streams jsme vytvořili sdílené stavové mikroslužby, z nichž každá slouží jako chybový a vysoce dostupný zdroj spolehlivých informací o stavu objektů v systému. Pro nás je to krok vpřed jak z hlediska spolehlivosti, tak i snadné podpory.

Pokud vás zajímá alternativní přístup, který vám umožní používat jedinou centrální databázi pro podporu formálního stavu vašich objektů, přečtěte si ji, bude to zajímavé...

Proč jsme si řekli, že je čas změnit způsob, jakým pracujeme se sdíleným stavem

Potřebovali jsme udržovat stav různých objektů na základě zpráv agentů (například: byl web napaden)? Před migrací na Kafka Streams jsme pro správu státu často spoléhali na jedinou centrální databázi (+ API služby). Tento přístup má své nevýhody: rande intenzivní situace udržení konzistence a synchronizace se stává skutečnou výzvou. Databáze se může stát úzkým hrdlem nebo skončit závodní podmínky a trpí nepředvídatelností.

Nejen zpracování: Jak jsme vytvořili distribuovanou databázi z Kafka Streams a co z toho vzešlo

Obrázek 1: Typický scénář rozděleného stavu před přechodem na
Kafka a Kafka Streams: agenti komunikují své pohledy přes API, aktualizovaný stav je vypočítáván prostřednictvím centrální databáze

Seznamte se s Kafka Streams, což usnadňuje vytváření sdílených státních mikroslužeb

Asi před rokem jsme se rozhodli důkladně prozkoumat naše sdílené scénáře stavu, abychom tyto problémy vyřešili. Okamžitě jsme se rozhodli vyzkoušet Kafka Streams – víme, jak je škálovatelný, vysoce dostupný a odolný proti chybám, jakou má bohatou streamovací funkcionalitu (transformace včetně stavových). Přesně to, co jsme potřebovali, nemluvě o tom, jak vyspělý a spolehlivý se stal systém zasílání zpráv v Kafce.

Každá stavová mikroslužba, kterou jsme vytvořili, byla postavena na instanci Kafka Streams s poměrně jednoduchou topologií. Skládal se z 1) zdroje 2) procesoru s perzistentním úložištěm klíč-hodnota 3) jímky:

Nejen zpracování: Jak jsme vytvořili distribuovanou databázi z Kafka Streams a co z toho vzešlo

Obrázek 2: Výchozí topologie našich instancí streamování pro stavové mikroslužby. Všimněte si, že je zde také úložiště, které obsahuje plánovací metadata.

V tomto novém přístupu agenti skládají zprávy, které jsou vloženy do zdrojového tématu, a spotřebitelé – řekněme služba upozornění na e-mail – obdrží vypočítaný sdílený stav prostřednictvím jímky (výstupní téma).

Nejen zpracování: Jak jsme vytvořili distribuovanou databázi z Kafka Streams a co z toho vzešlo

Obrázek 3: Nový příklad toku úloh pro scénář se sdílenými mikroslužbami: 1) agent vygeneruje zprávu, která dorazí na zdrojové téma Kafka; 2) mikroslužba se sdíleným stavem (pomocí Kafka Streams) jej zpracuje a zapíše vypočítaný stav do finálního Kafkova tématu; načež 3) spotřebitelé přijmou nový stav

Hej, tento vestavěný obchod s páry klíč-hodnota je skutečně velmi užitečný!

Jak bylo uvedeno výše, naše topologie sdíleného stavu obsahuje úložiště párů klíč–hodnota. Našli jsme několik možností jeho použití a dvě z nich jsou popsány níže.

Možnost č. 1: Pro výpočty použijte úložiště párů klíč–hodnota

Naše první úložiště párů klíč–hodnota obsahovalo pomocná data, která jsme potřebovali pro výpočty. Například v některých případech byl sdílený stát určen principem „většinových hlasů“. Úložiště by mohlo obsahovat všechny nejnovější zprávy agentů o stavu nějakého objektu. Poté, když jsme od jednoho nebo druhého agenta obdrželi novou zprávu, mohli jsme ji uložit, načíst zprávy od všech ostatních agentů o stavu stejného objektu z úložiště a zopakovat výpočet.
Obrázek 4 níže ukazuje, jak jsme vystavili úložiště klíč/hodnota metodě zpracování procesoru, aby pak mohla být zpracována nová zpráva.

Nejen zpracování: Jak jsme vytvořili distribuovanou databázi z Kafka Streams a co z toho vzešlo

Obrázek 4: Otevřeme přístup k úložišti klíč-hodnota pro metodu zpracování procesoru (poté musí každý skript, který pracuje se sdíleným stavem, implementovat metodu doProcess)

Možnost č. 2: Vytvoření CRUD API nad Kafka Streams

Po vytvoření základního toku úloh jsme se začali pokoušet napsat RESTful CRUD API pro naše sdílené stavové mikroslužby. Chtěli jsme mít možnost načíst stav některých nebo všech objektů a také nastavit nebo odstranit stav objektu (užitečné pro podporu backendu).

Abychom podporovali všechna rozhraní Get State API, kdykoli jsme potřebovali přepočítat stav během zpracování, uložili jsme jej na dlouhou dobu do vestavěného úložiště klíč-hodnota. V tomto případě je docela jednoduché implementovat takové API pomocí jediné instance Kafka Streams, jak je uvedeno v seznamu níže:

Nejen zpracování: Jak jsme vytvořili distribuovanou databázi z Kafka Streams a co z toho vzešlo

Obrázek 5: Použití vestavěného úložiště klíč–hodnota k získání předem vypočítaného stavu objektu

Aktualizace stavu objektu přes API je také snadno implementovatelná. V podstatě vše, co musíte udělat, je vytvořit Kafkova producenta a použít jej k vytvoření desky, která obsahuje nový stav. Tím je zajištěno, že všechny zprávy generované prostřednictvím API budou zpracovány stejným způsobem jako zprávy přijaté od jiných výrobců (např. agentů).

Nejen zpracování: Jak jsme vytvořili distribuovanou databázi z Kafka Streams a co z toho vzešlo

Obrázek 6: Stav objektu můžete nastavit pomocí výrobce Kafka

Malá komplikace: Kafka má mnoho oddílů

Dále jsme chtěli rozložit zatížení zpracování a zlepšit dostupnost poskytnutím clusteru mikroslužeb ve sdíleném stavu pro každý scénář. Nastavení bylo hračkou: jakmile jsme nakonfigurovali všechny instance tak, aby běžely pod stejným ID aplikace (a stejnými bootstrap servery), téměř vše ostatní se provedlo automaticky. Také jsme určili, že každé zdrojové téma se bude skládat z několika oddílů, takže každé instanci lze přiřadit podmnožinu takových oddílů.

Ještě zmíním, že je běžnou praxí vytvořit záložní kopii státního úložiště, takže například v případě obnovy po selhání tuto kopii přenesete do jiné instance. Pro každý stav úložiště v Kafka Streams se vytvoří replikované téma s protokolem změn (který sleduje místní aktualizace). Kafka tak neustále zálohuje státní obchod. V případě selhání té či oné instance Kafka Streams lze tedy stavové úložiště rychle obnovit na jiné instanci, kam přejdou příslušné oddíly. Naše testy ukázaly, že je to hotovo během několika sekund, i když jsou v obchodě miliony záznamů.

Při přechodu z jedné mikroslužby se sdíleným stavem na shluk mikroslužeb je implementace rozhraní Get State API méně triviální. V nové situaci obsahuje stavové úložiště každé mikroslužby pouze část celkového obrazu (ty objekty, jejichž klíče byly namapovány na konkrétní oddíl). Museli jsme určit, která instance obsahuje stav objektu, který jsme potřebovali, a udělali jsme to na základě metadat vlákna, jak je uvedeno níže:

Nejen zpracování: Jak jsme vytvořili distribuovanou databázi z Kafka Streams a co z toho vzešlo

Obrázek 7: Pomocí metadat streamu určíme, ze které instance se dotazovat na stav požadovaného objektu; podobný přístup byl použit s GET ALL API

Klíčová zjištění

Státní obchody v Kafka Streams mohou sloužit jako de facto distribuovaná databáze,

  • neustále replikované v Kafkovi
  • CRUD API lze snadno vybudovat na vrcholu takového systému
  • Manipulace s více oddíly je trochu složitější
  • K topologii streamování je také možné přidat jedno nebo více stavových úložišť pro uložení pomocných dat. Tuto možnost lze použít pro:
  • Dlouhodobé uchovávání dat potřebných pro výpočty při zpracování proudu
  • Dlouhodobé ukládání dat, která mohou být užitečná při příštím zřízení instance streamování
  • mnohem více...

Díky těmto a dalším výhodám se Kafka Streams dobře hodí pro udržování globálního stavu v distribuovaném systému, jako je ten náš. Kafka Streams se ukázal jako velmi spolehlivý v produkci (od nasazení jsme nezaznamenali prakticky žádnou ztrátu zpráv) a jsme si jisti, že tím jeho schopnosti nekončí!

Zdroj: www.habr.com

Přidat komentář