{"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\/pt\/blog\/administrirovanie\/kafka-i-mikroservisy-obzor","title":{"rendered":"Kafka e microservi\u00e7os: uma vis\u00e3o geral","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Kafka e microservi\u00e7os: uma vis\u00e3o geral\" src=\"\/wp-content\/uploads\/2019\/09\/ab0534ad5d28b3c3aa03e4e0b2d3101b.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ol\u00e1 a todos. Neste artigo, vou explicar por que escolhemos o Kafka na Avito h\u00e1 nove meses e o que ele realmente \u00e9. Vou compartilhar um dos casos de uso \u2014 um corretor de mensagens. E, por \u00faltimo, falaremos sobre os benef\u00edcios que obtivemos com a abordagem Kafka as a Service.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1 id=\"problema\">O problema<\/h1>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka e microservi\u00e7os: uma vis\u00e3o geral\" src=\"\/wp-content\/uploads\/2019\/09\/dfa5e231847cee67259da17867a11812.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Para come\u00e7ar, um pouco de contexto. H\u00e1 algum tempo, come\u00e7amos a nos distanciar da arquitetura monol\u00edtica, e agora na Avito j\u00e1 temos v\u00e1rias centenas de servi\u00e7os diferentes. Cada um possui seu pr\u00f3prio armazenamento, sua pr\u00f3pria stack de tecnologias e \u00e9 respons\u00e1vel por uma parte da l\u00f3gica de neg\u00f3cios. <\/p>\n<p><\/p>\n<p>Um dos problemas com um grande n\u00famero de servi\u00e7os \u00e9 a comunica\u00e7\u00e3o. O servi\u00e7o A frequentemente deseja saber informa\u00e7\u00f5es que o servi\u00e7o B possui. Nesse caso, o servi\u00e7o A se comunica com o servi\u00e7o B atrav\u00e9s de uma API s\u00edncrona. O servi\u00e7o C quer saber o que acontece com os servi\u00e7os D e E, enquanto E e D, por sua vez, est\u00e3o interessados nos servi\u00e7os A e B. Quando h\u00e1 muitos servi\u00e7os 'curiosos', as conex\u00f5es entre eles se tornam um emaranhado complexo.<\/p>\n<p><\/p>\n<p>Al\u00e9m disso, a qualquer momento, o servi\u00e7o A pode ficar indispon\u00edvel. E o que fazer nesse caso com o servi\u00e7o B e todos os outros servi\u00e7os que dependem dele? E se para executar uma opera\u00e7\u00e3o comercial for necess\u00e1rio realizar uma cadeia de chamadas s\u00edncronas consecutivas, a probabilidade de falha de toda a opera\u00e7\u00e3o aumenta ainda mais (e maior \u00e9 essa probabilidade quanto mais longa for a cadeia). <\/p>\n<p><\/p>\n<h1 id=\"vybor-tehnologii\">Escolha da tecnologia<\/h1>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka e microservi\u00e7os: uma vis\u00e3o geral\" src=\"\/wp-content\/uploads\/2019\/09\/3acd7bcf3dded8093bdef6d627eb4071.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ok, os problemas est\u00e3o claros. Podemos resolv\u00ea-los criando um sistema centralizado de troca de mensagens entre os servi\u00e7os. Agora, cada um dos servi\u00e7os s\u00f3 precisa saber sobre esse sistema de troca de mensagens. Al\u00e9m disso, o pr\u00f3prio sistema deve ser tolerante a falhas e escal\u00e1vel horizontalmente, e, em caso de falha, deve acumular um buffer de chamadas para tratamento posterior. <\/p>\n<p><\/p>\n<p>Agora vamos escolher a tecnologia na qual a entrega de mensagens ser\u00e1 implementada. Para isso, primeiro vamos entender o que esperamos dela:<\/p>\n<p><\/p>\n<ul>\n<li>as mensagens entre os servi\u00e7os n\u00e3o devem ser perdidas;<\/li>\n<li>as mensagens podem ser duplicadas;<\/li>\n<li>as mensagens podem ser armazenadas e lidas com uma profundidade de v\u00e1rios dias (buffer persistente);<\/li>\n<li>os servi\u00e7os podem se inscrever em dados que lhes interessam;<\/li>\n<li>v\u00e1rios servi\u00e7os podem ler os mesmos dados;<\/li>\n<li>as mensagens podem conter um payload detalhado e volumoso (transfer\u00eancia de estado carregada por evento);<\/li>\n<li>\u00e0s vezes \u00e9 necess\u00e1ria a garantia da ordem das mensagens.<\/li>\n<\/ul>\n<p><\/p>\n<p>Al\u00e9m disso, era crucial para n\u00f3s escolher um sistema o mais escal\u00e1vel e confi\u00e1vel poss\u00edvel, com alta capacidade de processamento (pelo menos 100 mil mensagens de v\u00e1rios kilobytes por segundo).<\/p>\n<p><\/p>\n<p>Nesta fase, nos despediu do RabbitMQ (dif\u00edcil de manter est\u00e1vel em altas taxas de RPS), PGQ do SkyTools (n\u00e3o r\u00e1pido o suficiente e mal escal\u00e1vel) e NSQ (n\u00e3o persistente). Todas essas tecnologias s\u00e3o utilizadas em nossa empresa, mas n\u00e3o se adequavam \u00e0 tarefa em quest\u00e3o. <\/p>\n<p><\/p>\n<p>Em seguida, come\u00e7amos a olhar para novas tecnologias para n\u00f3s \u2014 Apache Kafka, Apache Pulsar e NATS Streaming.<\/p>\n<p><\/p>\n<p>Resolvemos descartar o Pulsar primeiro. Decidimos que Kafka e Pulsar s\u00e3o solu\u00e7\u00f5es bastante semelhantes. E embora o Pulsar tenha sido testado por grandes empresas, seja mais novo e ofere\u00e7a menor lat\u00eancia (em teoria), optamos por manter o Kafka como padr\u00e3o de fato para essas tarefas. \u00c9 prov\u00e1vel que voltemos ao Apache Pulsar no futuro. <\/p>\n<p><\/p>\n<p>E assim restaram dois candidatos: NATS Streaming e Apache Kafka. Estudamos ambos os sistemas detalhadamente, e ambos se adequavam \u00e0 tarefa. Mas, no final, tememos a relativa juventude do NATS Streaming (e o fato de que um dos principais desenvolvedores, Tyler Treat, decidiu deixar o projeto e iniciar o seu pr\u00f3prio \u2014 Liftbridge). Ao mesmo tempo, o modo de Cluster do NATS Streaming n\u00e3o oferecia grande escalabilidade horizontal (provavelmente, isso j\u00e1 n\u00e3o \u00e9 um problema ap\u00f3s a adi\u00e7\u00e3o do modo de particionamento em 2017).<\/p>\n<p><\/p>\n<p>No entanto, o NATS Streaming \u00e9 uma tecnologia incr\u00edvel, escrita em Go e com suporte da Cloud Native Computing Foundation. Ao contr\u00e1rio do Apache Kafka, ele n\u00e3o precisa do Zookeeper para funcionar (possivelmente, <noindex><a rel=\"nofollow\" href=\"https:\/\/cwiki.apache.org\/confluence\/display\/KAFKA\/KIP-500%3A+Replace+ZooKeeper+with+a+Self-Managed+Metadata+Quorum\">em breve poderemos dizer o mesmo sobre o Kafka<\/a><\/noindex>), uma vez que implementa RAFT internamente. Al\u00e9m disso, o NATS Streaming \u00e9 mais f\u00e1cil de administrar. N\u00e3o descartamos que, no futuro, possamos voltar a essa tecnologia. <\/p>\n<p><\/p>\n<p>Ainda assim, at\u00e9 hoje, nosso vencedor foi o Apache Kafka. Em nossos testes, ele se mostrou bastante r\u00e1pido (mais de um milh\u00e3o de mensagens por segundo tanto para leitura quanto para escrita com mensagens de 1 kilobyte), bastante confi\u00e1vel, bem escal\u00e1vel e testado na pr\u00e1tica por grandes empresas. Al\u00e9m disso, o Kafka \u00e9 suportado por pelo menos v\u00e1rias grandes empresas comerciais (n\u00f3s, por exemplo, usamos a vers\u00e3o da Confluent), e tamb\u00e9m possui um ecossistema robusto.<br \/>\n<br clear=\"left\">\n <\/p>\n<p><\/p>\n<h1 id=\"obzor-kafka\">Vis\u00e3o geral do Kafka<\/h1>\n<p><\/p>\n<p>Antes de come\u00e7ar, recomendo imediatamente um excelente livro \u2014 <em>\u00abKafka: The Definitive Guide\u00bb<\/em> (existe tamb\u00e9m na tradu\u00e7\u00e3o em russo, mas os termos podem ser um pouco confusos). Nele, voc\u00ea pode encontrar informa\u00e7\u00f5es necess\u00e1rias para uma compreens\u00e3o b\u00e1sica do Kafka e at\u00e9 um pouco mais. A pr\u00f3pria documenta\u00e7\u00e3o da Apache e o blog da Confluent tamb\u00e9m s\u00e3o bem escritos e f\u00e1ceis de ler. <\/p>\n<p><\/p>\n<p>Ent\u00e3o, vamos dar uma olhada em como o Kafka \u00e9 estruturado de uma perspectiva geral. A topologia b\u00e1sica do Kafka consiste em produtor, consumidor, corretor e zookeeper.<\/p>\n<p><\/p>\n<h3 id=\"broker\">Corretor<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka e microservi\u00e7os: uma vis\u00e3o geral\" src=\"\/wp-content\/uploads\/2019\/09\/82f34b5a1aadcdc07eef58eb5414b553.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>O corretor (broker) \u00e9 respons\u00e1vel pelo armazenamento dos seus dados. Todos os dados s\u00e3o armazenados em formato bin\u00e1rio, e o corretor pouco sabe sobre o que eles representam e qual \u00e9 sua estrutura. <\/p>\n<p><\/p>\n<p>Cada tipo l\u00f3gico de evento geralmente est\u00e1 em seu pr\u00f3prio t\u00f3pico (topic). Por exemplo, um evento de cria\u00e7\u00e3o de an\u00fancio pode ir para o t\u00f3pico item.created, enquanto um evento de altera\u00e7\u00e3o vai para item.changed. Os t\u00f3picos podem ser vistos como classificadores de eventos. No n\u00edvel do t\u00f3pico, \u00e9 poss\u00edvel definir par\u00e2metros de configura\u00e7\u00e3o como: <\/p>\n<p><\/p>\n<ul>\n<li>volume de dados armazenados e\/ou sua idade (retention.bytes, retention.ms); <\/li>\n<li>fator de redund\u00e2ncia de dados (replication factor);<\/li>\n<li>tamanho m\u00e1ximo de uma mensagem (max.message.bytes);<\/li>\n<li>n\u00famero m\u00ednimo de r\u00e9plicas em sincronia necess\u00e1rias para que dados possam ser escritos no t\u00f3pico (min.insync.replicas);<\/li>\n<li>possibilidade de fazer failover para uma r\u00e9plica desatualizada, com potencial perda de dados (unclean.leader.election.enable);<\/li>\n<li>e muitos outros (<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>Por sua vez, cada t\u00f3pico \u00e9 dividido em uma ou mais parti\u00e7\u00f5es (partition). \u00c9 nas parti\u00e7\u00f5es que os eventos acabam sendo armazenados. Se houver mais de um corretor no cluster, as parti\u00e7\u00f5es ser\u00e3o distribu\u00eddas uniformemente entre todos os corretores (na medida do poss\u00edvel), o que permite escalonar a carga de grava\u00e7\u00e3o e leitura de um \u00fanico t\u00f3pico em v\u00e1rios corretores ao mesmo tempo.<\/p>\n<p><\/p>\n<p>No disco, os dados de cada parti\u00e7\u00e3o s\u00e3o armazenados como arquivos de segmentos, que por padr\u00e3o t\u00eam um gigabyte (controlado atrav\u00e9s de log.segment.bytes). Uma caracter\u00edstica importante \u00e9 que a remo\u00e7\u00e3o de dados das parti\u00e7\u00f5es (quando a reten\u00e7\u00e3o \u00e9 acionada) acontece em segmentos (n\u00e3o \u00e9 poss\u00edvel remover um \u00fanico evento de uma parti\u00e7\u00e3o, apenas um segmento inteiro, e somente se estiver inativo).<\/p>\n<p><\/p>\n<h3 id=\"zookeeper\">Zookeeper<\/h3>\n<p><\/p>\n<p>O Zookeeper atua como um reposit\u00f3rio de metadados e coordenador. Ele \u00e9 capaz de dizer se os corretores est\u00e3o ativos (isso pode ser visto atrav\u00e9s do Zookeeper com o comando <code>ls \/brokers\/ids<\/code>), qual dos corretores \u00e9 o controlador (<code>get \/controller<\/code>), est\u00e3o as parti\u00e7\u00f5es em estado de sincronia com suas r\u00e9plicas (<code>get \/brokers\/topics\/topic_name\/partitions\/partition_number\/state<\/code>). Tamb\u00e9m, at\u00e9 mesmo o zookeeper inicialmente receber\u00e1 o produtor e o consumidor, para descobrir em qual corretora est\u00e3o armazenados quais t\u00f3picos e parti\u00e7\u00f5es. Nos casos em que o fator de replica\u00e7\u00e3o para o t\u00f3pico \u00e9 maior que 1, o zookeeper indicar\u00e1 quais parti\u00e7\u00f5es s\u00e3o l\u00edderes (nelas ocorrer\u00e1 a grava\u00e7\u00e3o e delas a leitura). Caso uma corretora falhe, as informa\u00e7\u00f5es sobre novos l\u00edderes de parti\u00e7\u00f5es ser\u00e3o registradas no zookeeper (a partir da vers\u00e3o 1.1.0 de forma ass\u00edncrona, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.confluent.io\/blog\/apache-kafka-supports-200k-partitions-per-cluster\">e isso \u00e9 importante<\/a><\/noindex>).<\/p>\n<p><\/p>\n<p>Em vers\u00f5es mais antigas do Kafka, o zookeeper tamb\u00e9m era respons\u00e1vel pelo armazenamento de offsets, mas agora eles s\u00e3o armazenados em um t\u00f3pico especial <code>__consumer_offsets<\/code> na corretora (embora voc\u00ea ainda possa usar o zookeeper para esses fins). <\/p>\n<p><\/p>\n<p>A maneira mais simples de transformar seus dados em ab\u00f3bora \u00e9 exatamente a perda de informa\u00e7\u00f5es com o zookeeper. Nesse cen\u00e1rio, entender o que e de onde precisa ser lido ser\u00e1 muito dif\u00edcil. <\/p>\n<p><\/p>\n<h3 id=\"producer\">Producer<\/h3>\n<p><\/p>\n<p>O produtor \u2014 geralmente \u00e9 um servi\u00e7o que grava diretamente dados no Apache Kafka. O produtor escolhe o t\u00f3pico onde suas mensagens tem\u00e1ticas ser\u00e3o armazenadas e come\u00e7a a gravar informa\u00e7\u00f5es nele. Por exemplo, o produtor pode ser um servi\u00e7o de an\u00fancios. Nesse caso, ele enviar\u00e1 para os t\u00f3picos tem\u00e1ticos eventos como \"an\u00fancio criado\", \"an\u00fancio atualizado\", \"an\u00fancio removido\", etc. Cada evento, portanto, representa um par chave-valor.<\/p>\n<p><\/p>\n<p>Por padr\u00e3o, todos os eventos s\u00e3o distribu\u00eddos entre as parti\u00e7\u00f5es do t\u00f3pico em round-robin, se a chave n\u00e3o for especificada (perdendo a ordena\u00e7\u00e3o), e atrav\u00e9s do MurmurHash (chave), se a chave estiver presente (manuten\u00e7\u00e3o da ordena\u00e7\u00e3o dentro de uma parti\u00e7\u00e3o).<\/p>\n<p><\/p>\n<p>Aqui \u00e9 importante observar que o Kafka garante a ordem dos eventos apenas dentro de uma parti\u00e7\u00e3o. Mas, na verdade, isso muitas vezes n\u00e3o \u00e9 um problema. Por exemplo, pode-se garantir que todas as altera\u00e7\u00f5es de um mesmo an\u00fancio sejam adicionadas a uma parti\u00e7\u00e3o (mantendo assim a ordem dessas altera\u00e7\u00f5es dentro do an\u00fancio). Tamb\u00e9m \u00e9 poss\u00edvel transmitir um n\u00famero sequencial em um dos campos do evento.<\/p>\n<p><\/p>\n<h3 id=\"consumer\">Consumer<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka e microservi\u00e7os: uma vis\u00e3o geral\" src=\"\/wp-content\/uploads\/2019\/09\/1f69a53dc19bb6c587883b8754cde29f.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>O consumidor \u00e9 respons\u00e1vel por receber dados do Apache Kafka. Se voltarmos ao exemplo acima, o consumidor pode ser um servi\u00e7o de modera\u00e7\u00e3o. Este servi\u00e7o ficar\u00e1 inscrito no t\u00f3pico do servi\u00e7o de an\u00fancios e, quando um novo an\u00fancio aparecer, receber\u00e1 e analisar\u00e1 em conformidade com algumas pol\u00edticas definidas.<\/p>\n<p><\/p>\n<p>O Apache Kafka lembra quais s\u00e3o os \u00faltimos eventos recebidos pelo consumidor (para isso, utiliza-se um t\u00f3pico de servi\u00e7o <code>__consumer__offsets<\/code>), garantindo assim que, ap\u00f3s uma leitura bem-sucedida, o consumidor n\u00e3o receba a mesma mensagem duas vezes. No entanto, se voc\u00ea usar a op\u00e7\u00e3o enable.auto.commit = true e deixar completamente a responsabilidade do rastreamento da posi\u00e7\u00e3o do consumidor no t\u00f3pico para o Kafka, pode-se <noindex><a rel=\"nofollow\" href=\"https:\/\/blog.newrelic.com\/engineering\/kafka-consumer-config-auto-commit-data-loss\/\">perder dados<\/a><\/noindex>. No c\u00f3digo de produ\u00e7\u00e3o, geralmente, a posi\u00e7\u00e3o do consumidor \u00e9 controlada manualmente (o desenvolvedor gerencia o momento em que o commit do evento lido deve necessariamente ocorrer).<\/p>\n<p><\/p>\n<p>Nos casos em que um \u00fanico consumidor n\u00e3o \u00e9 suficiente (por exemplo, quando o fluxo de novos eventos \u00e9 muito grande), \u00e9 poss\u00edvel adicionar mais consumidores, vinculando-os em um grupo de consumidores. O grupo de consumidores representa logicamente o mesmo consumidor, mas com a distribui\u00e7\u00e3o de dados entre os membros do grupo. Isso permite que cada um dos participantes receba sua parte das mensagens, escalando assim a velocidade de leitura. <\/p>\n<p><\/p>\n<h1 id=\"rezultaty-testirovaniya\">Resultados do teste<\/h1>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka e microservi\u00e7os: uma vis\u00e3o geral\" src=\"\/wp-content\/uploads\/2019\/09\/f7abe4bcf34fdb0d762c8a928bd873ee.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aqui n\u00e3o vou escrever muito texto explicativo, apenas compartilharei os resultados obtidos. Os testes foram realizados em 3 m\u00e1quinas f\u00edsicas (12 CPU, 384GB de RAM, 15k SAS DISK, 10GBit\/s Net), com os brokers e o zookeeper implantados em lxc. <\/p>\n<p><\/p>\n<p><strong>Testes de desempenho<\/strong><\/p>\n<p><\/p>\n<p>Durante os testes, foram obtidos os seguintes resultados.<\/p>\n<p><\/p>\n<ul>\n<li>A velocidade de grava\u00e7\u00e3o de mensagens de 1KB simultaneamente por 9 produtores foi de 1.300.000 eventos por segundo.<\/li>\n<li>A velocidade de leitura de mensagens de 1KB simultaneamente por 9 consumidores foi de 1.500.000 eventos por segundo.<\/li>\n<\/ul>\n<p><\/p>\n<p><strong>Testes de resist\u00eancia<\/strong><\/p>\n<p><\/p>\n<p>Durante os testes, foram obtidos os seguintes resultados (3 brokers, 3 zookeepers).<\/p>\n<p><\/p>\n<ul>\n<li>A falha de um dos brokers n\u00e3o leva \u00e0 parada ou indisponibilidade do cluster. O trabalho continua normalmente, mas os brokers restantes enfrentam uma carga maior.<\/li>\n<li>O encerramento inesperado de dois brokers em um cluster de tr\u00eas brokers com min.isr = 2 resulta na indisponibilidade do cluster para grava\u00e7\u00e3o, mas dispon\u00edvel para leitura. Se min.isr = 1, o cluster permanece dispon\u00edvel tanto para leitura quanto para grava\u00e7\u00e3o. No entanto, esse modo contraria a exig\u00eancia de alta durabilidade dos dados.<\/li>\n<li>O encerramento inesperado de um dos servidores Zookeeper n\u00e3o leva \u00e0 parada ou indisponibilidade do cluster. O funcionamento continua normalmente.<\/li>\n<li>O encerramento inesperado de dois servidores Zookeeper resulta na indisponibilidade do cluster at\u00e9 que pelo menos um dos servidores Zookeeper seja restaurado. Essa afirma\u00e7\u00e3o \u00e9 verdadeira para um cluster Zookeeper com 3 servidores. Como resultado de pesquisas, foi decidido aumentar o cluster Zookeeper para 5 servidores para aumentar a resili\u00eancia. <br clear=\"left\">\n <\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"kafka-as-a-service\">Kafka como servi\u00e7o<\/h1>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka e microservi\u00e7os: uma vis\u00e3o geral\" src=\"\/wp-content\/uploads\/2019\/09\/19b2356131203cefbadfd90a25ae9674.png\" style=\"display:block;margin: 0 auto;\" \/> <\/p>\n<p><\/p>\n<p>Constatamos que o Kafka \u00e9 uma excelente tecnologia que nos permite resolver a tarefa proposta (implementa\u00e7\u00e3o de um broker de mensagens). No entanto, decidimos proibir que os servi\u00e7os acessassem o Kafka diretamente e o encerramos acima do servi\u00e7o data-bus. Por que fizemos isso? Na verdade, h\u00e1 v\u00e1rias raz\u00f5es.<\/p>\n<p><\/p>\n<ul>\n<li>\n<p>O data-bus assumiu todas as tarefas relacionadas \u00e0 integra\u00e7\u00e3o com o Kafka (implementa\u00e7\u00e3o e configura\u00e7\u00e3o de consumers e producers, monitoramento, alertas, registro, escalabilidade, etc.). Assim, a integra\u00e7\u00e3o com o broker de mensagens ocorre da forma mais simples poss\u00edvel. <\/p>\n<p>\n<\/li>\n<li>\n<p>O data-bus permitiu abstrair de uma linguagem ou biblioteca espec\u00edfica para trabalhar com o Kafka. <\/p>\n<p>\n<\/li>\n<li>\n<p>O data-bus permitiu que outros servi\u00e7os se abstra\u00edssem da camada de armazenamento. Pode ser que, em algum momento, mudemos o Kafka para o Pulsar, e isso n\u00e3o ser\u00e1 percebido (todos os servi\u00e7os conhecem apenas a API do data-bus).<\/p>\n<p>\n<\/li>\n<li>\n<p>O data-bus assumiu a valida\u00e7\u00e3o dos esquemas de eventos.<\/p>\n<p>\n<\/li>\n<li>\n<p>Com o data-bus, foi implementada a autentica\u00e7\u00e3o.<\/p>\n<p>\n<\/li>\n<li>\n<p>Sob a cobertura do data-bus, podemos atualizar as vers\u00f5es do Kafka sem tempo de inatividade, de forma invis\u00edvel, gerenciar centralizadamente as configura\u00e7\u00f5es de producers, consumers, brokers, etc.<\/p>\n<p>\n<\/li>\n<li>\n<p>O data-bus permitiu adicionar os recursos necess\u00e1rios que n\u00e3o est\u00e3o no Kafka (como auditoria de t\u00f3picos, controle de anomalias no cluster, cria\u00e7\u00e3o de DLQ, etc.).<\/p>\n<p>\n<\/li>\n<li>\n<p>O data-bus permite implementar failover de forma centralizada para todos os servi\u00e7os.<\/p>\n<p>\n<\/li>\n<\/ul>\n<p><\/p>\n<p>Atualmente, para come\u00e7ar a enviar eventos para o broker de mensagens, basta conectar uma pequena biblioteca no c\u00f3digo do seu servi\u00e7o. \u00c9 tudo. Voc\u00ea tem a possibilidade de escrever, ler e escalar com uma \u00fanica linha de c\u00f3digo. Toda a implementa\u00e7\u00e3o est\u00e1 oculta para voc\u00ea; o que aparece externamente \u00e9 apenas algumas configura\u00e7\u00f5es, como o tamanho do lote. Sob o cap\u00f4, o servi\u00e7o data-bus levanta a quantidade necess\u00e1ria de inst\u00e2ncias de producers e consumers no Kubernetes e fornece a configura\u00e7\u00e3o necess\u00e1ria, tudo de forma transparente para o seu servi\u00e7o. <\/p>\n<p><\/p>\n<p>Claro, n\u00e3o existe uma solu\u00e7\u00e3o m\u00e1gica, e essa abordagem tem suas limita\u00e7\u00f5es.<\/p>\n<p><\/p>\n<ul>\n<li>O data-bus precisa ser mantido por voc\u00ea mesmo, ao contr\u00e1rio de bibliotecas de terceiros.<\/li>\n<li>O data-bus aumenta o n\u00famero de intera\u00e7\u00f5es entre servi\u00e7os e o broker de mensagens, o que leva a uma diminui\u00e7\u00e3o de desempenho em compara\u00e7\u00e3o com a Kafka pura.<\/li>\n<li>Nem tudo pode ser t\u00e3o facilmente ocultado dos servi\u00e7os; duplicar a funcionalidade do KSQL ou Kafka Streams no data-bus n\u00e3o \u00e9 algo que queremos, ent\u00e3o \u00e0s vezes precisamos permitir que os servi\u00e7os acessem diretamente. <\/li>\n<\/ul>\n<p><\/p>\n<p>No nosso caso, os benef\u00edcios superaram as desvantagens, e a decis\u00e3o de ocultar o broker de mensagens atr\u00e1s de um servi\u00e7o separado se mostrou v\u00e1lida. Em um ano de opera\u00e7\u00e3o, n\u00e3o tivemos nenhuma falha ou problema s\u00e9rio.<\/p>\n<p><\/p>\n<p>P.S. Agrade\u00e7o \u00e0 minha namorada, Ekaterina Obalyaeva, pelas ilustra\u00e7\u00f5es incr\u00edveis para este artigo. Se voc\u00ea gostou delas, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.instagram.com\/o.k_o.k_\/\">aqui<\/a><\/noindex> mais ilustra\u00e7\u00f5es estar\u00e3o dispon\u00edveis.<\/p>\n<p>Fonte: <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.3 - 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\/pt\/blog\/administrirovanie\/kafka-i-mikroservisy-obzor\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\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\/pt\/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 e microservi\u00e7os: uma vis\u00e3o geral | ProHoster","description":"Ol\u00e1 a todos.","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/kafka-i-mikroservisy-obzor","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","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\/pt\/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\/pt\/wp-json\/wp\/v2\/posts\/37849","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=37849"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/37849\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/28406"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=37849"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=37849"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=37849"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}