{"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\/es\/blog\/administrirovanie\/kafka-i-mikroservisy-obzor","title":{"rendered":"Kafka y microservicios: un vistazo","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Kafka y microservicios: un vistazo\" src=\"\/wp-content\/uploads\/2019\/09\/ab0534ad5d28b3c3aa03e4e0b2d3101b.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hola a todos. En este art\u00edculo les contar\u00e9 por qu\u00e9 en Avito elegimos Kafka hace nueve meses y qu\u00e9 es exactamente. Compartir\u00e9 uno de los casos de uso: el corredor de mensajes. Y, por \u00faltimo, hablaremos sobre cu\u00e1les son los beneficios que hemos obtenido al aplicar el enfoque de Kafka como servicio.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1 id=\"problema\">Problema<\/h1>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka y microservicios: un vistazo\" src=\"\/wp-content\/uploads\/2019\/09\/dfa5e231847cee67259da17867a11812.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Para comenzar, un poco de contexto. Hace alg\u00fan tiempo comenzamos a alejarnos de la arquitectura monol\u00edtica, y ahora en Avito ya hay varios cientos de servicios diferentes. Cada uno tiene su propio almacenamiento, su propio stack tecnol\u00f3gico y es responsable de su parte de la l\u00f3gica del negocio. <\/p>\n<p><\/p>\n<p>Uno de los problemas con un gran n\u00famero de servicios son las comunicaciones. El servicio A a menudo quiere conocer informaci\u00f3n que tiene el servicio B. En este caso, el servicio A se comunica con el servicio B a trav\u00e9s de una API s\u00edncrona. El servicio C quiere saber qu\u00e9 est\u00e1 sucediendo en los servicios D y E, mientras que estos, a su vez, est\u00e1n interesados en los servicios A y B. Cuando hay muchos servicios \u201ccuriosos\u201d, las conexiones entre ellos se convierten en un complicado ovillo.<\/p>\n<p><\/p>\n<p>En cualquier momento, el servicio A puede volverse inaccesible. \u00bfQu\u00e9 deber\u00edan hacer el servicio B y todos los dem\u00e1s servicios vinculados a \u00e9l en este caso? Y si para llevar a cabo una operaci\u00f3n comercial es necesario realizar una cadena de llamadas s\u00edncronas consecutivas, la probabilidad de que falle toda la operaci\u00f3n se eleva a\u00fan m\u00e1s (y es mayor cuanto m\u00e1s larga sea esta cadena). <\/p>\n<p><\/p>\n<h1 id=\"vybor-tehnologii\">Selecci\u00f3n de tecnolog\u00eda<\/h1>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka y microservicios: un vistazo\" src=\"\/wp-content\/uploads\/2019\/09\/3acd7bcf3dded8093bdef6d627eb4071.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Est\u00e1 bien, los problemas est\u00e1n claros. Se pueden resolver creando un sistema centralizado de intercambio de mensajes entre los servicios. Ahora, cada servicio solo necesita conocer este sistema de intercambio de mensajes. Adem\u00e1s, el propio sistema debe ser resistente a fallos y escalable horizontalmente, y en caso de una emergencia, debe acumular un b\u00fafer de las solicitudes para su posterior procesamiento. <\/p>\n<p><\/p>\n<p>Ahora elijamos la tecnolog\u00eda sobre la cual se implementar\u00e1 la entrega de mensajes. Para ello, primero entendamos qu\u00e9 esperamos de ella:<\/p>\n<p><\/p>\n<ul>\n<li>los mensajes entre servicios no deben perderse;<\/li>\n<li>los mensajes pueden duplicarse;<\/li>\n<li>los mensajes se pueden almacenar y leer durante varios d\u00edas (b\u00fafer persistente);<\/li>\n<li>los servicios pueden suscribirse a los datos que les interesan;<\/li>\n<li>varios servicios pueden leer los mismos datos;<\/li>\n<li>los mensajes pueden contener un payload detallado y voluminoso (transferencia de estado mediante eventos);<\/li>\n<li>a veces se necesita una garant\u00eda del orden de los mensajes.<\/li>\n<\/ul>\n<p><\/p>\n<p>Adem\u00e1s, era crucial para nosotros elegir un sistema que fuera lo m\u00e1s escalable y confiable posible, con un alto ancho de banda (al menos 100k mensajes de varios kilobytes por segundo).<\/p>\n<p><\/p>\n<p>En esta etapa, dijimos adi\u00f3s a RabbitMQ (dif\u00edcil de mantener estable a altos rps), PGQ de SkyTools (no lo suficientemente r\u00e1pido y poco escalable) y NSQ (no persistente). Todas estas tecnolog\u00edas se utilizan en nuestra empresa, pero no se adaptaban a la tarea que deb\u00edamos resolver. <\/p>\n<p><\/p>\n<p>Luego comenzamos a explorar nuevas tecnolog\u00edas para nosotros: Apache Kafka, Apache Pulsar y NATS Streaming.<\/p>\n<p><\/p>\n<p>Primero descartamos Pulsar. Decidimos que Kafka y Pulsar eran soluciones bastante similares. A pesar de que Pulsar ha sido probado por grandes empresas, es m\u00e1s nuevo y ofrece una latencia m\u00e1s baja (en teor\u00eda), elegimos dejar Kafka entre las dos, como el est\u00e1ndar de facto para tales tareas. Es probable que volvamos a Apache Pulsar en el futuro. <\/p>\n<p><\/p>\n<p>Y as\u00ed nos quedaron dos candidatos: NATS Streaming y Apache Kafka. Estudiamos ambos soluciones en detalle, y ambas eran adecuadas para la tarea. Sin embargo, al final nos preocup\u00f3 la relativa juventud de NATS Streaming (y que uno de los desarrolladores principales, Tyler Treat, decidi\u00f3 abandonar el proyecto y comenzar el suyo propio \u2014 Liftbridge). Adem\u00e1s, el modo de Clustering de NATS Streaming no permit\u00eda un fuerte escalado horizontal (probablemente ya no sea un problema tras la adici\u00f3n del modo de particionamiento en 2017).<\/p>\n<p><\/p>\n<p>Sin embargo, NATS Streaming es una tecnolog\u00eda impresionante, escrita en Go y respaldada por la Cloud Native Computing Foundation. A diferencia de Apache Kafka, no necesita Zookeeper para funcionar (posiblemente, <noindex><a rel=\"nofollow\" href=\"https:\/\/cwiki.apache.org\/confluence\/display\/KAFKA\/KIP-500%3A+Replace+ZooKeeper+with+a+Self-Managed+Metadata+Quorum\">pronto se podr\u00e1 decir lo mismo de Kafka<\/a><\/noindex>), ya que internamente implementa RAFT. Adem\u00e1s, NATS Streaming es m\u00e1s f\u00e1cil de administrar. No descartamos que en el futuro volvamos a esta tecnolog\u00eda. <\/p>\n<p><\/p>\n<p>Aun as\u00ed, hoy en d\u00eda, nuestro ganador es Apache Kafka. En nuestras pruebas, demostr\u00f3 ser lo suficientemente r\u00e1pido (m\u00e1s de un mill\u00f3n de mensajes por segundo en lectura y escritura con un volumen de mensajes de 1 kilobyte), bastante confiable, bien escalable y probado en producci\u00f3n por grandes empresas. Adem\u00e1s, Kafka es respaldado por al menos varias grandes empresas comerciales (por ejemplo, nosotros utilizamos la versi\u00f3n de Confluent), y tambi\u00e9n Kafka tiene un ecosistema desarrollado.<br \/>\n<br clear=\"left\">\n <\/p>\n<p><\/p>\n<h1 id=\"obzor-kafka\">Revisi\u00f3n de Kafka<\/h1>\n<p><\/p>\n<p>Antes de comenzar, recomiendo inmediatamente un excelente libro \u2014 <em>\u00abKafka: The Definitive Guide\u00bb<\/em> (hay tambi\u00e9n en la traducci\u00f3n al ruso, pero los t\u00e9rminos pueden resultar confusos). En ella se puede encontrar informaci\u00f3n necesaria para una comprensi\u00f3n b\u00e1sica de Kafka e incluso un poco m\u00e1s. La documentaci\u00f3n de Apache y el blog de Confluent tambi\u00e9n est\u00e1n muy bien escritos y son f\u00e1ciles de leer. <\/p>\n<p><\/p>\n<p>As\u00ed que, echemos un vistazo a c\u00f3mo est\u00e1 estructurada Kafka desde una perspectiva general. La topolog\u00eda b\u00e1sica de Kafka consiste en productor, consumidor, corredor y zookeeper.<\/p>\n<p><\/p>\n<h3 id=\"broker\">Corredor<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka y microservicios: un vistazo\" src=\"\/wp-content\/uploads\/2019\/09\/82f34b5a1aadcdc07eef58eb5414b553.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>El corredor (broker) es responsable del almacenamiento de sus datos. Todos los datos se almacenan en formato binario, y el corredor sabe poco sobre lo que representan y cu\u00e1l es su estructura. <\/p>\n<p><\/p>\n<p>Cada tipo l\u00f3gico de eventos generalmente se encuentra en su propio tema (topic) separado. Por ejemplo, un evento de creaci\u00f3n de un anuncio podr\u00eda ir al tema item.created, y un evento de su modificaci\u00f3n al item.changed. Los temas pueden considerarse como clasificadores de eventos. A nivel de tema, se pueden establecer par\u00e1metros de configuraci\u00f3n como: <\/p>\n<p><\/p>\n<ul>\n<li>volumen de datos almacenados y\/o su antig\u00fcedad (retention.bytes, retention.ms); <\/li>\n<li>factor de redundancia de datos (replication factor);<\/li>\n<li>tama\u00f1o m\u00e1ximo de un mensaje (max.message.bytes);<\/li>\n<li>n\u00famero m\u00ednimo de r\u00e9plicas alineadas necesarias para poder escribir datos en el tema (min.insync.replicas);<\/li>\n<li>posibilidad de realizar failover a una r\u00e9plica rezagada no alineada con posible p\u00e9rdida de datos (unclean.leader.election.enable);<\/li>\n<li>y muchos otros (<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>A su vez, cada tema se divide en una o m\u00e1s particiones (partition). Es en las particiones donde finalmente se almacenan los eventos. Si hay m\u00e1s de un corredor en el cl\u00faster, las particiones se distribuir\u00e1n uniformemente entre todos los corredores (en la medida de lo posible), lo que permitir\u00e1 escalar la carga de escritura y lectura en un tema a varios corredores al mismo tiempo.<\/p>\n<p><\/p>\n<p>En el disco, los datos de cada partici\u00f3n se almacenan en forma de archivos de segmentos, que por defecto tienen un tama\u00f1o de un gigabyte (controlado a trav\u00e9s de log.segment.bytes). Una caracter\u00edstica importante es que la eliminaci\u00f3n de datos de las particiones (cuando se activa la retenci\u00f3n) ocurre en segmentos (no se puede eliminar un solo evento de una partici\u00f3n, solo se puede eliminar todo un segmento, y este debe ser inactivo).<\/p>\n<p><\/p>\n<h3 id=\"zookeeper\">Zookeeper<\/h3>\n<p><\/p>\n<p>Zookeeper act\u00faa como un almac\u00e9n de metadatos y coordinador. Es capaz de decir si los corredores est\u00e1n vivos (se puede observar esto a trav\u00e9s de zookeeper con el comando zookeeper-shell <code>ls \/brokers\/ids<\/code>), qu\u00e9 corredor es el controlador (<code>get \/controller<\/code>), \u00bfest\u00e1n las particiones en estado sincronizado con sus r\u00e9plicas (<code>get \/brokers\/topics\/topic_name\/partitions\/partition_number\/state<\/code>). Adem\u00e1s, es a zookeeper donde primero ir\u00e1n el productor y el consumidor para averiguar en qu\u00e9 corredor se almacenan los temas y particiones. En los casos en que el factor de replicaci\u00f3n para un tema se establece en m\u00e1s de 1, zookeeper indicar\u00e1 qu\u00e9 particiones son l\u00edderes (donde se realizar\u00e1 la escritura y de donde tambi\u00e9n se leer\u00e1). En caso de que un corredor caiga, ser\u00e1 en zookeeper donde se registrar\u00e1 la informaci\u00f3n sobre las nuevas particiones l\u00edderes (desde la versi\u00f3n 1.1.0, de forma asincr\u00f3nica, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.confluent.io\/blog\/apache-kafka-supports-200k-partitions-per-cluster\">y esto es importante<\/a><\/noindex>).<\/p>\n<p><\/p>\n<p>En versiones anteriores de Kafka, zookeeper tambi\u00e9n se encargaba de almacenar los offsets, pero ahora se almacenan en un tema especial <code>__consumer_offsets<\/code> en el corredor (aunque todav\u00eda puedes seguir utilizando zookeeper para estos fines). <\/p>\n<p><\/p>\n<p>La forma m\u00e1s sencilla de convertir tus datos en calabaza es precisamente perder informaci\u00f3n de zookeeper. En tal escenario, ser\u00e1 muy complicado entender qu\u00e9 y de d\u00f3nde necesitas leer. <\/p>\n<p><\/p>\n<h3 id=\"producer\">Producer<\/h3>\n<p><\/p>\n<p>El productor es, en la mayor\u00eda de los casos, un servicio que realiza la escritura de datos en Apache Kafka. El productor elige el tema en el que se almacenar\u00e1n sus mensajes tem\u00e1ticos y comienza a registrar informaci\u00f3n en \u00e9l. Por ejemplo, un productor puede ser un servicio de anuncios. En tal caso, enviar\u00e1 eventos a los temas tem\u00e1ticos como \"anuncio creado\", \"anuncio actualizado\", \"anuncio eliminado\", etc. Cada evento representa un par clave-valor.<\/p>\n<p><\/p>\n<p>Por defecto, todos los eventos se distribuyen entre las particiones del tema en un esquema round-robin si no se especifica una clave (perdiendo el orden), y a trav\u00e9s de MurmurHash (clave) si se proporciona una clave (manteniendo el orden dentro de una partici\u00f3n).<\/p>\n<p><\/p>\n<p>Aqu\u00ed cabe mencionar que Kafka garantiza el orden de los eventos solo dentro de una partici\u00f3n. Pero, en realidad, a menudo esto no es un problema. Por ejemplo, se puede garantizar que todos los cambios de un mismo anuncio se a\u00f1adan a una partici\u00f3n (manteniendo as\u00ed el orden de estos cambios en relaci\u00f3n al anuncio). Tambi\u00e9n se puede pasar un n\u00famero de secuencia en uno de los campos del evento.<\/p>\n<p><\/p>\n<h3 id=\"consumer\">Consumidor<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka y microservicios: un vistazo\" src=\"\/wp-content\/uploads\/2019\/09\/1f69a53dc19bb6c587883b8754cde29f.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>El consumidor es responsable de obtener datos de Apache Kafka. Volviendo al ejemplo anterior, el consumidor podr\u00eda ser un servicio de moderaci\u00f3n. Este servicio estar\u00e1 suscrito al tema del servicio de anuncios y, cuando aparezca un nuevo anuncio, lo recibir\u00e1 y lo analizar\u00e1 en funci\u00f3n de ciertas pol\u00edticas establecidas.<\/p>\n<p><\/p>\n<p>Apache Kafka recuerda cu\u00e1les fueron los \u00faltimos eventos que recibi\u00f3 el consumidor (para esto se utiliza un tema de control __consumer__offsets <code>), asegurando as\u00ed que, al leer con \u00e9xito, el consumidor no reciba el mismo mensaje dos veces. Sin embargo, si se utiliza la opci\u00f3n enable.auto.commit = true y se delega completamente el seguimiento de la posici\u00f3n del consumidor en el tema a Kafka, se puede<\/code>perder datos <noindex><a rel=\"nofollow\" href=\"https:\/\/blog.newrelic.com\/engineering\/kafka-consumer-config-auto-commit-data-loss\/\">. En el c\u00f3digo de producci\u00f3n, lo m\u00e1s com\u00fan es que la posici\u00f3n del consumidor se controle manualmente (el desarrollador gestiona el momento en que debe realizarse necesariamente el commit del evento le\u00eddo).<\/a><\/noindex>En los casos en que un solo consumidor no es suficiente (por ejemplo, cuando el flujo de nuevos eventos es muy grande), se puede agregar varios consumidores, vincul\u00e1ndolos en un grupo de consumidores. Un grupo de consumidores representa l\u00f3gicamente al mismo consumidor, pero con la distribuci\u00f3n de datos entre los miembros del grupo. Esto permite que cada uno de los participantes tome su parte de los mensajes, escalando as\u00ed la velocidad de lectura.<\/p>\n<p><\/p>\n<p>Resultados de las pruebas <\/p>\n<p><\/p>\n<h1 id=\"rezultaty-testirovaniya\">No voy a escribir mucho texto explicativo aqu\u00ed, solo compartir\u00e9 los resultados obtenidos. Las pruebas se realizaron en 3 m\u00e1quinas f\u00edsicas (12 CPU, 384GB RAM, 15k SAS DISK, 10GBit\/s Net), los brokers y zookeeper se desplegaron en lxc.<\/h1>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka y microservicios: un vistazo\" src=\"\/wp-content\/uploads\/2019\/09\/f7abe4bcf34fdb0d762c8a928bd873ee.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Durante las pruebas se obtuvieron los siguientes resultados. <\/p>\n<p><\/p>\n<p><strong>Prueba de rendimiento<\/strong><\/p>\n<p><\/p>\n<p>La velocidad de escritura de mensajes de 1KB simult\u00e1neamente por 9 productores es de 1300000 eventos por segundo.<\/p>\n<p><\/p>\n<ul>\n<li>La velocidad de lectura de mensajes de 1KB simult\u00e1neamente por 9 consumidores es de 1500000 eventos por segundo.<\/li>\n<li>Pruebas de resistencia<\/li>\n<\/ul>\n<p><\/p>\n<p><strong>Durante las pruebas se obtuvieron los siguientes resultados (3 brokers, 3 zookeeper).<\/strong><\/p>\n<p><\/p>\n<p>La ca\u00edda inesperada de uno de los brokers no provoca la detenci\u00f3n o inaccesibilidad del cl\u00faster. La operaci\u00f3n contin\u00faa normalmente, pero la carga recae m\u00e1s en los brokers restantes.<\/p>\n<p><\/p>\n<ul>\n<li>La finalizaci\u00f3n inesperada de uno de los brokers no provoca la detenci\u00f3n o inaccesibilidad del cl\u00faster. El funcionamiento contin\u00faa de manera normal, pero los brokers restantes asumen una mayor carga.<\/li>\n<li>La terminaci\u00f3n an\u00f3mala de dos brokers en un cl\u00faster de tres brokers y min.isr = 2 provoca la indisponibilidad del cl\u00faster para la escritura, pero mantiene la disponibilidad para la lectura. En el caso de que min.isr = 1, el cl\u00faster sigue estando disponible tanto para lectura como para escritura. Sin embargo, este modo contradice el requisito de alta integridad de los datos.<\/li>\n<li>La terminaci\u00f3n an\u00f3mala de uno de los servidores Zookeeper no provoca la detenci\u00f3n ni la indisponibilidad del cl\u00faster. El funcionamiento contin\u00faa normalmente.<\/li>\n<li>La terminaci\u00f3n an\u00f3mala de dos servidores Zookeeper provoca la indisponibilidad del cl\u00faster hasta que al menos uno de los servidores Zookeeper se recupere. Esta afirmaci\u00f3n es v\u00e1lida para un cl\u00faster Zookeeper de 3 servidores. Como resultado de estas investigaciones, se decidi\u00f3 aumentar el cl\u00faster Zookeeper a 5 servidores para mejorar la resistencia a fallos. <br clear=\"left\">\n <\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"kafka-as-a-service\">Kafka como servicio<\/h1>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Kafka y microservicios: un vistazo\" src=\"\/wp-content\/uploads\/2019\/09\/19b2356131203cefbadfd90a25ae9674.png\" style=\"display:block;margin: 0 auto;\" \/> <\/p>\n<p><\/p>\n<p>Hemos comprobado que Kafka es una excelente tecnolog\u00eda que nos permite resolver el desaf\u00edo planteado (la implementaci\u00f3n de un broker de mensajes). Sin embargo, decidimos prohibir que los servicios accedan directamente a Kafka y la cerramos a trav\u00e9s del servicio data-bus. \u00bfPor qu\u00e9 hicimos esto? En realidad, hay varias razones.<\/p>\n<p><\/p>\n<ul>\n<li>\n<p>Data-bus asumi\u00f3 todas las tareas relacionadas con la integraci\u00f3n con Kafka (implementaci\u00f3n y configuraci\u00f3n de consumidores y productores, monitoreo, alertas, registro, escalado, etc.). De esta manera, la integraci\u00f3n con el broker de mensajes se realiza de la forma m\u00e1s sencilla posible. <\/p>\n<p>\n<\/li>\n<li>\n<p>Data-bus permiti\u00f3 la abstracci\u00f3n del lenguaje o la biblioteca concreta para trabajar con Kafka. <\/p>\n<p>\n<\/li>\n<li>\n<p>Data-bus permiti\u00f3 que otros servicios se abstrajeran de la capa de almacenamiento. Puede que en alg\u00fan momento cambiemos Kafka por Pulsar, y nadie se dar\u00e1 cuenta (todos los servicios solo conocen la API de data-bus).<\/p>\n<p>\n<\/li>\n<li>\n<p>Data-bus asumi\u00f3 la validaci\u00f3n de los esquemas de eventos.<\/p>\n<p>\n<\/li>\n<li>\n<p>Con data-bus se implement\u00f3 la autenticaci\u00f3n.<\/p>\n<p>\n<\/li>\n<li>\n<p>Bajo la protecci\u00f3n de data-bus, podemos actualizar las versiones de Kafka de manera centralizada y sin tiempo de inactividad, gestionando de forma centralizada las configuraciones de productores, consumidores, brokers, etc.<\/p>\n<p>\n<\/li>\n<li>\n<p>Data-bus permiti\u00f3 a\u00f1adir las funciones necesarias que no est\u00e1n disponibles en Kafka (como la auditor\u00eda de temas, el control de anomal\u00edas en el cl\u00faster, la creaci\u00f3n de DLQ, etc.).<\/p>\n<p>\n<\/li>\n<li>\n<p>Data-bus permite implementar el failover de manera centralizada para todos los servicios.<\/p>\n<p>\n<\/li>\n<\/ul>\n<p><\/p>\n<p>En este momento, para comenzar a enviar eventos a un corredor de mensajes, es suficiente con conectar una peque\u00f1a biblioteca al c\u00f3digo de su servicio. Eso es todo. Tiene la posibilidad de escribir, leer y escalar con una l\u00ednea de c\u00f3digo. Toda la implementaci\u00f3n est\u00e1 oculta de usted; solo quedan a la vista algunas configuraciones como el tama\u00f1o del lote. En segundo plano, el servicio data-bus genera en Kubernetes la cantidad necesaria de instancias de productores y consumidores y les proporciona la configuraci\u00f3n necesaria, pero todo esto es transparente para su servicio. <\/p>\n<p><\/p>\n<p>Por supuesto, no existe una soluci\u00f3n m\u00e1gica, y este enfoque tiene sus limitaciones.<\/p>\n<p><\/p>\n<ul>\n<li>Data-bus necesita ser mantenido por su cuenta, a diferencia de las bibliotecas de terceros.<\/li>\n<li>Data-bus incrementa el n\u00famero de interacciones entre servicios y el corredor de mensajes, lo que resulta en una disminuci\u00f3n del rendimiento comparado con Kafka directamente.<\/li>\n<li>No todo se puede ocultar tan f\u00e1cilmente de los servicios; no queremos duplicar la funcionalidad de KSQL o Kafka Streams en data-bus, por lo que a veces es necesario permitir que los servicios accedan directamente. <\/li>\n<\/ul>\n<p><\/p>\n<p>En nuestro caso, los beneficios superaron a los inconvenientes, y la decisi\u00f3n de cubrir el corredor de mensajes con un servicio separado result\u00f3 ser correcta. Durante un a\u00f1o de operaci\u00f3n, no hemos tenido incidentes o problemas graves.<\/p>\n<p><\/p>\n<p>P.D. Gracias a mi novia, Ekaterina Obalayeva, por las incre\u00edbles ilustraciones de este art\u00edculo. Si te han gustado, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.instagram.com\/o.k_o.k_\/\">aqu\u00ed<\/a><\/noindex> habr\u00e1 a\u00fan m\u00e1s ilustraciones.<\/p>\n<p>Fuente: <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.2 - 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\/es\/blog\/administrirovanie\/kafka-i-mikroservisy-obzor\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\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\/es\/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 y microservicios: una revisi\u00f3n | ProHoster","description":"Hola a todos.","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/kafka-i-mikroservisy-obzor","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"es_ES","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\/es\/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\/es\/wp-json\/wp\/v2\/posts\/37849","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=37849"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/37849\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/28406"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=37849"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=37849"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=37849"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}