{"id":38172,"date":"2019-10-31T22:22:05","date_gmt":"2019-10-31T19:22:05","guid":{"rendered":"https:\/\/prohoster.info\/blog\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka\/"},"modified":"2019-10-31T22:22:05","modified_gmt":"2019-10-31T19:22:05","slug":"ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka","status":"publish","type":"post","link":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka","title":{"rendered":"Entendiendo los brokers de mensajes. Estudiando la mec\u00e1nica de mensajer\u00eda a trav\u00e9s de ActiveMQ y Kafka. Cap\u00edtulo 3. Kafka","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Continuaci\u00f3n de la traducci\u00f3n de un peque\u00f1o libro:<br \/>\n\u00abEntendiendo los intermediarios de mensajes\u00bb,<br \/>\nautor: Jakub Korab, editorial: O'Reilly Media, Inc., fecha de publicaci\u00f3n: junio de 2017, ISBN: 9781492049296.<\/p>\n<p>Parte traducida anteriormente: <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/466385\/\">Comprensi\u00f3n de los intermediarios de mensajes. Estudio de la mec\u00e1nica del intercambio de mensajes a trav\u00e9s de ActiveMQ y Kafka. Cap\u00edtulo 1. Introducci\u00f3n<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>CAP\u00cdTULO 3<\/h2>\n<p><\/p>\n<h2>Kafka<\/h2>\n<p>\nKafka fue desarrollado en LinkedIn para superar algunas de las limitaciones de los intermediarios de mensajes tradicionales y evitar la necesidad de configurar varios intermediarios de mensajes para diferentes interacciones \u00abpunto a punto\u00bb, lo que se describe en este libro en la secci\u00f3n \u00abEscalado vertical y horizontal\u00bb en la p\u00e1gina 28. Los escenarios de uso en LinkedIn se basaron principalmente en la absorci\u00f3n unidireccional de grandes vol\u00famenes de datos, como clics en p\u00e1ginas y registros de acceso, al mismo tiempo que permit\u00edan que m\u00faltiples sistemas usaran estos datos sin afectar el rendimiento de los productores o de otros consumidores. De hecho, la raz\u00f3n de ser de Kafka es lograr una arquitectura de intercambio de mensajes como la descrita en el Universal Data Pipeline.<\/p>\n<p>Con este objetivo final en mente, naturalmente surgieron otros requisitos. Kafka debe:<\/p>\n<ul>\n<li>Ser extremadamente r\u00e1pida<\/li>\n<li>Ofrecer una alta capacidad de procesamiento en el manejo de mensajes<\/li>\n<li>Soportar modelos de \u00abPublicador-Subscriptores\u00bb y \u00abPunto a Punto\u00bb<\/li>\n<li>No disminuir la velocidad al agregar consumidores. Por ejemplo, el rendimiento de las colas y de los t\u00f3picos en ActiveMQ se deteriora con el aumento en el n\u00famero de consumidores en el destinatario<\/li>\n<li>Ser escalable horizontalmente; si un intermediario que almacena (persiste) mensajes solo puede hacerlo a la velocidad m\u00e1xima del disco, tiene sentido exceder un \u00fanico ejemplar de intermediario para aumentar el rendimiento<\/li>\n<li>Restringir el acceso al almacenamiento y a la recuperaci\u00f3n de mensajes<\/li>\n<\/ul>\n<p>\nPara lograr todo esto, Kafka ha adoptado una arquitectura que ha redefinido los roles y responsabilidades de los clientes y los brokers de mensajer\u00eda. El modelo JMS est\u00e1 muy orientado al broker, donde este se encarga de la distribuci\u00f3n de mensajes, mientras que los clientes solo deben preocuparse por enviar y recibir mensajes. Kafka, por otro lado, est\u00e1 centrado en el cliente, haciendo que este asuma muchas de las funciones del broker tradicional, como la distribuci\u00f3n justa de mensajes relevantes entre los consumidores, a cambio de recibir un broker extremadamente r\u00e1pido y escalable. Para aquellos que han trabajado con sistemas de mensajer\u00eda tradicionales, trabajar con Kafka requiere cambios fundamentales en la perspectiva.<br \/>\nEsta direcci\u00f3n de ingenier\u00eda ha llevado a la creaci\u00f3n de una infraestructura de mensajer\u00eda capaz de aumentar la capacidad de procesamiento en \u00f3rdenes de magnitud en comparaci\u00f3n con un broker convencional. Como veremos, este enfoque implica compensaciones que significan que Kafka no es adecuado para ciertos tipos de cargas y software establecido.<\/p>\n<h3>Modelo unificado del destinatario<\/h3>\n<p>\nPara cumplir con los requisitos descritos anteriormente, Kafka ha combinado mensajer\u00eda tipo 'publicaci\u00f3n-suscripci\u00f3n' y 'punto a punto' bajo un \u00fanico tipo de destinatario - <i>tema<\/i>. Esto confunde a las personas que han trabajado con sistemas de mensajer\u00eda donde la palabra 'tema' se refiere a un mecanismo de difusi\u00f3n del que (del tema) la lectura no es confiable (es no duradera). Los temas de Kafka deben ser considerados como un tipo h\u00edbrido de destinatario, de acuerdo con la definici\u00f3n que se presenta en la introducci\u00f3n de este libro.<\/p>\n<blockquote><p>En el resto de este cap\u00edtulo, a menos que indiquemos lo contrario, el t\u00e9rmino 'tema' se referir\u00e1 al tema de Kafka.<\/p><\/blockquote>\n<p>\nPara entender completamente c\u00f3mo se comportan los temas y qu\u00e9 garant\u00edas ofrecen, primero debemos considerar c\u00f3mo est\u00e1n implementados en Kafka.<br \/>\n<i>Cada tema en Kafka tiene su propio registro.<\/i><br \/>\nLos productores que env\u00edan mensajes a Kafka anotan en este registro, mientras que los consumidores leen del registro utilizando punteros que se mueven continuamente hacia adelante. Peri\u00f3dicamente, Kafka elimina las partes m\u00e1s antiguas del registro, independientemente de si los mensajes en esas partes han sido le\u00eddos o no. Una parte central del dise\u00f1o de Kafka es que el corredor no se preocupa por si los mensajes han sido le\u00eddos o no; esa es la responsabilidad del cliente.<\/p>\n<blockquote><p>Los t\u00e9rminos \"registro\" y \"puntero\" no aparecen en <noindex><a rel=\"nofollow\" href=\"https:\/\/kafka.apache.org\/documentation.html\">la documentaci\u00f3n de Kafka<\/a><\/noindex>. Estos t\u00e9rminos bien conocidos se utilizan aqu\u00ed para ayudar a la comprensi\u00f3n.<\/p><\/blockquote>\n<p>\nEste modelo es completamente diferente de ActiveMQ, donde los mensajes de todas las colas se almacenan en un solo registro, y el corredor marca los mensajes como eliminados despu\u00e9s de que han sido le\u00eddos.<br \/>\nAhora profundicemos un poco y consideremos el registro del tema m\u00e1s en detalle.<br \/>\nEl registro de Kafka consiste en varias particiones (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/tm\/w2\/yf\/tmw2yf3lanppqtrumxoidotplhi.png\">Figura 3-1<\/a><\/noindex>). Kafka garantiza un orden estricto en cada partici\u00f3n. Esto significa que los mensajes escritos en una partici\u00f3n en un orden espec\u00edfico se leer\u00e1n en el mismo orden. Cada partici\u00f3n se implementa como un archivo de registro c\u00edclico (rolling) que contiene <i>un subconjunto <\/i>(subset) de todos los mensajes enviados al tema por sus productores. El tema creado contiene por defecto una partici\u00f3n. La idea de las particiones es la idea central de Kafka para la escalabilidad horizontal.<\/p>\n<p><img decoding=\"async\" alt=\"Entendiendo los brokers de mensajes. Estudiando la mec\u00e1nica de mensajer\u00eda a trav\u00e9s de ActiveMQ y Kafka. Cap\u00edtulo 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/39f41ebcb73ec247656c0dea438158a9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figura 3-1. Particiones de Kafka<\/i><\/p>\n<p>Cuando un productor env\u00eda un mensaje al tema de Kafka, decide en qu\u00e9 partici\u00f3n enviar el mensaje. Lo consideraremos m\u00e1s detalladamente m\u00e1s adelante.<\/p>\n<h2>Lectura de mensajes<\/h2>\n<p>\nEl cliente que desea leer mensajes gestiona un puntero nombrado, llamado <i>grupo de consumidores (consumer group)<\/i>, que apunta a <i>el desplazamiento (offset)<\/i> del mensaje en la partici\u00f3n. El desplazamiento es una posici\u00f3n con un n\u00famero creciente que comienza en 0 al comienzo de la partici\u00f3n. Este grupo de consumidores, al que se hace referencia en la API a trav\u00e9s de un identificador definido por el usuario group_id, corresponde <i>a un \u00fanico consumidor l\u00f3gico o sistema<\/i>.<\/p>\n<p>La mayor\u00eda de los sistemas que utilizan mensajer\u00eda leen datos de los destinatarios a trav\u00e9s de varias instancias y flujos para el procesamiento paralelo de mensajes. As\u00ed, generalmente habr\u00e1 muchas instancias de consumidores compartiendo el mismo grupo de consumidores.<\/p>\n<p>El problema de lectura se puede representar de la siguiente manera:<\/p>\n<ul>\n<li>Un tema tiene varias particiones.<\/li>\n<li>Varios grupos de consumidores pueden utilizar el mismo tema simult\u00e1neamente.<\/li>\n<li>Un grupo de consumidores puede tener varias instancias separadas.<\/li>\n<\/ul>\n<p>\nEste es un problema no trivial de \u00abmuchos a muchos\u00bb. Para entender c\u00f3mo Kafka maneja las relaciones entre grupos de consumidores, instancias de consumidores y particiones, consideremos una serie de escenarios de lectura que se complican gradualmente.<\/p>\n<h3>Consumidores y grupos de consumidores.<\/h3>\n<p>\nTomemos como punto de partida un tema con una partici\u00f3n (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/6z\/tz\/dh\/6ztzdhqmjweck-z15htxb2xbe28.png\">Figura 3-2<\/a><\/noindex>).<\/p>\n<p><img decoding=\"async\" alt=\"Entendiendo los brokers de mensajes. Estudiando la mec\u00e1nica de mensajer\u00eda a trav\u00e9s de ActiveMQ y Kafka. Cap\u00edtulo 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/46c92e6bd38774dfef3be4bd198bf35d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figura 3-2. El consumidor lee de la partici\u00f3n.<\/i><\/p>\n<p>Cuando una instancia de consumidor se conecta a este tema con su propio group_id, se le asigna una partici\u00f3n para leer y un desplazamiento en esa partici\u00f3n. La posici\u00f3n de este desplazamiento se configura en el cliente como un puntero a la posici\u00f3n m\u00e1s reciente (el mensaje m\u00e1s nuevo) o la posici\u00f3n m\u00e1s antigua (el mensaje m\u00e1s antiguo). El consumidor solicita (polls) mensajes del tema, lo que lleva a su lectura secuencial desde el registro.<br \/>\nLa posici\u00f3n del desplazamiento se confirma regularmente de nuevo en Kafka y se guarda como mensajes en el tema interno <i>_consumer_offsets<\/i>. Los mensajes le\u00eddos no se eliminan, a diferencia de un corredor normal, y el cliente puede retroceder (rewind) el desplazamiento para volver a procesar los mensajes ya vistos.<\/p>\n<p>Cuando se conecta un segundo consumidor l\u00f3gico, utilizando otro group_id, gestiona un segundo puntero que no depende del primero (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/qe\/v1\/yk\/qev1yktga3s-g1gqlynylbe3n9w.png\">Figura 3-3<\/a><\/noindex>). Por lo tanto, el tema Kafka act\u00faa como una cola, donde existe un \u00fanico consumidor y, como un tema t\u00edpico de publicador-suscriptor (pub-sub), al que est\u00e1n suscritos varios consumidores, con la ventaja adicional de que todos los mensajes se conservan y pueden ser procesados varias veces.<\/p>\n<p><img decoding=\"async\" alt=\"Entendiendo los brokers de mensajes. Estudiando la mec\u00e1nica de mensajer\u00eda a trav\u00e9s de ActiveMQ y Kafka. Cap\u00edtulo 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/e9e8b9063ef7367005254d36abb47f4f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figura 3-3. Dos consumidores en diferentes grupos de consumidores leen de una partici\u00f3n.<\/i><\/p>\n<h3>Consumidores en un grupo de consumidores.<\/h3>\n<p>\nCuando una instancia de consumidor lee datos de una partici\u00f3n, controla completamente el puntero y procesa los mensajes como se describe en la secci\u00f3n anterior.<br \/>\nSi varias instancias de consumidores se han conectado con el mismo group_id a un tema con una partici\u00f3n, la instancia que se conect\u00f3 por \u00faltima vez asumir\u00e1 el control del puntero y a partir de ese momento recibir\u00e1 todos los mensajes (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/0j\/ao\/f2\/0jaof2mdwg3cqvmwemhtxkrltuq.png\">Figura 3-4<\/a><\/noindex>).<\/p>\n<p><img decoding=\"async\" alt=\"Entendiendo los brokers de mensajes. Estudiando la mec\u00e1nica de mensajer\u00eda a trav\u00e9s de ActiveMQ y Kafka. Cap\u00edtulo 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/ec6af819445dad4028f65449a735ae22.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figura 3-4. Dos consumidores en el mismo grupo de consumidores leen de una partici\u00f3n<\/i><\/p>\n<p>Este modo de procesamiento, en el que el n\u00famero de instancias de consumidores supera el n\u00famero de particiones, puede considerarse una variedad de consumidor monopolista. Esto puede ser \u00fatil si necesita una agrupaci\u00f3n de sus instancias de consumidores de \"activo-pasivo\" (o \"caliente-tibia\"), aunque es mucho m\u00e1s t\u00edpica la operaci\u00f3n paralela de varios consumidores (\"activo-activo\" o \"caliente-caliente\") que los consumidores en modo de espera.<\/p>\n<blockquote><p>Este comportamiento de distribuci\u00f3n de mensajes, descrito anteriormente, puede resultar sorprendente en comparaci\u00f3n con el comportamiento de una cola JMS tradicional. En este modelo, los mensajes enviados a la cola se distribuir\u00e1n equitativamente entre dos consumidores.<\/p><\/blockquote>\n<p>\nA menudo, cuando creamos varias instancias de consumidores, lo hacemos para el procesamiento paralelo de mensajes, para aumentar la velocidad de lectura o para mejorar la resiliencia del proceso de lectura. Dado que solo una instancia de consumidor puede leer datos de una partici\u00f3n a la vez, \u00bfc\u00f3mo se logra esto en Kafka?<\/p>\n<p>Una forma de hacerlo es utilizar una instancia de consumidor para leer todos los mensajes y pasarlos a un pool de hilos. Aunque este enfoque aumenta la capacidad de procesamiento, tambi\u00e9n incrementa la complejidad de la l\u00f3gica de los consumidores y no contribuye a mejorar la resiliencia del sistema de lectura. Si una instancia de consumidor se desconecta debido a un fallo en la alimentaci\u00f3n o un evento similar, la lectura se detiene.<\/p>\n<p>La forma can\u00f3nica de abordar este problema en Kafka es utilizar un<i>A<\/i>mayor n\u00famero de particiones.<\/p>\n<h3>Particionado<\/h3>\n<p>\nLas particiones son el mecanismo principal para paralelizar la lectura y escalar un tema m\u00e1s all\u00e1 de la capacidad de un solo broker. Para comprenderlo mejor, consideremos la situaci\u00f3n en la que existe un tema con dos particiones y un consumidor se suscribe a este tema (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/en\/9g\/ct\/en9gct0o017cqp8buawguwlscty.png\">Figura 3-5<\/a><\/noindex>).<\/p>\n<p><img decoding=\"async\" alt=\"Entendiendo los brokers de mensajes. Estudiando la mec\u00e1nica de mensajer\u00eda a trav\u00e9s de ActiveMQ y Kafka. Cap\u00edtulo 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/cc766bf69af22698aacc3f1ac70b067f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figura 3-5. Un consumidor lee de m\u00faltiples particiones<\/i><\/p>\n<p>En este escenario, al consumidor se le da control sobre los punteros que corresponden a su group_id en ambas particiones, y comienza a leer mensajes de ambas particiones.<br \/>\nCuando se agrega un consumidor adicional a este tema para el mismo group_id, Kafka reasigna (reallocate) una de las particiones del primer al segundo consumidor. Despu\u00e9s de eso, cada instancia del consumidor leer\u00e1 de una partici\u00f3n del tema (<noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/8b\/a0\/um\/8ba0umn2yzr9yy3vztonhdfiub0.png\">Figura 3-6<\/a><\/noindex>).<\/p>\n<p>Para procesar mensajes en paralelo en 20 hilos, necesitar\u00e1 al menos 20 particiones. Si hay menos particiones, tendr\u00e1 consumidores que no tendr\u00e1n nada que hacer, como se describi\u00f3 anteriormente en la discusi\u00f3n sobre los consumidores monopolistas.<\/p>\n<p><img decoding=\"async\" alt=\"Entendiendo los brokers de mensajes. Estudiando la mec\u00e1nica de mensajer\u00eda a trav\u00e9s de ActiveMQ y Kafka. Cap\u00edtulo 3. Kafka\" src=\"\/wp-content\/uploads\/2019\/09\/a3c4001e4a5b92d53b6f529b2633254a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Figura 3-6. Dos consumidores en el mismo grupo de consumidores leen de diferentes particiones<\/i><\/p>\n<p>Este esquema reduce significativamente la complejidad del broker de Kafka en comparaci\u00f3n con la distribuci\u00f3n de mensajes requerida para soportar la cola JMS. Aqu\u00ed no hay necesidad de preocuparse por los siguientes aspectos:<\/p>\n<ul>\n<li>Qu\u00e9 consumidor deber\u00eda recibir el siguiente mensaje, bas\u00e1ndose en la distribuci\u00f3n en ciclo (round-robin), la capacidad actual de los buffers de lectura anticipada o los mensajes anteriores (como para los grupos de mensajes JMS).<\/li>\n<li>Qu\u00e9 mensajes se enviaron a qu\u00e9 consumidores y si deben ser entregados nuevamente en caso de fallo.<\/li>\n<\/ul>\n<p>\nTodo lo que el broker de Kafka debe hacer es transmitir mensajes de manera secuencial al consumidor cuando este los solicita.<\/p>\n<p>Sin embargo, los requisitos para paralelizar la lectura y reenv\u00edo de mensajes fallidos no desaparecen; la responsabilidad por ellos simplemente pasa del broker al cliente. Esto significa que deben ser considerados en su c\u00f3digo.<\/p>\n<h2>Env\u00edo de mensajes<\/h2>\n<p>\nLa responsabilidad de decidir a qu\u00e9 partici\u00f3n enviar un mensaje recae en el productor de ese mensaje. Para entender el mecanismo a trav\u00e9s del cual se hace esto, primero debemos considerar qu\u00e9 es lo que realmente estamos enviando.<\/p>\n<p>Mientras que en JMS usamos una estructura de mensaje con metadatos (encabezados y propiedades) y un cuerpo que contiene la carga \u00fatil (payload), en Kafka el mensaje es <i>un par 'clave-valor'<\/i>. La carga \u00fatil del mensaje se env\u00eda como valor (value). La clave, por otro lado, se utiliza principalmente para la partici\u00f3n y debe contener <i>una clave espec\u00edfica de la l\u00f3gica empresarial<\/i>, para colocar mensajes relacionados en la misma partici\u00f3n.<\/p>\n<p>En el Cap\u00edtulo 2 discutimos el escenario de apuestas en l\u00ednea, donde los eventos relacionados deben procesarse en orden por un \u00fanico consumidor:<\/p>\n<ol>\n<li>La cuenta de usuario est\u00e1 configurada.<\/li>\n<li>El dinero se abona en la cuenta.<\/li>\n<li>Se realiza una apuesta que retira dinero de la cuenta.<\/li>\n<\/ol>\n<p>\nSi cada evento representa un mensaje enviado a un t\u00f3pico, entonces la clave natural ser\u00e1 el identificador de la cuenta.<br \/>\nCuando se env\u00eda un mensaje utilizando la Kafka Producer API, este se pasa a la funci\u00f3n de particionamiento, que, considerando el mensaje y el estado actual del cl\u00faster de Kafka, devuelve el identificador de la partici\u00f3n a la que debe enviarse el mensaje. Esta funci\u00f3n est\u00e1 implementada en Java a trav\u00e9s de la interfaz Partitioner.<\/p>\n<p>Esta interfaz se ve de la siguiente manera:<\/p>\n<pre><code class=\"java\">interface Partitioner {\n    int partition(String topic,\n        Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster);\n}<\/code><\/pre>\n<p>\nLa implementaci\u00f3n de Partitioner para determinar la partici\u00f3n utiliza por defecto un algoritmo de hash de clave (general-purpose hashing algorithm over the key) o un algoritmo round-robin, si no se especifica una clave. Este valor por defecto funciona bien en la mayor\u00eda de los casos. Sin embargo, en el futuro querr\u00e1s escribir tu propio.<\/p>\n<h3>Escribir tu propia estrategia de particionamiento<\/h3>\n<p>\nVeamos un ejemplo en el que deseas enviar metadatos junto con la carga \u00fatil del mensaje. La carga \u00fatil en nuestro ejemplo es una instrucci\u00f3n para realizar un dep\u00f3sito en la cuenta de juego. La instrucci\u00f3n es algo que queremos asegurarnos de no modificar al transmitir y queremos estar seguros de que solo un sistema de confianza puede iniciar esta instrucci\u00f3n. En este caso, los sistemas emisor y receptor acuerdan el uso de una firma para verificar la autenticidad del mensaje.<br \/>\nEn un JMS normal, simplemente definimos la propiedad 'firma del mensaje' y la a\u00f1adimos al mensaje. Sin embargo, Kafka no nos proporciona un mecanismo para transmitir metadatos: solo clave y valor.<\/p>\n<p>Dado que el valor es la carga \u00fatil de la transferencia bancaria (bank transfer payload), cuya integridad deseamos mantener, no tenemos m\u00e1s opci\u00f3n que definir la estructura de datos para usar en la clave. Suponiendo que necesitamos un identificador de cuenta para la partici\u00f3n, ya que todos los mensajes relacionados con la cuenta deben procesarse en orden, idearemos la siguiente estructura JSON:<\/p>\n<pre><code class=\"json\">{\n  \"signature\": \"541661622185851c248b41bf0cea7ad0\",\n  \"accountId\": \"10007865234\"\n}<\/code><\/pre>\n<p>\nDado que el valor de la firma variar\u00e1 dependiendo de la carga \u00fatil, la estrategia de hashing predeterminada de la interfaz Partitioner no agrupar\u00e1 de manera confiable los mensajes relacionados. Por lo tanto, necesitaremos escribir nuestra propia estrategia, que analizar\u00e1 esta clave y separar\u00e1 (partition) el valor accountId.<\/p>\n<blockquote><p>Kafka incluye sumas de verificaci\u00f3n para detectar la corrupci\u00f3n de mensajes en el almacenamiento y tiene un conjunto completo de funciones de seguridad. Aun as\u00ed, a veces surgen requisitos espec\u00edficos de la industria, como el que se menciona arriba.<\/p><\/blockquote>\n<p>\nLa estrategia de partici\u00f3n personalizada debe garantizar que todos los mensajes relacionados se encuentren en una sola partici\u00f3n. Aunque esto parece sencillo, el requisito puede complicarse debido a la importancia de mantener el orden de los mensajes relacionados y a cu\u00e1n fijo est\u00e1 el n\u00famero de particiones en el tema.<\/p>\n<p>El n\u00famero de particiones en un tema puede cambiar con el tiempo, ya que se pueden a\u00f1adir si el tr\u00e1fico supera las expectativas iniciales. As\u00ed, las claves de los mensajes pueden estar relacionadas con la partici\u00f3n a la que fueron enviadas originalmente, implicando parte del estado que debe ser distribuido entre las instancias del productor.<\/p>\n<p>Otro factor a considerar es la uniformidad de la distribuci\u00f3n de mensajes entre las particiones. Como regla general, las claves no se distribuyen de manera uniforme en los mensajes, y las funciones de hash no garantizan una distribuci\u00f3n justa de los mensajes para un conjunto peque\u00f1o de claves.<br \/>\nEs importante se\u00f1alar que, independientemente de c\u00f3mo decida dividir los mensajes, es posible que deba reutilizar el propio delimitador.<\/p>\n<p>Consideremos el requisito de replicaci\u00f3n de datos entre cl\u00fasteres de Kafka en diferentes ubicaciones geogr\u00e1ficas. Para este prop\u00f3sito, Kafka viene con una herramienta de l\u00ednea de comandos llamada MirrorMaker, que se utiliza para leer mensajes de un cl\u00faster y transferirlos a otro.<\/p>\n<p>MirrorMaker debe entender las claves del tema a replicar para mantener el orden relativo de los mensajes durante la replicaci\u00f3n entre cl\u00fasteres, ya que el n\u00famero de particiones para este tema puede no coincidir en los dos cl\u00fasteres.<\/p>\n<p>Las estrategias de particionamiento personalizadas son relativamente raras, ya que el hash predeterminado o el redondeo funcionan con \u00e9xito en la mayor\u00eda de los escenarios. Sin embargo, si necesita garant\u00edas estrictas de ordenamiento o necesita extraer metadatos de las cargas \u00fatiles, entonces el particionamiento es algo en lo que debe profundizar.<\/p>\n<p>Las ventajas de escalabilidad y rendimiento de Kafka se deben al traslado de algunas responsabilidades tradicionales del corredor al cliente. En este caso, se toma la decisi\u00f3n de distribuir mensajes potencialmente relacionados entre varios consumidores que operan en paralelo.<\/p>\n<blockquote><p>Los corredores de JMS tambi\u00e9n deben lidiar con tales requisitos. Curiosamente, el mecanismo de env\u00edo de mensajes relacionados al mismo consumidor, implementado a trav\u00e9s de JMS Message Groups (una variante de la estrategia de balanceo de carga adhesivo (SLB)), tambi\u00e9n requiere que el remitente etiquete los mensajes como relacionados. En el caso de JMS, el corredor es responsable de enviar este grupo de mensajes relacionados a un consumidor de muchos y de transferir la propiedad del grupo si el consumidor falla.<\/p><\/blockquote>\n<p><\/p>\n<h2>Acuerdos del productor<\/h2>\n<p>\nEl particionamiento no es lo \u00fanico que se debe considerar al enviar mensajes. Vamos a revisar los m\u00e9todos send() de la clase Producer en la API de Java:<\/p>\n<pre><code class=\"java\">Future  send(ProducerRecord  record);\nFuture  send(ProducerRecord  record, Callback callback);<\/code><\/pre>\n<p>\nEs importante se\u00f1alar que ambos m\u00e9todos devuelven un Future, lo que indica que la operaci\u00f3n de env\u00edo no se lleva a cabo de inmediato. Como resultado, el mensaje (ProducerRecord) se escribe en el b\u00fafer de env\u00edo para cada partici\u00f3n activa y se env\u00eda al corredor en segundo plano por un hilo en la biblioteca del cliente de Kafka. Aunque esto hace que el trabajo sea incre\u00edblemente r\u00e1pido, significa que una aplicaci\u00f3n mal escrita puede perder mensajes si su proceso se detiene.<\/p>\n<p>Como siempre, hay una forma de hacer la operaci\u00f3n de env\u00edo m\u00e1s confiable a expensas del rendimiento. Se puede establecer el tama\u00f1o de este b\u00fafer en 0, y el hilo de la aplicaci\u00f3n de env\u00edo se ver\u00e1 obligado a esperar hasta que se complete la transmisi\u00f3n del mensaje al corredor, de la siguiente manera:<\/p>\n<pre><code class=\"java\">RecordMetadata metadata = producer.send(record).get();<\/code><\/pre>\n<p><\/p>\n<h2>Una vez m\u00e1s sobre la lectura de mensajes<\/h2>\n<p>\nLeer mensajes conlleva complicaciones adicionales que deben considerarse. A diferencia de la API JMS, que puede iniciar un oyente de mensajes (message listener) en respuesta a la llegada de un mensaje, la interfaz <i>Consumidor <\/i>Kafka solo realiza polling. Analicemos m\u00e1s a fondo el m\u00e9todo <i>poll ()<\/i>, que se utiliza para este prop\u00f3sito:<\/p>\n<pre><code class=\"java\">ConsumerRecords poll(long timeout);<\/code><\/pre>\n<p>\nEl valor devuelto por el m\u00e9todo es una estructura contenedora que contiene varios objetos <i>ConsumerRecord <\/i>de potencialmente varias particiones. <i>ConsumerRecord <\/i>es en s\u00ed misma un objeto contenedor para un par clave-valor con los metadatos correspondientes, como la partici\u00f3n de la que se obtuvo.<\/p>\n<p>Como se discuti\u00f3 en el Cap\u00edtulo 2, debemos recordar constantemente qu\u00e9 sucede con los mensajes despu\u00e9s de que han sido procesados exitosamente o no, por ejemplo, si el cliente no puede procesar un mensaje o si se detiene. En JMS, esto se manejaba a trav\u00e9s del modo de confirmaci\u00f3n (acknowledgement mode). El corredor eliminar\u00e1 el mensaje procesado exitosamente o volver\u00e1 a entregar el que no se proces\u00f3 o fall\u00f3 (si se utilizaron transacciones). <br \/>\nKafka funciona de manera muy diferente. Los mensajes no se eliminan en el corredor despu\u00e9s de ser le\u00eddos y la responsabilidad de lo que ocurre en caso de fallo recae en el propio c\u00f3digo de lectura.<\/p>\n<p>Como ya mencionamos, un grupo de consumidores est\u00e1 asociado con un desplazamiento en el registro. La posici\u00f3n en el registro asociada con este desplazamiento corresponde al siguiente mensaje que se emitir\u00e1 en respuesta a <i>poll ()<\/i>El momento en que se produce este desplazamiento es crucial para la lectura.<\/p>\n<p>Volviendo al modelo de lectura mencionado anteriormente, el procesamiento del mensaje consta de tres etapas:<\/p>\n<ol>\n<li>Extraer el mensaje para leer.<\/li>\n<li>Procesar el mensaje.<\/li>\n<li>Confirmar el mensaje.<\/li>\n<\/ol>\n<p>\nEl consumidor de Kafka viene con una opci\u00f3n de configuraci\u00f3n <i>enable.auto.commit<\/i>. Esta es una configuraci\u00f3n predeterminada com\u00fanmente utilizada, como suele ser el caso con las configuraciones que contienen la palabra 'auto'.<\/p>\n<p>Hasta Kafka 0.10, el cliente que utilizaba este par\u00e1metro enviaba el desplazamiento del \u00faltimo mensaje le\u00eddo en la siguiente llamada <i>poll ()<\/i> despu\u00e9s del procesamiento. Esto significaba que cualquier mensaje que ya hubiera sido extra\u00eddo podr\u00eda ser procesado nuevamente si el cliente ya lo hab\u00eda procesado, pero fue destruido inesperadamente antes de la llamada <i>poll ()<\/i>. Dado que el broker no mantiene ning\u00fan estado sobre cu\u00e1ntas veces se ha le\u00eddo un mensaje, el siguiente consumidor que extraiga este mensaje no sabr\u00e1 que ocurri\u00f3 algo malo. Este comportamiento era pseudo-transaccional. El desplazamiento se confirmaba solo en caso de un procesamiento exitoso del mensaje, pero si el cliente interrump\u00eda su trabajo, el broker volv\u00eda a enviar el mismo mensaje a otro cliente. Este comportamiento estaba alineado con la garant\u00eda de entrega de mensajes \u00ab<i>al menos una vez<\/i>\u00ab.<\/p>\n<p>En Kafka 0.10, el c\u00f3digo del cliente se modific\u00f3 de tal manera que la confirmaci\u00f3n comenzaba a ejecutarse peri\u00f3dicamente por la biblioteca del cliente, de acuerdo con la configuraci\u00f3n <i>auto.commit.interval.ms<\/i>. Este comportamiento se encuentra en alg\u00fan lugar entre los modos JMS AUTO_ACKNOWLEDGE y DUPS_OK_ACKNOWLEDGE. Al utilizar la confirmaci\u00f3n autom\u00e1tica, los mensajes pod\u00edan ser confirmados independientemente de si hab\u00edan sido procesados realmente \u2014 esto podr\u00eda ocurrir en el caso de un consumidor lento. Si el consumidor se interrump\u00eda, los mensajes eran extra\u00eddos por el siguiente consumidor, comenzando desde la posici\u00f3n confirmada, lo que podr\u00eda llevar a la omisi\u00f3n de mensajes. En este caso, Kafka no perd\u00eda mensajes, simplemente el c\u00f3digo de lectura no los procesaba.<\/p>\n<p>Este modo tiene las mismas perspectivas que en la versi\u00f3n 0.9: los mensajes pueden ser procesados, pero en caso de falla, el desplazamiento puede no estar confirmado, lo que potencialmente puede llevar a la duplicaci\u00f3n de entregas. Cuantos m\u00e1s mensajes extraigas al realizar <i>poll ()<\/i>, m\u00e1s grande es este problema.<\/p>\n<p>Como se discuti\u00f3 en la secci\u00f3n 'Lectura de mensajes de la cola' en la p\u00e1gina 21, en el sistema de mensajer\u00eda no existe el concepto de entrega \u00fanica de un mensaje, considerando los modos de falla.<\/p>\n<p>En Kafka, hay dos formas de confirmar (comprometer) un desplazamiento (offset): autom\u00e1tica y manualmente. En ambos casos, los mensajes pueden ser procesados varias veces si un mensaje se proces\u00f3, pero hubo un fallo antes del compromiso. Tambi\u00e9n puede no procesar un mensaje en absoluto si el compromiso se realiz\u00f3 en segundo plano y su c\u00f3digo se complet\u00f3 antes de que comenzara el procesamiento (posiblemente en Kafka 0.9 y versiones anteriores).<\/p>\n<p>Usted puede gestionar el proceso de compromiso de desplazamiento manualmente en la API del consumidor de Kafka, estableciendo el par\u00e1metro <i>enable.auto.commit<\/i> en false y llamando expl\u00edcitamente a uno de los siguientes m\u00e9todos:<\/p>\n<pre><code class=\"java\">void commitSync();\nvoid commitAsync();<\/code><\/pre>\n<p>\nSi desea procesar un mensaje 'al menos una vez', debe comprometer el desplazamiento manualmente usando <i>commitSync()<\/i>, ejecutando este comando inmediatamente despu\u00e9s de procesar los mensajes.<\/p>\n<p>Estos m\u00e9todos no permiten confirmar (acknowledged) los mensajes hasta que sean procesados, pero no hacen nada para abordar la posible duplicaci\u00f3n del procesamiento, al mismo tiempo que crean la apariencia de transacciones. En Kafka no existen transacciones. El cliente no puede hacer lo siguiente:<\/p>\n<ul>\n<li>Revertir autom\u00e1ticamente (roll back) un mensaje fallido. Los consumidores deben manejar las excepciones que surgen de cargas problem\u00e1ticas y desconexiones del backend, ya que no pueden confiar en la reentrega de mensajes por parte del corredor.<\/li>\n<li>Enviar mensajes a m\u00faltiples temas como parte de una sola operaci\u00f3n at\u00f3mica. Como veremos pronto, el control sobre diferentes temas y particiones puede encontrarse en diferentes m\u00e1quinas en el cl\u00faster de Kafka, las cuales no coordinan transacciones al enviar. Hasta el momento de redactar este art\u00edculo, se hab\u00eda realizado un trabajo considerable para hacer esto posible a trav\u00e9s de KIP-98.<\/li>\n<li>Vincular la lectura de un mensaje de un tema con el env\u00edo de otro mensaje a otro tema. Nuevamente, la arquitectura de Kafka depende de muchas m\u00e1quinas independientes que operan como un solo bus y no se hacen esfuerzos para ocultar esto. Por ejemplo, no existen componentes de API que permitan vincular <i>Consumidor <\/i>y <i>Productor <\/i>en la transacci\u00f3n. En JMS, esto es garantizado por el objeto <i>Session<\/i>, del cual se crean <i>MessageProducers <\/i>y <i>MessageConsumers<\/i>.<\/li>\n<\/ul>\n<p>\nSi no podemos confiar en las transacciones, \u00bfc\u00f3mo podemos garantizar una sem\u00e1ntica m\u00e1s cercana a la que proporcionan los sistemas de mensajer\u00eda tradicionales?<\/p>\n<p>Si hay una posibilidad de que el desplazamiento del consumidor pueda aumentar antes de que se procese el mensaje, por ejemplo, durante una falla del consumidor, entonces el consumidor no tiene forma de saber si su grupo de consumidores ha perdido mensajes al asignarles una partici\u00f3n. As\u00ed, una de las estrategias consiste en rebobinar el desplazamiento a la posici\u00f3n anterior. La API del consumidor de Kafka proporciona los siguientes m\u00e9todos para esto:<\/p>\n<pre><code class=\"java\">void seek(TopicPartition partition, long offset);\nvoid seekToBeginning(Collection  partitions);<\/code><\/pre>\n<p>\nEl m\u00e9todo <i>seek ()<\/i> puede ser usado junto con el m\u00e9todo <br \/>\n<i>offsetsForTimes (Map timestampsToSearch)<\/i> para rebobinar a un estado en un momento determinado en el pasado.<\/p>\n<p>Impl\u00edcitamente, el uso de este enfoque significa que, muy probablemente, algunos mensajes que ya fueron procesados ser\u00e1n le\u00eddos y procesados nuevamente. Para evitar esto, podemos usar la lectura idempotente, como se describe en el Cap\u00edtulo 4, para rastrear los mensajes previamente vistos y excluir duplicados.<\/p>\n<p>Como alternativa, el c\u00f3digo de su consumidor puede ser simple si se permite la p\u00e9rdida o duplicaci\u00f3n de mensajes. Cuando consideramos escenarios de uso para los que generalmente se utiliza Kafka, como el procesamiento de eventos de registros, m\u00e9tricas, seguimiento de clics, etc., entendemos que la p\u00e9rdida de mensajes individuales probablemente no tendr\u00e1 un impacto significativo en las aplicaciones circundantes. En tales casos, los valores predeterminados son completamente aceptables. Por otro lado, si su aplicaci\u00f3n necesita procesar pagos, debe cuidar cuidadosamente cada mensaje individual. Todo se reduce al contexto.<\/p>\n<p>Observaciones personales muestran que a medida que aumenta la intensidad de los mensajes, el valor de cada mensaje individual disminuye. Mensajes de gran volumen se vuelven, por lo general, valiosos si se consideran en forma agregada.<\/p>\n<h2>Alta disponibilidad (High Availability)<\/h2>\n<p>\nEl enfoque de Kafka en cuanto a alta disponibilidad es significativamente diferente al de ActiveMQ. Kafka est\u00e1 dise\u00f1ada sobre la base de cl\u00fasteres horizontalmente escalables, donde todas las instancias del broker reciben y entregan mensajes simult\u00e1neamente.<\/p>\n<p>Un cl\u00faster de Kafka consiste en varias instancias de brokers que funcionan en diferentes servidores. Kafka fue dise\u00f1ada para operar en hardware aut\u00f3nomo com\u00fan, donde cada nodo tiene su propio almacenamiento dedicado. No se recomienda el uso de almacenamiento en red (SAN), ya que m\u00faltiples nodos de c\u00f3mputo pueden competir por intervalos temporales de almacenamiento y crear conflictos.<i>\u042b<\/i>Los<\/p>\n<p>Kafka es un <i>sistema siempre activo.<\/i> Muchos grandes usuarios de Kafka nunca apagan sus cl\u00fasteres y el software siempre actualiza mediante reinicios secuenciales. Esto se logra garantizando la compatibilidad con versiones anteriores para los mensajes y las interacciones entre brokers.<\/p>\n<p>Los brokers est\u00e1n conectados al cl\u00faster de servidores <noindex><a rel=\"nofollow\" href=\"http:\/\/zookeeper.apache.org\">ZooKeeper<\/a><\/noindex>, que act\u00faa como un registro de datos de configuraci\u00f3n y se utiliza para coordinar los roles de cada broker. ZooKeeper en s\u00ed es un sistema distribuido que asegura alta disponibilidad mediante la replicaci\u00f3n de informaci\u00f3n al establecer un <i>qu\u00f3rum.<\/i>.<\/p>\n<p>En su caso b\u00e1sico, un tema se crea en el cl\u00faster de Kafka con las siguientes propiedades:<\/p>\n<ul>\n<li>N\u00famero de particiones. Como se discuti\u00f3 anteriormente, el valor exacto utilizado aqu\u00ed depende del nivel deseado de lectura paralela.<\/li>\n<li>El factor de replicaci\u00f3n determina cu\u00e1ntas instancias de brokers en el cl\u00faster deben contener los logs para esta partici\u00f3n.<\/li>\n<\/ul>\n<p>\nUsando ZooKeepers para la coordinaci\u00f3n, Kafka intenta distribuir de manera justa nuevas particiones entre los brokers en el cl\u00faster. Esto se hace mediante una instancia que cumple el rol de Controlador.<\/p>\n<p>En tiempo de ejecuci\u00f3n, <i>para cada partici\u00f3n del tema,<\/i> <i>Controlador <\/i>asigna roles de broker <i>l\u00edder <\/i>(leader, maestro, principal) y <i>seguidores. <\/i>(seguidores, esclavos, subordinados). El corredor que act\u00faa como l\u00edder para esta partici\u00f3n es responsable de recibir todos los mensajes enviados por los productores y distribuir los mensajes a los consumidores. Al enviar mensajes a la partici\u00f3n del tema, se replican en todos los nodos del corredor que act\u00faan como seguidores para esta partici\u00f3n. Cada nodo que contiene registros para la partici\u00f3n se llama <i>r\u00e9plica<\/i>. El corredor puede actuar como l\u00edder para algunas particiones y como seguidor para otras.<\/p>\n<p>El seguidor que contiene todos los mensajes almacenados en el l\u00edder se llama <i>r\u00e9plica sincronizada<\/i> (r\u00e9plica en estado sincronizado, in-sync replica). Si el corredor que act\u00faa como l\u00edder para la partici\u00f3n se apaga, cualquier corredor que est\u00e9 en estado actualizado o sincronizado para esta partici\u00f3n puede asumir el papel de l\u00edder. Este es un dise\u00f1o incre\u00edblemente resistente.<\/p>\n<p>Una parte de la configuraci\u00f3n del productor es el par\u00e1metro <i>acks<\/i>, que define cu\u00e1ntas r\u00e9plicas deben confirmar (acknowledge) la recepci\u00f3n de un mensaje antes de que el flujo de la aplicaci\u00f3n contin\u00fae enviando: 0, 1 o todos. Si se establece el valor <i>todo<\/i>, al recibir un mensaje, el l\u00edder enviar\u00e1 una confirmaci\u00f3n (confirmation) de vuelta al productor tan pronto como reciba confirmaciones (acknowledgements) de varias r\u00e9plicas (incluy\u00e9ndose a s\u00ed mismo), definidas por la configuraci\u00f3n del tema <i>min.insync.replicas<\/i> (por defecto 1). Si el mensaje no puede ser replicado con \u00e9xito, el productor lanzar\u00e1 una excepci\u00f3n para la aplicaci\u00f3n (<i>NotEnoughReplicas<\/i> o <i>NotEnoughReplicasAfterAppend<\/i>).<\/p>\n<p>En una configuraci\u00f3n t\u00edpica, se crea un tema con un factor de replicaci\u00f3n de 3 (1 l\u00edder, 2 seguidores para cada partici\u00f3n) y el par\u00e1metro <i>min.insync.replicas<\/i> se establece en 2. En este caso, el cl\u00faster permitir\u00e1 que uno de los corredores que gestionan la partici\u00f3n del tema se apague sin afectar a las aplicaciones cliente.<\/p>\n<p>Esto nos lleva de vuelta al compromiso ya conocido entre rendimiento y confiabilidad. La replicaci\u00f3n ocurre a costa de un tiempo adicional esperando confirmaciones (acknowledgments) de los seguidores. Sin embargo, dado que se realiza en paralelo, la replicaci\u00f3n en al menos tres nodos tiene el mismo rendimiento que en dos (ignorando el aumento del uso del ancho de banda de la red).<\/p>\n<p>Al utilizar este esquema de replicaci\u00f3n, Kafka elude h\u00e1bilmente la necesidad de garantizar la grabaci\u00f3n f\u00edsica de cada mensaje en disco mediante la operaci\u00f3n <i>sync ()<\/i>. Cada mensaje enviado por el productor se registrar\u00e1 en el registro de la partici\u00f3n, pero, como se discuti\u00f3 en el Cap\u00edtulo 2, la grabaci\u00f3n en el archivo se realiza inicialmente en el b\u00fafer del sistema operativo. Si este mensaje se replica en otra instancia de Kafka y est\u00e1 en su memoria, la p\u00e9rdida de l\u00edder no significa que el mensaje en s\u00ed se haya perdido; puede ser tomado por una r\u00e9plica sincronizada.<br \/>\nRenunciar a la necesidad de ejecutar la operaci\u00f3n <i>sync ()<\/i> significa que Kafka puede aceptar mensajes a la velocidad a la que puede grabarlos en memoria. Y viceversa, cuanto m\u00e1s tiempo se pueda evitar el volcado (flushing) de memoria a disco, mejor. Por esta raz\u00f3n, no es raro que a los brokers de Kafka se les asigne 64 GB de memoria o m\u00e1s. Este uso de memoria significa que una instancia de Kafka puede funcionar f\u00e1cilmente a velocidades miles de veces m\u00e1s r\u00e1pidas que un broker de mensajes tradicional.<\/p>\n<p>Kafka tambi\u00e9n se puede configurar para aplicar la operaci\u00f3n <i>sync ()<\/i> a lotes de mensajes. Dado que todo en Kafka est\u00e1 orientado al trabajo con lotes, esto en realidad funciona bastante bien para muchos escenarios de uso y es una herramienta \u00fatil para los usuarios que requieren garant\u00edas muy s\u00f3lidas. Gran parte del rendimiento puro de Kafka est\u00e1 asociado con los mensajes que se env\u00edan al broker en forma de lotes, y con el hecho de que estos mensajes se leen del broker en bloques consecutivos mediante <noindex><a rel=\"nofollow\" href=\"http:\/\/www.linuxjournal.com\/article\/6345\">zero-copy<\/a><\/noindex> operaciones (operaciones en las que no se realiza la tarea de copiar datos de una \u00e1rea de memoria a otra). Esto \u00faltimo es una gran ganancia en t\u00e9rminos de rendimiento y recursos, y es posible solo gracias al uso de la estructura de datos de registro subyacente que define el esquema de partici\u00f3n.<\/p>\n<p>En un cl\u00faster de Kafka, se puede lograr un rendimiento mucho m\u00e1s alto que al usar un \u00fanico broker de Kafka, ya que las particiones del tema pueden escalar horizontalmente en m\u00faltiples m\u00e1quinas individuales.<\/p>\n<h2>Resultados<\/h2>\n<p>\nEn este cap\u00edtulo, hemos explorado c\u00f3mo la arquitectura de Kafka redefine las relaciones entre clientes y brokers para proporcionar un canal de mensajer\u00eda incre\u00edblemente resistente, con un ancho de banda muchas veces mayor que el de un broker de mensajes convencional. Discutimos las funcionalidades que utiliza para lograr este objetivo y revisamos brevemente la arquitectura de las aplicaciones que ofrecen dicha funcionalidad. En el siguiente cap\u00edtulo, abordaremos los problemas comunes que las aplicaciones basadas en mensajer\u00eda deben resolver y discutiremos estrategias para solucionarlos. Finalizaremos el cap\u00edtulo esbozando c\u00f3mo razonar sobre las tecnolog\u00edas de mensajer\u00eda en general, para que pueda evaluar su idoneidad para sus escenarios de uso.<\/p>\n<p>Parte traducida anteriormente: <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/466385\/\">Comprensi\u00f3n de los corredores de mensajes. Estudio de la mec\u00e1nica del intercambio de mensajes a trav\u00e9s de ActiveMQ y Kafka. Cap\u00edtulo 1<\/a><\/noindex><\/p>\n<p><b> Traducci\u00f3n realizada por: <noindex><a rel=\"nofollow\" href=\"http:\/\/tele.gg\/middle_java\">tele.gg\/middle_java<\/a><\/noindex><\/b><\/p>\n<p><i>Continuar\u00e1\u2026<\/i><\/p>\n<p class=\"for_users_only_msg\">Solo los usuarios registrados pueden participar en la encuesta. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/auth\/login\/\">Inicie sesi\u00f3n<\/a><\/noindex>, por favor.<\/p>\n<h2 class=\"default-block__polling-title\">\u00bfSe utiliza Kafka en su organizaci\u00f3n?<\/h2>\n<ul class=\"content-list content-list_polling\">\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    S\u00ed<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    No<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Se utiliz\u00f3 anteriormente, ahora no<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Planeamos utilizarlo<\/p>\n<\/li>\n<\/ul>\n<p>    38 usuarios votaron. 8 usuarios se abstuvieron.<br \/>\n<br \/>Fuente: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/466585\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043d\u0438\u0433\u0438: \u00abUnderstanding Message Brokers\u00bb, \u0430\u0432\u0442\u043e\u0440: Jakub Korab, \u0438\u0437\u0434\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e: O&#8217;Reilly Media, Inc., \u0434\u0430\u0442\u0430 \u0438\u0437\u0434\u0430\u043d\u0438\u044f: June 2017, ISBN: 9781492049296. \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c: \u041f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0418\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438 \u043e\u0431\u043c\u0435\u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c ActiveMQ \u0438 Kafka. \u0413\u043b\u0430\u0432\u0430 1. \u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0413\u041b\u0410\u0412\u0410 3 Kafka Kafka \u0431\u044b\u043b\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 \u0432 LinkedIn \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043e\u0439\u0442\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-38172","post","type-post","status-publish","format-standard","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=\"\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043d\u0438\u0433\u0438: \u00abUnderstanding Message Brokers\u00bb, \u0430\u0432\u0442\u043e\u0440: Jakub Korab, \u0438\u0437\u0434\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e: O&#039;Reilly Media, Inc., \u0434\u0430\u0442\u0430 \u0438\u0437\u0434\u0430\u043d\u0438\u044f: June 2017, ISBN: 9781492049296. \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f.\" \/>\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\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka\" \/>\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\udd47\u041f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0418\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438 \u043e\u0431\u043c\u0435\u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c ActiveMQ \u0438 Kafka. \u0413\u043b\u0430\u0432\u0430 3. Kafka | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043d\u0438\u0433\u0438: \u00abUnderstanding Message Brokers\u00bb, \u0430\u0432\u0442\u043e\u0440: Jakub Korab, \u0438\u0437\u0434\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e: O&#039;Reilly Media, Inc., \u0434\u0430\u0442\u0430 \u0438\u0437\u0434\u0430\u043d\u0438\u044f: June 2017, ISBN: 9781492049296. \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka\" \/>\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:22:05+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:22:05+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\udd47Entendiendo los brokers de mensajes. Estudio de la mec\u00e1nica de la mensajer\u00eda a trav\u00e9s de ActiveMQ y Kafka. Cap\u00edtulo 3. Kafka | ProHoster","description":"Continuaci\u00f3n de la traducci\u00f3n de un peque\u00f1o libro: \"Understanding Message Brokers\", autor: Jakub Korab, editorial: O'Reilly Media, Inc., fecha de publicaci\u00f3n: junio de 2017, ISBN: 9781492049296. Anteriormente traducido.","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka","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\udd47\u041f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0418\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438 \u043e\u0431\u043c\u0435\u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c ActiveMQ \u0438 Kafka. \u0413\u043b\u0430\u0432\u0430 3. Kafka | ProHoster","og:description":"\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043d\u0438\u0433\u0438: \u00abUnderstanding Message Brokers\u00bb, \u0430\u0432\u0442\u043e\u0440: Jakub Korab, \u0438\u0437\u0434\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e: O'Reilly Media, Inc., \u0434\u0430\u0442\u0430 \u0438\u0437\u0434\u0430\u043d\u0438\u044f: June 2017, ISBN: 9781492049296. \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f.","og:url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/ponimanie-brokerov-soobshhenij-izuchenie-mehaniki-obmena-soobshheniyami-posredstvom-activemq-i-kafka-glava-3-kafka","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:22:05+00:00","article:modified_time":"2019-10-31T19:22:05+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"38172","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 20:46:00","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 15:34:26","updated":"2026-01-23 20:46:00","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\/38172","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=38172"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/38172\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=38172"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=38172"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=38172"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}