Kafka dhe mikroshërbimet: një përmbledhje

Kafka dhe mikroshërbimet: një përmbledhje

TĂ« gjithĂ« pĂ«rshĂ«ndetje. NĂ« kĂ«tĂ« artikull do tĂ« flas pĂ«r arsyet qĂ« ne nĂ« Avito zgjodhĂ«m Kafka gjashtĂ« muaj mĂ« parĂ«, dhe se çfarĂ« pĂ«rfaqĂ«son ajo. Do tĂ« ndaj me ju njĂ« nga rastet e pĂ«rdorimit — broker mesazhesh. Dhe nĂ« fund, do tĂ« flasim pĂ«r pĂ«rfitimet qĂ« kemi marrĂ« nga pĂ«rdorimi i qasjes Kafka si ShĂ«rbim.

Problemi

Kafka dhe mikroshërbimet: një përmbledhje

Fillimisht, pak kontekst. Disa kohë më parë filluam të largohemi nga arkitektura monolite, dhe tani në Avito kemi disa qindra shërbime të ndryshme. Ato kanë magazinat e tyre, kupolën e teknologjive dhe përgjigjen për pjesën e tyre të logjikës së biznesit.

NjĂ« nga problemet me numrin e madh tĂ« shĂ«rbimeve Ă«shtĂ« komunikimi. ShĂ«rbimi A shpesh dĂ«shiron tĂ« dijĂ« informacionin qĂ« disponon shĂ«rbimi B. NĂ« kĂ«tĂ« rast, shĂ«rbimi A i drejtohet shĂ«rbimit B pĂ«rmes njĂ« API tĂ« sinkronizuar. ShĂ«rbimi B dĂ«shiron tĂ« dijĂ« çfarĂ« po ndodh tek shĂ«rbimet G dhe D, ndĂ«rsa ato, pĂ«r nga ana e tyre, janĂ« tĂ« interesuara pĂ«r shĂ«rbimet A dhe B. Kur numri i kĂ«tyre shĂ«rbimeve “kurioze” rritet, lidhjet midis tyre kthehen nĂ« njĂ« gjumĂ« tĂ« ngatĂ«rruar.

MegjithatĂ«, nĂ« çdo moment, shĂ«rbimi A mund tĂ« bĂ«het i paaksesueshĂ«m. ÇfarĂ« duhet tĂ« bĂ«jĂ« shĂ«rbimi B dhe tĂ« gjithĂ« shĂ«rbimet e tjera tĂ« lidhura me tĂ« nĂ« kĂ«tĂ« rast? NĂ«se pĂ«r tĂ« kryer njĂ« operacion biznesi Ă«shtĂ« e nevojshme tĂ« kryhen njĂ« grup thirrjesh sinkronike radhazi, probabiliteti i dĂ«shtimit tĂ« gjithĂ« operacionit bĂ«het edhe mĂ« i lartĂ« (dhe sa mĂ« e gjatĂ« tĂ« jetĂ« kjo rrjedhĂ«).

Zgjedhja e teknologjisë

Kafka dhe mikroshërbimet: një përmbledhje

Ok, problemet janë të qarta. Ato mund të zgjidhen duke krijuar një sistem të centralizuar të shkëmbimit të mesazheve ndërmjet shërbimeve. Tani, çdo shërbim duhet të dijë vetëm për këtë sistem shkëmbimi mesazhesh. Përveç kësaj, vetë sistemi duhet të jetë rezistent ndaj dështimeve dhe të zgjerueshëm horizontalisht, si dhe në rast emergjencash duhet të ruajë një bufer thirrjesh për përpunim të mëvonshëm.

Tani le të zgjedhim teknologjinë në të cilën do të realizohet dërgimi i mesazheve. Për këtë, së pari do të kuptojmë se çfarë presim nga ajo:

  • mesazhet ndĂ«rmjet shĂ«rbimeve nuk duhet tĂ« humbasin;
  • mesazhet mund tĂ« dublikohen;
  • mesazhet mund tĂ« ruhen dhe tĂ« lexohet pĂ«r disa ditĂ« (bufferi persistent);
  • shĂ«rbimet mund tĂ« regjistrohen pĂ«r tĂ« dhĂ«nat qĂ« i interesojnĂ«;
  • disa shĂ«rbime mund tĂ« lexojnĂ« tĂ« njĂ«jtat tĂ« dhĂ«na;
  • mesazhet mund tĂ« pĂ«rmbajnĂ« njĂ« payload tĂ« detajuar dhe voluminoz (transferim tĂ« gjendjes nga ngjarjet);
  • ndonjĂ«herĂ« nevojitet njĂ« garanci pĂ«r rendin e mesazheve.

Gjithashtu, na rëndësishme ishte të zgjidhnim një sistem sa më të shkallëzueshëm dhe të besueshëm me një kapacitet të lartë kalimi (jo më pak se 100k mesazhe disa kilobajt në sekondë).

Në këtë fazë, ne u ndamë me RabbitMQ (vështirë për ta mbajtur stabil në rps të larta), PGQ nga SkyTools (nuk është mjaft i shpejtë dhe i shkallëzueshëm) dhe NSQ (nuk është i qëndrueshëm). Të gjitha këto teknologji përdoren në kompaninë tonë, por nuk i përshtaten detyrës që po zgjidhim.

Pastaj filluam tĂ« shqyrtojmĂ« teknologjitĂ« e reja pĂ«r ne — Apache Kafka, Apache Pulsar dhe NATS Streaming.

I pari që e eliminuam ishte Pulsar. Vendosëm se Kafka dhe Pulsar janë zgjidhje të ngjashme. Dhe pavarësisht se Pulsar ka qenë i provuar nga kompanitë e mëdha, më i ri dhe ofron latencë më të ulët (në teori), vendosëm nga këto dy të mbajmë Kafka, si standard de facto për këto detyra. Probabilisht do të kthehemi te Apache Pulsar në të ardhmen.

Dhe ja mbeten dy kandidatĂ«: NATS Streaming dhe Apache Kafka. Ne i studiuam tĂ« dy zgjidhjet nĂ« mĂ«nyrĂ« tĂ« detajuar, dhe tĂ« dy u pĂ«rshtatĂ«n pĂ«r detyrĂ«n. Por nĂ« fund, kishim frikĂ« nga rinia relative e NATS Streaming (dhe nga vendimi i njĂ« nga zhvilluesve kryesorĂ«, Tyler Treat, pĂ«r tĂ« lĂ«nĂ« projektin dhe pĂ«r tĂ« filluar tĂ« tijin — Liftbridge). MegjithatĂ«, moda Clustering e NATS Streaming nuk ofronte mundĂ«si pĂ«r horizontal tĂ« fortĂ« tĂ« shkallĂ«zimit (ndoshta kjo nuk Ă«shtĂ« mĂ« njĂ« problem pas shtimit tĂ« modĂ«s sĂ« ndarjes nĂ« vitin 2017).

Megjithatë, NATS Streaming është një teknologji e shkëlqyer, e shkruar në Go dhe ka mbështetje nga Cloud Native Computing Foundation. Në krahasim me Apache Kafka, nuk i nevojitet Zookeeper për të funksionuar (ndoshta, shpejt mund të thuhet e njëjta gjë për Kafka), pasi brenda saj implementon RAFT. Në të njëjtën kohë, NATS Streaming është më e lehtë në administrim. Ne nuk përjashtojmë që më vonë të kthehemi përsëri në këtë teknologji.

Dhe megjithatë, deri më sot fituesi ynë është Apache Kafka. Në testet tona, ajo ka treguar një performancë mjaft të shpejtë (mbi një milion mesazhe në sekondë për lexim dhe shk writing kur volumi i mesazheve është 1 kilobajt), mjaft të besueshme, të shkallëzueshme dhe e provuar mbi bazën e përvojës në prodhim nga kompanitë e mëdha. Përveç kësaj, Kafka mbështetet nga të paktën disa kompani të rëndësishme tregtare (ne, për shembull, përdorim versionin Confluent), dhe gjithashtu Kafka ka një ekosistem të zhvilluar.

Përmbledhja e Kafka

Para se tĂ« fillojmĂ«, po rekomandoj njĂ« libĂ«r tĂ« shkĂ«lqyer — «Kafka: UdhĂ«zuesi pĂ«rfundimtar» (ushqimet janĂ« edhe nĂ« pĂ«rkthim nĂ« rusisht, por termat paksa tĂ« thyejnĂ« tru). Aty mund tĂ« gjeni informacionin e nevojshĂ«m pĂ«r njĂ« kuptim themelor tĂ« Kafka-s dhe edhe mĂ« shumĂ«. Dokumentacioni nga Apache dhe blogu nga Confluent gjithashtu janĂ« shkruar shkĂ«lqyer dhe lehtĂ« pĂ«r t'u lexuar.

Tani, le të shohim se si është strukturuar Kafka nga një këndvështrim i lartë. Topologjia bazë e Kafka-s përbëhet nga producer, consumer, broker dhe zookeeper.

Broker

Kafka dhe mikroshërbimet: një përmbledhje

Brokera (broker) është përgjegjëse për ruajtjen e të dhënave tuaja. Të gjitha të dhënat ruhen në formë binare, dhe brokeri di pak për atë që ato përfaqësojnë dhe cilat janë strukturat e tyre.

Çdo lloj logjik i ngjarjeve zakonisht ndodhet nĂ« temĂ«n e tij tĂ« veçantĂ« (topic). PĂ«r shembull, ngjarja e krijimit tĂ« njĂ« njoftimi mund tĂ« pĂ«rfshihet nĂ« temĂ«n item.created, ndĂ«rsa ngjarja e ndryshimit tĂ« tij nĂ« item.changed. Temat mund tĂ« konsiderohen si klasifikues tĂ« ngjarjeve. NĂ« nivelin e temĂ«s mund tĂ« vendosen parametrat e tillĂ« konfigurimi si:

  • vĂ«llimi i tĂ« dhĂ«nave tĂ« ruajtura dhe/ose mosha e tyre (retention.bytes, retention.ms);
  • fakti i tepĂ«rt i tĂ« dhĂ«nave (replication factor);
  • madhĂ«sia maksimale e njĂ« mesazhi (max.message.bytes);
  • numri minimal i replikave tĂ« miratuara, me tĂ« cilat mund tĂ« shkruhet nĂ« temĂ« (min.insync.replicas);
  • mundĂ«sia e kalimit nĂ« njĂ« replikĂ« tĂ« pasifikuar tĂ« pa sinkronizuar me humbje tĂ« mundshme tĂ« tĂ« dhĂ«nave (unclean.leader.election.enable);
  • dhe shumĂ« tĂ« tjera (https://kafka.apache.org/documentation/#topicconfigs).

Nga ana tjetër, çdo temë ndahet në një ose më shumë pjesë (partition). Në pjesën e fundit, ngjarjet përfundojnë. Nëse në kluster ka më shumë se një broker, atëherë pjesët do të shpërndahen njësoj në të gjithë brokerët (sa më shumë të jetë e mundur), duke lejuar që ngarkesa e shkrimit dhe leximin në një temë të shkarkohet menjëherë në disa brokerë.

Të dhënat në disk ruhet për çdo parti në formën e skedarëve segmentesh, të cilët nga default janë një gigabajt (kontrollohet përmes log.segment.bytes). Një veçori e rëndësishme është se fshirja e të dhënave nga partitë (kur ndodh ruajtja) ndodh pikërisht në segmentet (nuk mund të fshihet një ngjarje e vetme nga partia, vetëm një segment i tërë, për më tepër vetëm ai i pasivizuar).

Zookeeper

Zookeeper funksionon si një depo e metadatalogjisë dhe si koordinator. Ai është i aftë të tregojë nëse brokerët janë aktivë (mund të shikoni këtë nga këndvështrimi i zookeeper përmes komandes ls /brokers/ids), cili prej brokerëve është kontrollues (get /controller), nëse partitë janë në gjendje sinkronike me replikat e tyre (get /brokers/topics/topic_name/partitions/partition_number/state). Gjithashtu, fillimisht producentes dhe konsumatorët do të drejtohen te zookeeper për të mësuar se cili broker ka cilat tema dhe parte. Në rastet kur për temën është caktuar një faktor replikimi më i madh se 1, zookeeper do të tregojë se cilat pjesë janë liderë (në to do të bëhet shkruajti dhe edhe leximi). Në rastin e rënies së një brokeri, informacioni për lider-pjesët e reja do të regjistrohet pikërisht në zookeeper (që nga versioni 1.1.0 në mënyrë asinkrone, dhe kjo është e rëndësishme.).

Në versionet më të vjetra të Kafka, zookeeper-i merrte përsipër edhe ruajtjen e offset-ëve, por tani ato ruhen në një temë të veçantë. __consumer_offsets në broker (megjithatë ju mund të vazhdoni ta përdorni zookeeper për këto qëllime).

Mënyra më e thjeshtë për ta kthyer të dhënat tuaja në një nivel më të ulët është humbja e informacionit nga zookeeper. Në skenarin e tillë, do të jetë shumë e vështirë të kuptohet se çfarë dhe nga ku duhet lexuar.

Prodhues

Prodhuesi — Ă«shtĂ« mĂ« sĂ« shpeshti njĂ« shĂ«rbim qĂ« kryen regjistrimin e tĂ« dhĂ«nave direkt nĂ« Apache Kafka. Prodhuesi zgjedh temĂ«n ku do tĂ« ruhen mesazhet e tij tematike dhe fillon tĂ« regjistrojĂ« informacion nĂ« tĂ«. PĂ«r shembull, njĂ« prodhues mund tĂ« jetĂ« njĂ« shĂ«rbim shpalljesh. NĂ« atĂ« rast, ai do tĂ« dĂ«rgojĂ« nĂ« tematike ngjarje si "shpallje e krijuar", "shpallje e azhurnuar", "shpallje e fshirĂ«" etj. Çdo ngjarje pĂ«rbĂ«n njĂ« çift çelĂ«s-vlerĂ«.

Për default, të gjitha ngjarjet shpërndahen nëpër parti të temës me round-robin nëse çelësi nuk është caktuar (duke humbur renditjen), dhe përmes MurmurHash (çelësi) nëse çelësi është i pranishëm (renditje brenda një partie).

Këtu do të theksojmë se Kafka garanton rendin e ngjarjeve vetëm brenda një partie. Por në të vërtetë, shpesh kjo nuk është një problem. Për shembull, mund të sigurohet që të gjitha ndryshimet e një njoftimi të caktuar të shtohen në një parti (duke ruajtur kështu rendin e këtyre ndryshimeve në kuadër të njoftimit). Po ashtu, mund të kaloni numrin rendor në një prej fushave të ngjarjes.

Consumer

Kafka dhe mikroshërbimet: një përmbledhje

Konsumatori është përgjegjës për marrjen e të dhënave nga Apache Kafka. Nëse kthehemi te shembulli më sipër, konsumatori mund të jetë shërbimi i moderimit. Ky shërbim do të abonohë në temën e shërbimit të njoftimeve, dhe në momentin që shfaqet një njoftim i ri do ta marrë atë dhe do ta analizojë për përputhshmërinë me disa politika të caktuara.

Apache Kafka mban mend se cilat ishin ngjarjet e fundit që mori konsumatori (për këtë përdoret tema e shërbimit __consumer__offsets), duke garantuar kështu që gjatë leximit të suksesshëm konsumatori nuk do të marrë të njëjtin mesazh dy herë. Megjithatë, nëse përdoret opsioni enable.auto.commit = true dhe plotësisht t'i dorëzohet Kafka detyra e ndjekjes së pozicionit të konsumatorit në temë, mund të humbasim të dhëna. Në kodin e prodhimit, zakonisht pozita e konsumatorit kontrollohet manualisht (zhvilluesi menaxhon momentin kur është e detyrueshme që të ndodhi komitimi i ngjarjes së lexuar).

Në rastet kur një konsumator nuk mjafton (për shembull, fluksi i ngjarjeve të reja është shumë i madh), mund të shtoni disa konsumatorë të tjerë, duke i lidhur ata në një grup konsumatorësh. Grupi i konsumatorëve paraqet logjikisht një konsumator të tillë, por me shpërndarjen e të dhënave midis pjesëtarëve të grupit. Kjo i lejon secilit nga pjesëtarët të marrë pjesën e tij të mesazheve, duke e përshpejtuar kështu shpejtësinë e leximit.

Rezultatet e testimit

Kafka dhe mikroshërbimet: një përmbledhje

Këtu nuk do të shkruaj shumë tekste shpjeguese, thjesht do të ndaj rezultatet e marra. Testimi u krye në 3 makina fizike (12 CPU, 384GB RAM, 15k SAS DISK, 10GBit/s Net), brokerët dhe zookeeper ishin vendosur në lxc.

Testimi i performancës

Gjatë testimit u arritën rezultatet e mëposhtme.

  • ShpejtĂ«sia e shkruarjes sĂ« mesazheve me madhĂ«si 1KB nga 9 prodhues nĂ« tĂ« njĂ«jtĂ«n kohĂ« — 1,300,000 ngjarje nĂ« sekondĂ«.
  • ShpejtĂ«sia e leximit tĂ« mesazheve me madhĂ«si 1KB nga 9 konsumatorĂ« nĂ« tĂ« njĂ«jtĂ«n kohĂ« — 1,500,000 ngjarje nĂ« sekondĂ«.

Testimi i qëndrueshmërisë

Gjatë testimit u arritën rezultatet e mëposhtme (3 brokerë, 3 zookeeper).

  • Mbyllja e njĂ« nga brokerĂ«t nuk çon nĂ« ndalimin ose papastĂ«rtinĂ« e klasterit. Funksionimi vazhdon normalisht, por mbi brokerĂ«t e mbetur bie njĂ« ngarkesĂ« mĂ« e madhe.
  • Mbyllja e dy brokerĂ«ve nĂ« rastin e njĂ« klasteri me tre brokerĂ« dhe min.isr = 2 çon nĂ« papastĂ«rtinĂ« e klasterit pĂ«r shkrim, por mbetet i aksesueshĂ«m pĂ«r lexim. NĂ« rast se min.isr = 1, klasteri vazhdon tĂ« jetĂ« i aksesueshĂ«m si pĂ«r lexim ashtu edhe pĂ«r shkrim. MegjithatĂ«, ky mod ka tĂ« bĂ«jĂ« me njĂ« kĂ«rkesĂ« pĂ«r njĂ« ruajtje tĂ« lartĂ« tĂ« tĂ« dhĂ«nave.
  • Mbyllja e njĂ« nga serverĂ«ve Zookeeper nuk çon nĂ« ndalimin ose papastĂ«rtinĂ« e klasterit. Funksionimi vazhdon normalisht.
  • Mbyllja e dy serverĂ«ve Zookeeper çon nĂ« papastĂ«rtinĂ« e klasterit deri sa tĂ« rikthehet funksionimi i tĂ« paktĂ«n njĂ« nga serverĂ«t Zookeeper. Ky pohim Ă«shtĂ« i vĂ«rtetĂ« pĂ«r klasterin Zookeeper me 3 serverĂ«. Si rezultat i hulumtimeve, u vendos tĂ« rritet klasteri Zookeeper nĂ« 5 serverĂ« pĂ«r tĂ« rritur qĂ«ndrueshmĂ«rinĂ« ndaj shpĂ«rthimeve.

Kafka si shërbim

Kafka dhe mikroshërbimet: një përmbledhje

Kemi siguruar që Kafka është një teknologji e shkëlqyer që na lejon të zgjidhim detyrën që na është caktuar (implementimi i një brokeri mesazhesh). Megjithatë, vendosëm të ndalojmë shërbimet të qasen direkt tek Kafka dhe e mbyllëm atë me shërbimin data-bus. Pse e bëmë këtë? Në të vërtetë, ka disa arsye.

  • Data-bus mori pĂ«rsipĂ«r tĂ« gjitha detyrat e lidhura me integrimin me Kafka (implementimin dhe konfigurimin e konsumatorĂ«ve dhe prodhuesve, monitorimin, alarmin, regjistrimin, shkallĂ«zimin etj.). KĂ«shtu, integrimi me brokerin e mesazheve ndodh sa mĂ« thjeshtĂ« tĂ« jetĂ« e mundur.

  • Data-bus na lejon tĂ« abstraktojmĂ« nga gjuha ose biblioteka specifike pĂ«r punĂ«n me Kafka.

  • Data-bus u lejon shĂ«rbimeve tĂ« tjera tĂ« abstrahojnĂ« nga shtresa e ruajtjes. ndoshta, nĂ« njĂ« moment, do ta zĂ«vendĂ«sojmĂ« Kafka me Pulsar, dhe askush nuk do ta vĂ«rĂ« re (tĂ« gjitha shĂ«rbimet dinĂ« vetĂ«m pĂ«r API-nĂ« e data-bus).

  • Data-bus e mori pĂ«rsipĂ«r validimin e skemave tĂ« ngjarjeve.

  • Me ndihmĂ«n e data-bus Ă«shtĂ« realizuar autentifikimi.

  • NĂ«n mbulesĂ«n e data-bus mund tĂ« pĂ«rditsojmĂ« versionet e Kafka pa ndonjĂ« kohĂ« pushimi, nĂ« mĂ«nyrĂ« tĂ« padukshme, dhe tĂ« menaxhojmĂ« centralisht konfigurimet e prodhuesve, konsumatorĂ«ve, brokerĂ«ve etj.

  • Data-bus na ka lejon pĂ«r tĂ« shtuar tiparet qĂ« na nevojiten, tĂ« cilat mungojnĂ« nĂ« Kafka (siç janĂ« auditi i temave, kontrolli pĂ«r anomali nĂ« klaster, krijimi i DLQ, etj.).

  • Data-bus lejon tĂ« realizohet failover nĂ« mĂ«nyrĂ« qendrore pĂ«r tĂ« gjitha shĂ«rbimet.

Aktualisht, për të filluar dërgimin e ngjarjeve në brokerin e mesazheve, mjafton të lidhësh një bibliotekë të vogël në kodin e shërbimit tënd. Kjo është e gjitha. Të jep mundësinë të shkruash, lexosh dhe shkallëzosh me një rresht kodi. E tëra realizimi është e fshehur nga ju, jashtë dalin vetëm disa doreza siç është përmasa e grupit. Nën kapak, shërbimi data-bus ngre në Kubernetes numrin e nevojshëm të instance-ve të prodhuesve dhe konsumerëve dhe u jep atyre konfigurimin e duhur, por e gjithë kjo është transparente për shërbimin tuaj.

Sigurisht, nuk ka një plumb argjendi, dhe ky qasje ka kufizimet e veta.

  • Data-bus duhet tĂ« mbĂ«shtetet nga forcat tuaja, ndryshe nga bibliotekat e jashtme.
  • Data-bus rrit numrin e ndĂ«rveprimeve midis shĂ«rbimeve dhe brokerit tĂ« mesazheve, çka çon nĂ« njĂ« rĂ«nie tĂ« performancĂ«s krahasuar me Kafka-n e pastĂ«r.
  • Jo vetĂ«m se mund tĂ« fshihen nga shĂ«rbimet, ne nuk duam tĂ« kopjojmĂ« funksionalitetin e KSQL ose Kafka Streams nĂ« data-bus, kĂ«shtu qĂ« ndonjĂ«herĂ« duhet tĂ« lejojmĂ« shĂ«rbimet tĂ« kalojnĂ« nĂ« mĂ«nyrĂ« tĂ« drejtpĂ«rdrejtĂ«.

Në rastin tonë, avantazhet përfunduan se ishin më shumë se disavantazhet, dhe zgjidhja për të mbuluar brokerin e mesazheve me një shërbim të veçantë rezultoi e drejtë. Gjatë një viti përdorimi, nuk kemi pasur ndonjë aksident serioz apo probleme.

P.S. Falenderoj të dashurën time, Ekaterina Obalayeva, për imazhet fantastike të kësaj artikulli. Nëse ju pëlqen, këtu do të ketë edhe më shumë ilustarime.

Burimi: habr.com

Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster