{"id":37849,"date":"2019-10-31T22:20:09","date_gmt":"2019-10-31T19:20:09","guid":{"rendered":"https:\/\/prohoster.info\/blog\/kafka-i-mikroservisy-obzor\/"},"modified":"2019-10-31T22:20:09","modified_gmt":"2019-10-31T19:20:09","slug":"kafka-i-mikroservisy-obzor","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/kafka-i-mikroservisy-obzor","title":{"rendered":"Kafka i mikroserwisy: przegl\u0105d","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Kafka i mikroserwisy: przegl\u0105d\" src=\"\/wp-content\/uploads\/2019\/09\/ab0534ad5d28b3c3aa03e4e0b2d3101b.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Cze\u015b\u0107 wszystkim. W tym artykule opowiem, dlaczego dziewi\u0119\u0107 miesi\u0119cy temu w Avito wybrali\u015bmy Kafka i czym ona jest. Podziel\u0119 si\u0119 jednym z przypadk\u00f3w u\u017cycia \u2014 brokerem wiadomo\u015bci. Na koniec porozmawiamy o tym, jakie korzy\u015bci przynios\u0142o nam zastosowanie podej\u015bcia Kafka as a Service.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1 id=\"problema\">Problem<\/h1>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka i mikroserwisy: przegl\u0105d\" src=\"\/wp-content\/uploads\/2019\/09\/dfa5e231847cee67259da17867a11812.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Na pocz\u0105tek troch\u0119 kontekstu. Jaki\u015b czas temu zacz\u0119li\u015bmy odchodzi\u0107 od monolitycznej architektury i obecnie w Avito mamy ju\u017c kilka setek r\u00f3\u017cnych us\u0142ug. Maj\u0105 one swoje w\u0142asne bazy danych, swoje stosy technologiczne i odpowiadaj\u0105 za swoj\u0105 cz\u0119\u015b\u0107 logiki biznesowej. <\/p>\n<p><\/p>\n<p>Jednym z problem\u00f3w przy du\u017cej liczbie us\u0142ug s\u0105 komunikacje. Us\u0142uga A cz\u0119sto chce uzyska\u0107 informacj\u0119, kt\u00f3r\u0105 dysponuje us\u0142uga B. W takim przypadku us\u0142uga A zwraca si\u0119 do us\u0142ugi B za po\u015brednictwem synchronizowanego API. Us\u0142uga B chce wiedzie\u0107, co si\u0119 dzieje w us\u0142ugach G i D, a te z kolei interesuj\u0105 si\u0119 us\u0142ugami A i B. Gdy takich 'ciekawskich' us\u0142ug jest wiele, po\u0142\u0105czenia mi\u0119dzy nimi staj\u0105 si\u0119 spl\u0105tanym w\u0119z\u0142em.<\/p>\n<p><\/p>\n<p>W ka\u017cdej chwili us\u0142uga A mo\u017ce sta\u0107 si\u0119 niedost\u0119pna. Co w takim przypadku zrobi us\u0142uga B oraz wszystkie inne us\u0142ugi zale\u017cne od niej? A je\u015bli do wykonania operacji biznesowej konieczne jest wykonanie \u0142a\u0144cucha kolejnych synchronizowanych wywo\u0142a\u0144, prawdopodobie\u0144stwo awarii ca\u0142ej operacji staje si\u0119 jeszcze wy\u017csze (im d\u0142u\u017cszy jest ten \u0142a\u0144cuch, tym wy\u017csze to prawdopodobie\u0144stwo). <\/p>\n<p><\/p>\n<h1 id=\"vybor-tehnologii\">Wyb\u00f3r technologii<\/h1>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka i mikroserwisy: przegl\u0105d\" src=\"\/wp-content\/uploads\/2019\/09\/3acd7bcf3dded8093bdef6d627eb4071.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ok, problemy s\u0105 zrozumia\u0142e. Mo\u017cna je rozwi\u0105za\u0107, tworz\u0105c scentralizowany system wymiany wiadomo\u015bci mi\u0119dzy us\u0142ugami. Teraz ka\u017cda us\u0142uga musi zna\u0107 tylko ten system wymiany wiadomo\u015bci. Dodatkowo sam system musi by\u0107 odporny na awarie i skalowalny poziomo, a tak\u017ce w przypadku awarii gromadzi\u0107 w sobie bufor odwo\u0142a\u0144 do p\u00f3\u017aniejszego przetworzenia. <\/p>\n<p><\/p>\n<p>Teraz wybierzmy technologi\u0119, na kt\u00f3rej zostanie zrealizowana dostawa wiadomo\u015bci. Na pocz\u0105tku zrozummy, czego od niej oczekujemy:<\/p>\n<p><\/p>\n<ul>\n<li>wiadomo\u015bci mi\u0119dzy us\u0142ugami nie powinny by\u0107 tracone;<\/li>\n<li>wiadomo\u015bci mog\u0105 by\u0107 duplikowane;<\/li>\n<li>wiadomo\u015bci mo\u017cna przechowywa\u0107 i odczytywa\u0107 na g\u0142\u0119boko\u015b\u0107 kilku dni (bufor trwa\u0142y);<\/li>\n<li>us\u0142ugi mog\u0105 subskrybowa\u0107 interesuj\u0105ce je dane;<\/li>\n<li>kilka us\u0142ug mo\u017ce odczytywa\u0107 te same dane;<\/li>\n<li>wiadomo\u015bci mog\u0105 zawiera\u0107 szczeg\u00f3\u0142owy, obszerne payload (event-carried state transfer);<\/li>\n<li>czasami potrzebna jest gwarancja kolejno\u015bci wiadomo\u015bci.<\/li>\n<\/ul>\n<p><\/p>\n<p>R\u00f3wnie\u017c krytycznie wa\u017cne by\u0142o dla nas wybranie maksymalnie skalowalnego i niezawodnego systemu o wysokiej przepustowo\u015bci (nie mniej ni\u017c 100k wiadomo\u015bci na kilka kilobajt\u00f3w na sekund\u0119).<\/p>\n<p><\/p>\n<p>Na tym etapie po\u017cegnali\u015bmy si\u0119 z RabbitMQ (trudno utrzyma\u0107 stabilno\u015b\u0107 przy wysokich rps), PGQ od SkyTools (niewystarczaj\u0105co szybki i \u017ale skalowalny) oraz NSQ (niepersistentny). Wszystkie te technologie s\u0105 u\u017cywane w naszej firmie, ale do rozwi\u0105zywanego zadania nie by\u0142y odpowiednie. <\/p>\n<p><\/p>\n<p>Nast\u0119pnie zacz\u0119li\u015bmy przygl\u0105da\u0107 si\u0119 nowym dla nas technologiom \u2014 Apache Kafka, Apache Pulsar i NATS Streaming.<\/p>\n<p><\/p>\n<p>Najpierw odrzucili\u015bmy Pulsar. Stwierdzili\u015bmy, \u017ce Kafka i Pulsar to do\u015b\u0107 podobne rozwi\u0105zania. I mimo \u017ce Pulsar jest sprawdzony przez du\u017ce firmy, nowszy i teoretycznie oferuje ni\u017csze op\u00f3\u017anienia, postanowili\u015bmy pozostawi\u0107 Kafka jako de facto standard dla takich zada\u0144. Prawdopodobnie w przysz\u0142o\u015bci wr\u00f3cimy do Apache Pulsar. <\/p>\n<p><\/p>\n<p>Pozosta\u0142y wi\u0119c dwa kandydaci: NATS Streaming i Apache Kafka. Do\u015b\u0107 szczeg\u00f3\u0142owo zbadali\u015bmy oba rozwi\u0105zania i oba nadawa\u0142y si\u0119 do zadania. Ale ostatecznie obawiali\u015bmy si\u0119 wzgl\u0119dnej m\u0142odo\u015bci NATS Streaming (i tego, \u017ce jeden z g\u0142\u00f3wnych programist\u00f3w, Tyler Treat, zdecydowa\u0142 si\u0119 opu\u015bci\u0107 projekt i rozpocz\u0105\u0107 w\u0142asny \u2014 Liftbridge). W dodatku tryb klastrowania NATS Streaming nie pozwala\u0142 na silne poziome skalowanie (prawdopodobnie nie jest to ju\u017c problem po dodaniu trybu partycjonowania w 2017 roku).<\/p>\n<p><\/p>\n<p>Niemniej jednak, NATS Streaming to \u015bwietna technologia napisana w Go i wspierana przez Cloud Native Computing Foundation. W przeciwie\u0144stwie do Apache Kafka, nie potrzebuje Zookeepera do dzia\u0142ania (mo\u017cliwe, <noindex><a rel=\"nofollow\" href=\"https:\/\/cwiki.apache.org\/confluence\/display\/KAFKA\/KIP-500%3A+Replace+ZooKeeper+with+a+Self-Managed+Metadata+Quorum\">wkr\u00f3tce b\u0119dzie mo\u017cna powiedzie\u0107 to samo o Kafka<\/a><\/noindex>), poniewa\u017c wewn\u0119trznie implementuje RAFT. Ponadto, NATS Streaming jest prostszy w administracji. Nie wykluczamy, \u017ce w przysz\u0142o\u015bci wr\u00f3cimy do tej technologii. <\/p>\n<p><\/p>\n<p>Jednak na dzie\u0144 dzisiejszy naszym zwyci\u0119zc\u0105 zosta\u0142a Apache Kafka. W naszych testach wykaza\u0142a si\u0119 wystarczaj\u0105c\u0105 szybko\u015bci\u0105 (ponad milion wiadomo\u015bci na sekund\u0119 przy odczycie i zapisie o obj\u0119to\u015bci wiadomo\u015bci 1 kilobajt), wystarczaj\u0105c\u0105 niezawodno\u015bci\u0105, dobr\u0105 skalowalno\u015bci\u0105 i zosta\u0142a sprawdzona w produkcji przez du\u017ce firmy. Dodatkowo, Kafka wspiera przynajmniej kilka du\u017cych firm komercyjnych (my, na przyk\u0142ad, korzystamy z wersji Confluent), a tak\u017ce Kafka ma rozwini\u0119t\u0105 ekosystem.<br \/>\n<br clear=\"left\">\n <\/p>\n<p><\/p>\n<h1 id=\"obzor-kafka\">Przegl\u0105d Kafka<\/h1>\n<p><\/p>\n<p>Zanim zaczniemy, od razu polecam \u015bwietn\u0105 ksi\u0105\u017ck\u0119 \u2014 <em>\u201eKafka: The Definitive Guide\u201d<\/em> (jest tak\u017ce w rosyjskim t\u0142umaczeniu, ale terminy troch\u0119 \u0142ami\u0105 m\u00f3zg). Mo\u017cna w niej znale\u017a\u0107 informacje niezb\u0119dne do podstawowego zrozumienia Kafki, a nawet troch\u0119 wi\u0119cej. Sama dokumentacja od Apache i blog od Confluent s\u0105 r\u00f3wnie\u017c doskonale napisane i \u0142atwe do przeczytania. <\/p>\n<p><\/p>\n<p>Zatem przyjrzyjmy si\u0119, jak wygl\u0105da Kafka z lotu ptaka. Podstawowa topologia Kafki sk\u0142ada si\u0119 z producenta, konsumenta, brokera i zookeepra.<\/p>\n<p><\/p>\n<h3 id=\"broker\">Broker<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka i mikroserwisy: przegl\u0105d\" src=\"\/wp-content\/uploads\/2019\/09\/82f34b5a1aadcdc07eef58eb5414b553.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Za przechowywanie Twoich danych odpowiada broker (broker). Wszystkie dane s\u0105 przechowywane w formie binarnej, a broker ma ma\u0142o wiedzy na temat tego, czym one s\u0105 i jaka jest ich struktura. <\/p>\n<p><\/p>\n<p>Ka\u017cdy logiczny typ zdarze\u0144 zazwyczaj znajduje si\u0119 w osobnym temacie (topic). Na przyk\u0142ad zdarzenie utworzenia og\u0142oszenia mo\u017ce trafi\u0107 do tematu item.created, a zdarzenie jego zmiany \u2014 do item.changed. Tematy mo\u017cna traktowa\u0107 jako klasyfikatory zdarze\u0144. Na poziomie tematu mo\u017cna ustawi\u0107 takie parametry konfiguracyjne, jak: <\/p>\n<p><\/p>\n<ul>\n<li>obj\u0119to\u015b\u0107 przechowywanych danych i\/lub ich wiek (retention.bytes, retention.ms); <\/li>\n<li>wsp\u00f3\u0142czynnik redundancji danych (replication factor);<\/li>\n<li>maksymalny rozmiar jednego komunikatu (max.message.bytes);<\/li>\n<li>minimalna liczba zgodnych replik, przy kt\u00f3rej dane b\u0119d\u0105 mog\u0142y by\u0107 zapisane w temacie (min.insync.replicas);<\/li>\n<li>mo\u017cliwo\u015b\u0107 przeprowadzenia failover na niesynchronizowanej op\u00f3\u017anionej replicie z potencjaln\u0105 utrat\u0105 danych (unclean.leader.election.enable);<\/li>\n<li>i wiele innych (<noindex><a rel=\"nofollow\" href=\"https:\/\/kafka.apache.org\/documentation\/#topicconfigs\">https:\/\/kafka.apache.org\/documentation\/#topicconfigs<\/a><\/noindex>).<\/li>\n<\/ul>\n<p><\/p>\n<p>Z kolei ka\u017cdy temat dzieli si\u0119 na jedn\u0105 lub wi\u0119cej partycji (partition). To w\u0142a\u015bnie w partycjach ostatecznie trafiaj\u0105 zdarzenia. Je\u015bli w klastrze jest wi\u0119cej ni\u017c jeden broker, partycje b\u0119d\u0105 r\u00f3wnomiernie roz\u0142o\u017cone pomi\u0119dzy wszystkimi brokerami (na ile to mo\u017cliwe), co pozwoli na skalowanie obci\u0105\u017cenia zapisu i odczytu w jednym temacie na kilka broker\u00f3w.<\/p>\n<p><\/p>\n<p>Na dysku dane dla ka\u017cdej partycji przechowywane s\u0105 w formie plik\u00f3w segment\u00f3w, domy\u015blnie r\u00f3wnych jednemu gigabajtowi (kontrolowane przez log.segment.bytes). Wa\u017cn\u0105 cech\u0105 jest to, \u017ce usuwanie danych z partycji (po wyga\u015bni\u0119ciu retention) odbywa si\u0119 w\u0142a\u015bnie na poziomie segment\u00f3w (nie mo\u017cna usun\u0105\u0107 jednego zdarzenia z partycji, mo\u017cna usun\u0105\u0107 tylko ca\u0142y segment, przy czym tylko nieaktywny).<\/p>\n<p><\/p>\n<h3 id=\"zookeeper\">Zookeeper<\/h3>\n<p><\/p>\n<p>Zookeeper pe\u0142ni rol\u0119 magazynu metadanych i koordynatora. To on potrafi powiedzie\u0107, czy brokerzy s\u0105 aktywni (mo\u017cna to zobaczy\u0107 oczami zookeepra przez zookeeper-shell komend\u0105 <code>ls \/brokers\/ids<\/code>), kt\u00f3ry z broker\u00f3w jest kontrolerem (<code>get \/controller<\/code>), czy partycje s\u0105 w stanie synchronizacji ze swoimi replikami (<code>get \/brokers\/topics\/topic_name\/partitions\/partition_number\/state<\/code>). To w\u0142a\u015bnie do zookeepera najpierw udaj\u0105 si\u0119 producent i konsument, aby dowiedzie\u0107 si\u0119, na kt\u00f3rym brokerze jakie tematy i partycje s\u0105 przechowywane. W przypadkach, gdy dla tematu okre\u015blono wsp\u00f3\u0142czynnik replikacji wi\u0119kszy ni\u017c 1, zookeeper wska\u017ce, kt\u00f3re partycje s\u0105 liderami (to w nich b\u0119d\u0105 dokonywane zapisy, a stamt\u0105d r\u00f3wnie\u017c nast\u0105pi odczyt). W przypadku awarii brokera informacje o nowych liderach partycji b\u0119d\u0105 zapisane w zookeeperze (od wersji 1.1.0 asynchronicznie, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.confluent.io\/blog\/apache-kafka-supports-200k-partitions-per-cluster\">i to jest istotne<\/a><\/noindex>).<\/p>\n<p><\/p>\n<p>W starszych wersjach Kafka zookeeper odpowiada\u0142 r\u00f3wnie\u017c za przechowywanie offset\u00f3w, ale obecnie s\u0105 one przechowywane w specjalnym temacie <code>__consumer_offsets<\/code> na brokerze (cho\u0107 wci\u0105\u017c mo\u017cesz u\u017cywa\u0107 zookeepera do tych cel\u00f3w). <\/p>\n<p><\/p>\n<p>Najprostszym sposobem na przekszta\u0142cenie twoich danych w dyni\u0119 jest w\u0142a\u015bnie utrata informacji z zookeepera. W takim scenariuszu zrozumienie, co i sk\u0105d nale\u017cy odczyta\u0107, b\u0119dzie bardzo trudne. <\/p>\n<p><\/p>\n<h3 id=\"producer\">Producent<\/h3>\n<p><\/p>\n<p>Producent \u2014 to najcz\u0119\u015bciej us\u0142uga dokonuj\u0105ca bezpo\u015bredniego zapisu danych do Apache Kafka. Producent wybiera temat, w kt\u00f3rym b\u0119d\u0105 przechowywane jego wiadomo\u015bci, i zaczyna w nim zapisywa\u0107 informacje. Na przyk\u0142ad producentem mo\u017ce by\u0107 us\u0142uga og\u0142osze\u0144. W takim przypadku b\u0119dzie on wysy\u0142a\u0142 do tematycznych temat\u00f3w takie zdarzenia, jak \u201eog\u0142oszenie utworzone\u201d, \u201eog\u0142oszenie zaktualizowane\u201d, \u201eog\u0142oszenie usuni\u0119te\u201d itd. Ka\u017cde zdarzenie to para klucz-warto\u015b\u0107.<\/p>\n<p><\/p>\n<p>Domy\u015blnie wszystkie zdarzenia rozdzielane s\u0105 pomi\u0119dzy partycje tematu metod\u0105 round-robin, je\u015bli klucz nie jest okre\u015blony (trac\u0105c porz\u0105dek), oraz przez MurmurHash (klucz), je\u015bli klucz jest obecny (zachowuj\u0105c porz\u0105dek w ramach jednej partycji).<\/p>\n<p><\/p>\n<p>Tutaj od razu warto zauwa\u017cy\u0107, \u017ce Kafka gwarantuje porz\u0105dek zdarze\u0144 tylko w obr\u0119bie jednej partycji. Ale w rzeczywisto\u015bci cz\u0119sto nie jest to problemem. Na przyk\u0142ad mo\u017cna gwarantowa\u0107 dodawanie wszystkich zmian tego samego og\u0142oszenia do jednej partycji (w ten spos\u00f3b zachowuj\u0105c porz\u0105dek tych zmian w obr\u0119bie og\u0142oszenia). Mo\u017cna tak\u017ce przekaza\u0107 numer porz\u0105dkowy w jednym z p\u00f3l zdarzenia.<\/p>\n<p><\/p>\n<h3 id=\"consumer\">Consumer<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka i mikroserwisy: przegl\u0105d\" src=\"\/wp-content\/uploads\/2019\/09\/1f69a53dc19bb6c587883b8754cde29f.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Consumer odpowiada za odbieranie danych z Apache Kafka. Je\u015bli wr\u00f3ci\u0107 do powy\u017cszego przyk\u0142adu, consumerem mo\u017ce by\u0107 serwis moderacji. Ten serwis b\u0119dzie subskrybowa\u0107 temat serwisu og\u0142osze\u0144 i przy pojawieniu si\u0119 nowego og\u0142oszenia odbierze je oraz przeanalizuje pod k\u0105tem zgodno\u015bci z okre\u015blonymi politykami.<\/p>\n<p><\/p>\n<p>Apache Kafka zapami\u0119tuje, jakie by\u0142y ostatnie zdarzenia, kt\u00f3re odebra\u0142 consumer (do tego s\u0142u\u017cy serwisowy temat <code>__consumer__offsets<\/code>), co gwarantuje, \u017ce przy pomy\u015blnym odczycie consumer nie otrzyma tego samego komunikatu dwa razy. Niemniej jednak, je\u015bli u\u017cywa\u0107 opcji enable.auto.commit = true i ca\u0142kowicie powierzy\u0107 kontrolowanie pozycji consumer'a w temacie Kafce, mo\u017cna <noindex><a rel=\"nofollow\" href=\"https:\/\/blog.newrelic.com\/engineering\/kafka-consumer-config-auto-commit-data-loss\/\">straci\u0107 dane<\/a><\/noindex>. W kodzie produkcyjnym najcz\u0119\u015bciej kontrola pozycji consumer\u2019a odbywa si\u0119 r\u0119cznie (programista sam decyduje, kiedy musi nast\u0105pi\u0107 commit odczytanego zdarzenia).<\/p>\n<p><\/p>\n<p>W przypadkach, gdy jeden consumer nie wystarcza (na przyk\u0142ad, gdy strumie\u0144 nowych zdarze\u0144 jest bardzo du\u017cy), mo\u017cna doda\u0107 kilku dodatkowych consumer\u00f3w, \u0142\u0105cz\u0105c je w consumer group. Consumer group logicznie stanowi taki sam consumer, ale z rozdzielonymi danymi mi\u0119dzy uczestnikami grupy. Umo\u017cliwia to ka\u017cdemu z uczestnik\u00f3w wzi\u0119cie swojej cz\u0119\u015bci komunikat\u00f3w, co pozwala zwi\u0119kszy\u0107 szybko\u015b\u0107 odczytu. <\/p>\n<p><\/p>\n<h1 id=\"rezultaty-testirovaniya\">Wyniki testowania<\/h1>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka i mikroserwisy: przegl\u0105d\" src=\"\/wp-content\/uploads\/2019\/09\/f7abe4bcf34fdb0d762c8a928bd873ee.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tutaj nie b\u0119d\u0119 pisa\u0142 du\u017co wyja\u015bniaj\u0105cego tekstu, po prostu podziel\u0119 si\u0119 uzyskanymi wynikami. Testy by\u0142y przeprowadzane na 3 fizycznych maszynach (12 CPU, 384GB RAM, 15k SAS DISK, 10GBit\/s Net), brokerzy i zookeeper zostali uruchomieni w lxc. <\/p>\n<p><\/p>\n<p><strong>Testowanie wydajno\u015bci<\/strong><\/p>\n<p><\/p>\n<p>W trakcie test\u00f3w uzyskano nast\u0119puj\u0105ce wyniki.<\/p>\n<p><\/p>\n<ul>\n<li>Szybko\u015b\u0107 zapisu komunikat\u00f3w o rozmiarze 1KB jednocze\u015bnie przez 9 producer\u00f3w \u2013 1300000 zdarze\u0144 na sekund\u0119.<\/li>\n<li>Szybko\u015b\u0107 odczytu komunikat\u00f3w o rozmiarze 1KB jednocze\u015bnie przez 9 consumer\u00f3w \u2013 1500000 zdarze\u0144 na sekund\u0119.<\/li>\n<\/ul>\n<p><\/p>\n<p><strong>Testowanie odporno\u015bci na awarie<\/strong><\/p>\n<p><\/p>\n<p>W trakcie test\u00f3w uzyskano nast\u0119puj\u0105ce wyniki (3 brokerzy, 3 zookeepery).<\/p>\n<p><\/p>\n<ul>\n<li>Nieoczekiwane zako\u0144czenie pracy jednego z broker\u00f3w nie prowadzi do zatrzymania lub niedost\u0119pno\u015bci klastra. Praca trwa w normalnym trybie, ale na pozosta\u0142e brokerzy przypada wi\u0119ksze obci\u0105\u017cenie.<\/li>\n<li>Nieprawid\u0142owe zako\u0144czenie dw\u00f3ch broker\u00f3w w przypadku klastra sk\u0142adaj\u0105cego si\u0119 z trzech broker\u00f3w i min.isr = 2 prowadzi do braku dost\u0119pno\u015bci klastra do zapisu, ale dost\u0119pno\u015b\u0107 do odczytu pozostaje. W przypadku, gdy min.isr = 1, klaster nadal jest dost\u0119pny zar\u00f3wno do odczytu, jak i do zapisu. Niemniej jednak, ten tryb jest sprzeczny z wymaganiem wysokiej integralno\u015bci danych.<\/li>\n<li>Nieprawid\u0142owe zako\u0144czenie jednego z serwer\u00f3w Zookeeper nie prowadzi do zatrzymania ani braku dost\u0119pno\u015bci klastra. Praca trwa w trybie normalnym.<\/li>\n<li>Nieprawid\u0142owe zako\u0144czenie dw\u00f3ch serwer\u00f3w Zookeeper prowadzi do braku dost\u0119pno\u015bci klastra do momentu przywr\u00f3cenia dzia\u0142ania przynajmniej jednego z serwer\u00f3w Zookeeper. To stwierdzenie jest prawdziwe dla klastra Zookeeper z 3 serwerami. W wyniku bada\u0144 zdecydowano o zwi\u0119kszeniu klastra Zookeeper do 5 serwer\u00f3w w celu zwi\u0119kszenia odporno\u015bci na awarie. <br clear=\"left\">\n <\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"kafka-as-a-service\">Kafka jako us\u0142uga<\/h1>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka i mikroserwisy: przegl\u0105d\" src=\"\/wp-content\/uploads\/2019\/09\/19b2356131203cefbadfd90a25ae9674.png\" style=\"display:block;margin: 0 auto;\" \/> <\/p>\n<p><\/p>\n<p>Przekonali\u015bmy si\u0119, \u017ce Kafka to doskona\u0142a technologia, kt\u00f3ra pozwala nam rozwi\u0105za\u0107 postawione przed nami zadanie (implementacj\u0119 brokera wiadomo\u015bci). Niemniej jednak postanowili\u015bmy zabroni\u0107 us\u0142ugom bezpo\u015bredniego dost\u0119pu do Kafki i zamkn\u0119li\u015bmy j\u0105 z g\u00f3ry us\u0142ug\u0105 data-bus. Dlaczego to zrobili\u015bmy? W rzeczywisto\u015bci jest kilka powod\u00f3w.<\/p>\n<p><\/p>\n<ul>\n<li>\n<p>Data-bus przyj\u0105\u0142 na siebie wszystkie zadania zwi\u0105zane z integracj\u0105 z Kafk\u0105 (implementacja i konfiguracja konsument\u00f3w oraz producent\u00f3w, monitorowanie, alertowanie, logowanie, skalowanie itp.). Dzi\u0119ki temu integracja z brokerem wiadomo\u015bci odbywa si\u0119 w maksymalnie prosty spos\u00f3b. <\/p>\n<p>\n<\/li>\n<li>\n<p>Data-bus umo\u017cliwi\u0142 abstrahowanie od konkretnego j\u0119zyka czy biblioteki do pracy z Kafk\u0105. <\/p>\n<p>\n<\/li>\n<li>\n<p>Data-bus umo\u017cliwi\u0142 innym us\u0142ugom abstrahowanie od warstwy przechowywania. By\u0107 mo\u017ce w pewnym momencie zmienimy Kafk\u0119 na Pulsara, a nikt niczego nie zauwa\u017cy (wszystkie us\u0142ugi znaj\u0105 tylko API data-bus).<\/p>\n<p>\n<\/li>\n<li>\n<p>Data-bus przej\u0105\u0142 walidacj\u0119 schemat\u00f3w zdarze\u0144.<\/p>\n<p>\n<\/li>\n<li>\n<p>Za pomoc\u0105 data-bus zrealizowano autoryzacj\u0119.<\/p>\n<p>\n<\/li>\n<li>\n<p>Pod przykryciem data-bus mo\u017cemy bez przestoj\u00f3w, niezauwa\u017calnie aktualizowa\u0107 wersje Kafki, centralnie prowadzi\u0107 konfiguracje producent\u00f3w, konsument\u00f3w, broker\u00f3w itp.<\/p>\n<p>\n<\/li>\n<li>\n<p>Data-bus pozwoli\u0142 na dodanie nam potrzebnych funkcji, kt\u00f3re nie s\u0105 dost\u0119pne w Kafce (takich jak audyt temat\u00f3w, kontrola anomalii w klastrze, tworzenie DLQ itp.).<\/p>\n<p>\n<\/li>\n<li>\n<p>Data-bus umo\u017cliwia realizacj\u0119 failover centralnie dla wszystkich us\u0142ug.<\/p>\n<p>\n<\/li>\n<\/ul>\n<p><\/p>\n<p>Obecnie, aby rozpocz\u0105\u0107 wysy\u0142anie zdarze\u0144 do brokera wiadomo\u015bci, wystarczy pod\u0142\u0105czy\u0107 ma\u0142\u0105 bibliotek\u0119 w kodzie swojego serwisu. To wszystko. Zyskujesz mo\u017cliwo\u015b\u0107 pisania, odczytywania i skalowania za pomoc\u0105 jednej linii kodu. Ca\u0142a implementacja jest ukryta przed tob\u0105, na zewn\u0105trz wystaj\u0105 tylko kilka uchwyt\u00f3w typu rozmiar partii. Pod mask\u0105 serwis data-bus uruchamia w Kubernetes odpowiedni\u0105 liczb\u0119 instancji producer\u00f3w i konsument\u00f3w, i dostarcza im wymagan\u0105 konfiguracj\u0119, ale wszystko to jest przezroczyste dla twojego serwisu. <\/p>\n<p><\/p>\n<p>Oczywi\u015bcie, nie ma z\u0142otego \u015brodka, a takie podej\u015bcie ma swoje ograniczenia.<\/p>\n<p><\/p>\n<ul>\n<li>Data-bus trzeba utrzymywa\u0107 samodzielnie, w przeciwie\u0144stwie do zewn\u0119trznych bibliotek.<\/li>\n<li>Data-bus zwi\u0119ksza liczb\u0119 interakcji mi\u0119dzy serwisami a brokerem wiadomo\u015bci, co prowadzi do spadku wydajno\u015bci w por\u00f3wnaniu do surowej Kafki.<\/li>\n<li>Nie wszystko mo\u017cna tak \u0142atwo ukry\u0107 przed serwisami, nie chcemy duplikowa\u0107 funkcjonalno\u015bci KSQL lub Kafka Streams w data-bus, dlatego czasami musimy pozwoli\u0107 serwisom na bezpo\u015bredni dost\u0119p. <\/li>\n<\/ul>\n<p><\/p>\n<p>W naszym przypadku zalety przewy\u017cszy\u0142y wady i decyzja o ukryciu brokera wiadomo\u015bci za pomoc\u0105 osobnego serwisu okaza\u0142a si\u0119 uzasadniona. W ci\u0105gu roku u\u017cytkowania nie mieli\u015bmy \u017cadnych powa\u017cnych awarii ani problem\u00f3w.<\/p>\n<p><\/p>\n<p>P.S. Dzi\u0119kuj\u0119 mojej dziewczynie, Ekaterinie Obalaiewej, za \u015bwietne grafiki do tego artyku\u0142u. Je\u015bli si\u0119 wam spodoba\u0142y, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.instagram.com\/o.k_o.k_\/\">tutaj<\/a><\/noindex> znajd\u0105 si\u0119 jeszcze wi\u0119cej ilustracji.<\/p>\n<p>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/avito\/blog\/465315\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043f\u043e\u0447\u0435\u043c\u0443 \u043c\u044b \u0432 \u0410\u0432\u0438\u0442\u043e \u0434\u0435\u0432\u044f\u0442\u044c \u043c\u0435\u0441\u044f\u0446\u0435\u0432 \u043d\u0430\u0437\u0430\u0434 \u0432\u044b\u0431\u0440\u0430\u043b\u0438 Kafka, \u0438 \u0447\u0442\u043e \u043e\u043d\u0430 \u0438\u0437 \u0441\u0435\u0431\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442. \u041f\u043e\u0434\u0435\u043b\u044e\u0441\u044c \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u043a\u0435\u0439\u0441\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u2014 \u0431\u0440\u043e\u043a\u0435\u0440 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0418 \u043d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a\u0438\u0435 \u043f\u043b\u044e\u0441\u044b \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u0445\u043e\u0434\u0430 Kafka as a Service. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043c\u044b [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":28406,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-37849","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/kafka-i-mikroservisy-obzor\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47Kafka \u0438 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u044b: \u043e\u0431\u0437\u043e\u0440 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/kafka-i-mikroservisy-obzor\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:20:09+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:20:09+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Kafka i mikroserwisy: przegl\u0105d | ProHoster","description":"Witajcie wszyscy.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/kafka-i-mikroservisy-obzor","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47Kafka \u0438 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u044b: \u043e\u0431\u0437\u043e\u0440 | ProHoster","og:description":"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/kafka-i-mikroservisy-obzor","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:20:09+00:00","article:modified_time":"2019-10-31T19:20:09+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"37849","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-23 19:31:03","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:19:23","updated":"2026-01-23 19:31:03","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/37849","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=37849"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/37849\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/28406"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=37849"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=37849"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=37849"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}