Hoy en día un gran número de aplicaciones siguen una arquitectura basada en microservicios. Además, muchas aplicaciones manejan grandes cantidades de datos (actividad de los usuarios sobre la aplicación, logs, métricas…) que viajan constantemente entre microservicios. Esto puede derivar en una serie de problemas a la hora de integrar toda esta información, como la sincronización, escalado o procesado de los datos.
Una posible solución sería aplicar un sistema de mensajería tradicional, como las colas o el patrón publicar-suscribir. En el caso de las colas cada mensaje es leído por un consumidor, permitiendo el escalado, mientras que en publicar-suscribir el mensaje se envía a todos los consumidores suscritos, por lo que no permite escalado. Ambos sistemas carecen además de una garantía en el orden de consumo de los mensajes.
Por lo tanto, es necesario algo que nos garantice mayor fiabilidad y seguridad a la hora de leer mensajes. Es aquí donde entra en juego Apache Kafka, un sistema distribuido y redundante de gestión de eventos desarrollado inicialmente por LinkedIn en 2011. Kafka permite combinar las ventajas de las colas y publicar-suscribir, además de garantizar el consumo ordenado de los mensajes.
Podemos resumir las principales ventajas de Kafka en los siguientes puntos:
● Permite múltiples consumidores y productores. Los denominados grupos de consumidores permiten consumir un mismo mensaje por varios consumidores.
● Garantiza el orden de los mensajes consumidos.
● Retiene temporalmente los datos en disco. Los mensajes no se eliminan tras ser consumidos, sino que se mantienen en el disco hasta que se cumple la política de retención definida por el usuario, bien durante un período de tiempo específico o tras alcanzar una determinada capacidad.
● Es escalable, tanto vertical como horizontalmente, proporcionando resistencia a fallos.
● Proporciona un alto rendimiento, permite gestionar grandes cantidades de datos de manera diaria en aplicaciones en tiempo real.
Kafka dispone de varios clientes para gran cantidad de lenguajes, como Java, Python o Node.js, facilitando la comunicación entre aplicaciones escritas en distintos lenguajes.
¿Cómo funciona?
Apache Kafka basa su funcionamiento en una serie de elementos fundamentales:
Mensajes o records: La unidad mínima de información en Kafka es el mensaje, un array de bytes sin formato específico equivalente a una tupla en base de datos, por lo que puede emplearse para transmitir mensajes entre microservicios escritos en diferentes lenguajes. Cada mensaje almacena un entero (offset) entre sus metadatos que lo identifica de manera inequívoca.
Es habitual definir un esquema para estos mensajes de modo que se facilite su lectura y proporcione consistencia, como Json o XML.
Topics y particiones: Los mensajes de Kafka son clasificados en topics, siendo un topic análogo a una tabla en base de datos. A su vez un topic se divide en particiones, en donde se almacenan los mensajes en orden de llegada con un offset, garantizando así el orden cronológico de los mensajes en una partición, pero no para un mismo topic.
Brokers y clusters: Un broker es un servidor de Kafka, encargado de recibir los mensajes de los productores y commitearlos en logs, la estructura de almacenamiento en disco empleada por Kafka. También se encarga de gestionar las peticiones de los consumidores. Un cluster no es más que un grupo de brokers, en donde uno de ellos funciona como el controlador del cluster, realizando tareas administrativas como la gestión de particiones.
Una partición puede ser asignada a varios brokers, de este modo las réplicas permiten la redundancia de mensajes. Los productores y consumidores actuarán sobre una partición denominada líder, pero si ésta falla una de las réplicas pasará a ser el nuevo líder. Las particiones también son escalables, pudiendo estar alojada cada partición en un broker distinto, permitiendo así el escalado horizontal de topics.
Productores: Producen mensajes que son almacenados en una determinada partición de un topic. En principio la partición es elegida en base a un hash aplicado sobre la clave del mensaje (pues cada mensaje está compuesto por una clave y valor), por lo que el usuario puede establecer una clave específica si quiere escribir en una partición concreta del topic.
Consumidores: Leen mensajes de uno o varios topics en el orden en el que fueron almacenados. El offset de los mensajes es el que ayuda a los consumidores a llevar un control sobre el último mensaje que han leído para evitar pérdidas tras un reinicio del sistema.
Los consumidores pueden pertenecer a un grupo de consumidores definido por un id. Los grupos garantizan que cada partición es consumida por un solo miembro, mientras que consumidores de distintos grupos sí pueden consumir la misma partición. De este modo los consumidores pueden ser escalados horizontalmente para consumir topics con un gran número de mensajes, además de producirse un rebalanceo de particiones entre los consumidores restantes si uno falla.
Apache ZooKeeper
Este software, desarrollado por Apache como servicio de almacenamiento de configuración centralizado, es un componente fundamental para que Kafka funcione correctamente. Algunas de las funciones clave que desempeña ZooKeeper en el ecosistema de Kafka son las siguientes:
• Elegir un controlador entre los brokers, encargado de mantener la relación líder-seguidores de todas las particiones.
• Mantener información relativa a los topics: lista de topics existentes, número de particiones, dónde se encuentran las réplicas…
• Mantener una lista de todos los brokers activos en cada cluster.
Apache Kafka es empleado por Teldat en el desarrollo de nuestro SD-WAN para comunicar los microservicios y gestionar grandes cantidades de datos relativas a los dispositivos de manera eficiente.