Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafkinih tokova i što je iz toga proizašlo

Hej Habr!

Podsjećamo da nakon knjige o Kafka objavili smo jednako zanimljiv rad o knjižnici Kafka Streams API.

Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafkinih tokova i što je iz toga proizašlo

Za sada zajednica tek upoznaje granice ovog moćnog alata. Tako je nedavno izašao članak s čijim prijevodom vas želimo upoznati. Iz vlastitog iskustva autor govori kako Kafka Streamove pretvoriti u distribuiranu pohranu podataka. Uživaj čitajući!

Knjižnica Apache Kafkini potoci koristi se širom svijeta u poduzećima za distribuiranu obradu toka na vrhu Apache Kafke. Jedan od nedovoljno cijenjenih aspekata ovog okvira je taj što vam omogućuje pohranjivanje lokalnog stanja proizvedenog na temelju obrade niti.

U ovom članku ću vam reći kako je naša tvrtka uspjela isplativo iskoristiti ovu priliku pri razvoju proizvoda za sigurnost aplikacija u oblaku. Koristeći Kafka Streams, stvorili smo mikroservise dijeljenog stanja, od kojih svaki služi kao otporan na greške i visoko dostupan izvor pouzdanih informacija o stanju objekata u sustavu. Za nas je ovo korak naprijed u smislu pouzdanosti i jednostavnosti podrške.

Ako vas zanima alternativni pristup koji vam omogućuje korištenje jedinstvene središnje baze podataka za podršku formalnog stanja vaših objekata, pročitajte ga, bit će zanimljivo...

Zašto smo mislili da je vrijeme da promijenimo način na koji radimo sa dijeljenim stanjem

Trebali smo održavati stanje raznih objekata na temelju izvješća agenata (na primjer: je li stranica napadnuta)? Prije prelaska na Kafka Streams, često smo se oslanjali na jednu središnju bazu podataka (+ API usluge) za upravljanje stanjem. Ovaj pristup ima svoje nedostatke: datumi intenzivne situacije održavanje dosljednosti i sinkronizacije postaje pravi izazov. Baza podataka može postati usko grlo ili završiti u stanje utrke i pate od nepredvidljivosti.

Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafkinih tokova i što je iz toga proizašlo

Slika 1: Tipični scenarij podijeljenog stanja viđen prije prijelaza na
Kafka i Kafka Streams: agenti komuniciraju svoje stavove putem API-ja, ažurirano stanje izračunava se putem središnje baze podataka

Upoznajte Kafka Streamove koji olakšavaju stvaranje mikroservisa dijeljenog stanja

Prije otprilike godinu dana odlučili smo pažljivo proučiti naše scenarije zajedničkog stanja kako bismo riješili te probleme. Odmah smo odlučili isprobati Kafka Streams - znamo koliko je skalabilan, visoko dostupan i tolerantan na pogreške te koliko je bogata njegova streaming funkcionalnost (transformacije, uključujući one sa stanjem). Upravo ono što nam je trebalo, a da ne spominjemo koliko je sustav razmjene poruka postao zreo i pouzdan u Kafki.

Svaka mikrousluga s praćenjem stanja koju smo stvorili izgrađena je na instanci Kafka Streams s prilično jednostavnom topologijom. Sastojao se od 1) izvora 2) procesora s trajnom pohranom ključeva i vrijednosti 3) odvodnika:

Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafkinih tokova i što je iz toga proizašlo

Slika 2: Zadana topologija naših instanci strujanja za mikroservise s praćenjem stanja. Imajte na umu da ovdje postoji i repozitorij koji sadrži metapodatke o planiranju.

U ovom novom pristupu, agenti sastavljaju poruke koje se ubacuju u izvornu temu, a potrošači—recimo, usluga obavijesti e-poštom—primaju izračunato dijeljeno stanje putem odvodnika (izlazna tema).

Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafkinih tokova i što je iz toga proizašlo

Slika 3: Novi primjer tijeka zadatka za scenarij s dijeljenim mikrouslugama: 1) agent generira poruku koja stiže u izvornu temu Kafka; 2) mikroservis s dijeljenim stanjem (koristeći Kafka Streams) obrađuje ga i upisuje izračunato stanje u konačnu Kafka temu; nakon čega 3) potrošači prihvaćaju novo stanje

Hej, ova ugrađena pohrana ključeva i vrijednosti zapravo je vrlo korisna!

Kao što je gore spomenuto, naša dijeljena topologija stanja sadrži pohranu ključ-vrijednost. Pronašli smo nekoliko opcija za korištenje, a dvije su opisane u nastavku.

Opcija #1: Koristite pohranu ključ-vrijednost za izračune

Naša prva pohrana ključ-vrijednosti sadržavala je pomoćne podatke koji su nam bili potrebni za izračune. Na primjer, u nekim je slučajevima zajedničko stanje određivano po načelu "većine glasova". Repozitorij bi mogao sadržavati sva najnovija izvješća agenta o statusu nekog objekta. Zatim, kad smo primili novo izvješće od jednog ili drugog agenta, mogli smo ga spremiti, dohvatiti izvješća od svih ostalih agenata o stanju istog objekta iz pohrane i ponoviti izračun.
Slika 4 u nastavku prikazuje kako smo izložili pohranu ključa/vrijednosti procesorovoj metodi obrade tako da se nova poruka može obraditi.

Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafkinih tokova i što je iz toga proizašlo

Ilustracija 4: Otvaramo pristup pohrani ključeva i vrijednosti za metodu obrade procesora (nakon toga svaka skripta koja radi s dijeljenim stanjem mora implementirati metodu doProcess)

Opcija #2: Stvaranje CRUD API-ja povrh Kafka Streams

Nakon što smo uspostavili osnovni tijek zadataka, počeli smo pokušavati napisati RESTful CRUD API za naše mikroservise dijeljenog stanja. Htjeli smo moći dohvatiti stanje nekih ili svih objekata, kao i postaviti ili ukloniti stanje objekta (korisno za pozadinsku podršku).

Kako bismo podržali sve API-je Get State, kad god smo trebali ponovno izračunati stanje tijekom obrade, pohranili smo ga u ugrađenu pohranu ključ-vrijednost na duže vrijeme. U ovom slučaju, postaje vrlo jednostavno implementirati takav API koristeći jednu instancu Kafka Streams, kao što je prikazano u popisu ispod:

Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafkinih tokova i što je iz toga proizašlo

Slika 5: Korištenje ugrađene memorije ključ-vrijednost za dobivanje unaprijed izračunatog stanja objekta

Ažuriranje stanja objekta putem API-ja također je jednostavno implementirati. Uglavnom, sve što trebate učiniti je stvoriti Kafka producenta i koristiti ga za izradu zapisa koji sadrži novo stanje. To osigurava da će sve poruke generirane putem API-ja biti obrađene na isti način kao i one primljene od drugih proizvođača (npr. agenata).

Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafkinih tokova i što je iz toga proizašlo

Slika 6: Možete postaviti stanje objekta pomoću Kafka producenta

Mala komplikacija: Kafka ima mnogo pregrada

Zatim smo željeli rasporediti opterećenje obrade i poboljšati dostupnost pružanjem klastera mikroservisa dijeljenog stanja po scenariju. Postavljanje je bilo jednostavno: nakon što smo konfigurirali sve instance za rad pod istim ID-om aplikacije (i istim poslužiteljima za pokretanje), gotovo sve ostalo je učinjeno automatski. Također smo specificirali da će se svaka izvorna tema sastojati od nekoliko particija, tako da se svakoj instanci može dodijeliti podskup takvih particija.

Također ću spomenuti da je uobičajena praksa napraviti sigurnosnu kopiju državne pohrane tako da, na primjer, u slučaju oporavka nakon kvara, tu kopiju prenesete na drugu instancu. Za svaku državnu pohranu u Kafka Streams kreira se replicirana tema s zapisnikom promjena (koji prati lokalna ažuriranja). Tako Kafka stalno podupire državnu trgovinu. Stoga, u slučaju kvara jedne ili druge instance Kafka Streams, pohrana stanja može se brzo vratiti na drugu instancu, gdje će ići odgovarajuće particije. Naši testovi su pokazali da se to radi u nekoliko sekundi, čak i ako postoje milijuni zapisa u trgovini.

Prelaskom s jednog mikroservisa s dijeljenim stanjem na klaster mikroservisa, postaje manje trivijalno implementirati Get State API. U novoj situaciji, pohrana stanja svake mikroservise sadrži samo dio ukupne slike (one objekte čiji su ključevi mapirani na određenu particiju). Morali smo odrediti koja instanca sadrži stanje objekta koji nam je potreban, a to smo učinili na temelju metapodataka niti, kao što je prikazano u nastavku:

Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafkinih tokova i što je iz toga proizašlo

Slika 7: Korištenjem metapodataka toka, određujemo iz koje instance postaviti upit o stanju željenog objekta; sličan pristup korišten je s API-jem GET ALL

Glavni nalazi

Državne trgovine u Kafkinim potocima mogu poslužiti kao de facto distribuirana baza podataka,

  • stalno preslikava kod Kafke
  • CRUD API se lako može izgraditi na vrhu takvog sustava
  • Rukovanje višestrukim particijama malo je kompliciranije
  • Također je moguće dodati jedno ili više pohranjivanja stanja topologiji strujanja za pohranjivanje pomoćnih podataka. Ova se opcija može koristiti za:
  • Dugoročna pohrana podataka potrebnih za izračune tijekom obrade toka
  • Dugoročna pohrana podataka koji mogu biti korisni sljedeći put kada se instanca strujanja omogući
  • mnogo više...

Ove i druge prednosti čine Kafka Streams prikladnim za održavanje globalnog stanja u distribuiranom sustavu poput našeg. Kafka Streams se pokazao vrlo pouzdanim u proizvodnji (praktički nismo imali gubitak poruka otkad smo ga postavili) i uvjereni smo da njegove mogućnosti neće tu stati!

Izvor: www.habr.com

Dodajte komentar