Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafka Streams-a i šta je od toga proizašlo

Hej Habr!

Podsjećamo da prateći knjigu o Kafka objavili smo jednako zanimljiv rad o biblioteci Kafka Streams API.

Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafka Streams-a i šta je od toga proizašlo

Za sada, zajednica tek uči granice ovog moćnog alata. Dakle, nedavno je objavljen članak s čijim prijevodom želimo da vas upoznamo. Iz vlastitog iskustva, autor govori kako Kafka Streams pretvoriti u distribuirano skladište podataka. Uživajte u čitanju!

Apache biblioteka Kafka Streams koristi se širom svijeta u preduzećima za distribuiranu obradu toka na vrhu Apache Kafke. Jedan od nedovoljno cijenjenih aspekata ovog okvira je to što vam omogućava pohranjivanje lokalnog stanja proizvedenog na osnovu obrade niti.

U ovom članku ću vam reći kako je naša kompanija uspjela profitabilno iskoristiti ovu priliku prilikom razvoja proizvoda za sigurnost aplikacija u oblaku. Koristeći Kafka Streams, kreirali smo dijeljene mikroservise stanja, od kojih svaki služi kao otporan na greške i visoko dostupan izvor pouzdanih informacija o stanju objekata u sistemu. Za nas je ovo korak naprijed iu smislu pouzdanosti i lakoće podrške.

Ako ste zainteresovani za alternativni pristup koji vam omogućava da koristite jednu centralnu bazu podataka za podršku formalnog stanja vaših objekata, pročitajte je, biće zanimljivo...

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

Trebali smo održavati stanje različitih objekata na osnovu izvještaja agenata (na primjer: je li lokacija bila napadnuta)? Prije migracije na Kafka Streams, često smo se oslanjali na jedinstvenu centralnu bazu podataka (+ servisni API) za upravljanje stanjem. Ovaj pristup ima svoje nedostatke: izlazite u intenzivnim situacijama održavanje konzistentnosti i sinhronizacije postaje pravi izazov. Baza podataka može postati usko grlo ili završiti u njoj trkačko stanje i pate od nepredvidljivosti.

Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafka Streams-a i šta je od toga proizašlo

Slika 1: Tipičan scenarij podijeljenog stanja viđen prije prelaska na
Kafka i Kafka tokovi: agenti komuniciraju svoje stavove putem API-ja, ažurirano stanje se izračunava preko centralne baze podataka

Upoznajte Kafka Streams, što olakšava kreiranje mikroservisa dijeljenih stanja

Prije otprilike godinu dana odlučili smo da pažljivo pogledamo naše zajedničke scenarije stanja kako bismo riješili ova pitanja. Odmah smo odlučili isprobati Kafka Streams - znamo koliko je skalabilan, visoko dostupan i tolerantan na greške, kakvu bogatu streaming funkcionalnost ima (transformacije, uključujući i one sa stanjem). Baš ono što nam je trebalo, a da ne spominjemo koliko je zreo i pouzdan sistem za razmenu poruka u Kafki.

Svaki od mikroservisa sa stanjem koje smo kreirali izgrađen je na vrhu Kafka Streams instance sa prilično jednostavnom topologijom. Sastojao se od 1) izvora 2) procesora sa stalnim skladištem ključ/vrijednost 3) sinkronizacije:

Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafka Streams-a i šta je od toga proizašlo

Slika 2: Podrazumevana topologija naših streaming instanci za mikroservise sa statusom. Imajte na umu da ovdje također postoji spremište koje sadrži metapodatke o planiranju.

U ovom novom pristupu, agenti sastavljaju poruke koje se unose u izvornu temu, a potrošači – recimo, usluga za obavještavanje putem pošte – primaju izračunato zajedničko stanje kroz sinkronizaciju (izlazna tema).

Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafka Streams-a i šta je od toga proizašlo

Slika 3: Novi primjer toka zadatka za scenario sa zajedničkim mikroservisima: 1) agent generiše poruku koja stiže na izvornu temu Kafke; 2) mikroservis sa zajedničkim stanjem (koristeći Kafka Streams) ga obrađuje i upisuje izračunato stanje u završnu Kafka temu; nakon čega 3) potrošači prihvataju novo stanje

Hej, ovo ugrađeno skladište ključ-vrijednost je zapravo vrlo korisno!

Kao što je gore spomenuto, naša topologija dijeljenog stanja sadrži skladište ključ/vrijednost. Pronašli smo nekoliko opcija za njegovo korištenje, a dvije od njih su opisane u nastavku.

Opcija #1: Koristite skladište ključ/vrijednost za izračune

Naše prvo skladište ključ/vrijednost sadržavalo je pomoćne podatke koji su nam bili potrebni za proračune. Na primjer, u nekim slučajevima zajednička država je određena principom "većine glasova". Repozitorijum može sadržati sve najnovije izveštaje agenta o statusu nekog objekta. Zatim, kada smo primili novi izvještaj od jednog ili drugog agenta, mogli smo ga sačuvati, preuzeti izvještaje svih ostalih agenata o stanju istog objekta iz skladišta i ponoviti proračun.
Slika 4 ispod pokazuje kako smo izložili skladište ključ/vrijednost procesorskom metodu obrade kako bi se nova poruka potom mogla obraditi.

Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafka Streams-a i šta je od toga proizašlo

Ilustracija 4: Otvaramo pristup spremištu ključ/vrijednost za metodu obrade procesora (nakon toga, svaka skripta koja radi sa zajedničkim stanjem mora implementirati metodu doProcess)

Opcija #2: Kreiranje CRUD API-ja na vrhu Kafka Stream-a

Nakon što smo uspostavili naš osnovni tok zadataka, počeli smo da pokušavamo da napišemo RESTful CRUD API za naše mikroservise deljenog stanja. Htjeli smo biti u mogućnosti da dohvatimo stanje nekih ili svih objekata, kao i da postavimo ili uklonimo stanje objekta (korisno za podršku u pozadini).

Kako bismo podržali sve API-je Get State, kad god smo trebali ponovo izračunati stanje tokom obrade, pohranili smo ga u ugrađenu ključ/vrijednost spremište na duže vrijeme. U ovom slučaju, postaje prilično jednostavno implementirati takav API koristeći jednu instancu Kafka Stream-a, kao što je prikazano na listi ispod:

Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafka Streams-a i šta je od toga proizašlo

Slika 5: Upotreba ugrađenog skladišta ključ/vrijednost za dobivanje unaprijed izračunatog stanja objekta

Ažuriranje stanja objekta putem API-ja je također lako implementirati. U suštini, sve što treba da uradite je da kreirate Kafka producenta i da ga upotrebite da napravite zapis koji sadrži novo stanje. Ovo osigurava da će sve poruke generirane preko API-ja biti obrađene na isti način kao one primljene od drugih proizvođača (npr. agenata).

Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafka Streams-a i šta je od toga proizašlo

Slika 6: Možete postaviti stanje objekta pomoću Kafka proizvođača

Mala komplikacija: Kafka ima mnogo particija

Zatim smo željeli distribuirati opterećenje obrade i poboljšati dostupnost pružanjem klastera mikroservisa dijeljenog stanja po scenariju. Postavljanje je bilo lako: kada smo konfigurisali sve instance da se pokreću pod istim ID-om aplikacije (i istim bootstrap serverima), gotovo sve ostalo je urađeno automatski. Također smo naveli da će se svaka izvorna tema sastojati od nekoliko particija, tako da se svakoj instanci može dodijeliti podskup takvih particija.

Spomenut ću i da je uobičajena praksa napraviti sigurnosnu kopiju državne trgovine kako bi, na primjer, u slučaju oporavka nakon kvara, ovu kopiju prenijeli na drugu instancu. Za svaku državnu prodavnicu u Kafka Streams-u kreira se replicirana tema s dnevnikom promjena (koji prati lokalna ažuriranja). Dakle, Kafka stalno podržava državnu trgovinu. Stoga, u slučaju kvara jedne ili druge Kafka Streams instance, skladište 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 za nekoliko sekundi, čak i ako postoje milioni zapisa u prodavnici.

Prelaskom sa jedne mikrousluge sa zajedničkim stanjem na klaster mikroservisa, postaje manje trivijalno implementirati Get State API. U novoj situaciji, skladište stanja svakog mikroservisa 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 bio potreban, i to smo uradili na osnovu metapodataka niti, kao što je prikazano u nastavku:

Ne samo obrada: Kako smo napravili distribuiranu bazu podataka od Kafka Streams-a i šta je od toga proizašlo

Slika 7: Koristeći metapodatke toka, određujemo iz koje instance da upitamo stanje željenog objekta; sličan pristup je korišten sa GET ALL API-jem

Glavni nalazi

Državne prodavnice u Kafka Streams-u mogu poslužiti kao de facto distribuirana baza podataka,

  • stalno replicirano u Kafki
  • CRUD API se lako može izgraditi na vrhu takvog sistema
  • Rukovanje s više particija je malo složenije
  • Također je moguće dodati jedno ili više skladišta stanja u topologiju strujanja za pohranjivanje pomoćnih podataka. Ova opcija se može koristiti za:
  • Dugotrajno skladištenje podataka potrebnih za proračune tokom obrade toka
  • Dugotrajna pohrana podataka koja može biti korisna sljedeći put kada se instanca za striming omogući
  • mnogo više...

Ove i druge prednosti čine Kafka Streams pogodnim za održavanje globalnog stanja u distribuiranom sistemu poput našeg. Kafka Streams se pokazao vrlo pouzdanim u proizvodnji (nemamo gotovo nikakvih gubitaka poruka otkako smo ga implementirali), i uvjereni smo da se njegove mogućnosti neće tu zaustaviti!

izvor: www.habr.com

Dodajte komentar