Apache Kafka

Apache Kafka es una plataforma de mensajería distribuida diseñada para manejar grandes volúmenes de datos en tiempo real. Originalmente desarrollado por LinkedIn y posteriormente donado a la Apache Software Foundation, Kafka se ha convertido en una solución ampliamente adoptada para la transmisión de datos en entornos distribuidos.

Este sistema se basa en el concepto de "publicar y suscribirse" (publish-subscribe) y permite que los sistemas intercambien datos de manera confiable, eficiente y escalable. Su arquitectura distribuida lo hace ideal para aplicaciones que requieren alta disponibilidad y tolerancia a fallos.

Kafka es un sistema diseñado para procesar flujos de eventos en tiempo real. Esto significa que está optimizado para capturar y responder a sucesos que ocurren de manera continua. Los "productores" envían estos eventos a Kafka, organizándolos en "topics" (temas) que actúan como canales de datos.

Los "brokers" de Kafka almacenan estos eventos de forma duradera y los distribuyen a los "consumidores". Estos consumidores son aplicaciones que procesan los eventos a medida que llegan, permitiendo reacciones casi instantáneas. La capacidad de Kafka para manejar grandes volúmenes de datos y su arquitectura distribuida aseguran que estas reacciones ocurran de manera eficiente y escalable.

¿Para qué sirve Apache Kafka?

Apache Kafka se utiliza para la ingesta y procesamiento de grandes cantidades de datos en tiempo real. Su funcionalidad es útil en diversos escenarios, tales como:

  • 🔸Procesamiento de eventos en tiempo real: Empresas que necesitan analizar datos al instante, como plataformas de redes sociales, comercio electrónico y sistemas de detección de fraudes.
  • 🔸Monitoreo de logs y métricas: Kafka facilita la recolección y análisis de registros y métricas en sistemas distribuidos.
  • 🔸Integración de sistemas: Permite la comunicación entre distintos servicios y aplicaciones a través de su sistema de eventos.
  • 🔸Procesamiento de flujos de datos: Gracias a Kafka Streams, se pueden procesar datos en tiempo real con baja latencia.
  • 🔸Mensajería escalable: Sirve como alternativa a sistemas de mensajería tradicionales como RabbitMQ o ActiveMQ, pero con una mayor capacidad de escalabilidad.

Arquitectura

Kafka está compuesto por varios elementos clave que permiten su funcionamiento:

  • Producers: Los productores son la primera línea en el ecosistema de Kafka. Son aplicaciones que generan datos y los envían a Kafka. Estos datos pueden ser de cualquier tipo: registros de actividad de usuarios, datos de sensores, logs de aplicaciones, transacciones financieras, etc.
  • ∘ La clave de los productores es su capacidad para enviar datos de forma asíncrona y a alta velocidad. Esto permite que las aplicaciones continúen funcionando sin tener que esperar a que los datos sean procesados.

    ∘ Los productores tienen la flexibilidad de elegir a qué "topic" (tema) enviar sus mensajes, lo que permite organizar los datos en categorías lógicas.

  • Topics: Los productores tienen la flexibilidad de elegir a qué "topic" (tema) enviar sus mensajes, lo que permite organizar los datos en categorías lógicas.
  • ∘ Cada mensaje enviado a Kafka debe pertenecer a un topic. Por ejemplo, podrías tener un topic para "logs de usuarios", otro para "transacciones de ventas" y otro para "datos de sensores".

    ∘ Los topics permiten que diferentes aplicaciones (productores y consumidores) interactúen con flujos de datos específicos.

  • Brokers: Los brokers son los servidores que componen el clúster de Kafka. Son responsables de almacenar los mensajes y distribuirlos a los consumidores.
  • ∘ Un clúster de Kafka puede estar compuesto por múltiples brokers, lo que proporciona alta disponibilidad y tolerancia a fallos.

    ∘ Cuando un productor envía un mensaje, este se almacena en uno o varios brokers, dependiendo de la configuración del topic.

    ∘ Los brokers son los responsables de la persistencia de los datos, guardando los mensajes en el disco. Esto asegura que los datos no se pierdan, incluso en caso de fallos del sistema.

  • Partitions: Para mejorar la escalabilidad y el rendimiento, cada topic puede dividirse en múltiples particiones.
  • ∘ Cada partición es una secuencia ordenada de mensajes, y cada mensaje dentro de una partición tiene un offset único.

    ∘ Las particiones permiten distribuir la carga de trabajo entre múltiples brokers, lo que aumenta el rendimiento y la capacidad de procesamiento de Kafka.

    ∘ Además, las particiones permiten que múltiples consumidores procesen los mensajes en paralelo, lo que acelera el procesamiento de datos.

  • Consumers: Los consumidores son aplicaciones que leen los mensajes almacenados en Kafka.
  • ∘ Los consumidores se suscriben a uno o varios topics y procesan los mensajes a medida que llegan.

    ∘ Kafka permite que múltiples consumidores trabajen en paralelo para procesar los mensajes de un topic. Esto se logra mediante la asignación de particiones a los consumidores.

    ∘ Los consumidores pueden agruparse en grupos de consumidores (consumer groups), lo que permite distribuir la carga de trabajo y asegurar que cada mensaje sea procesado una sola vez dentro de un grupo.

  • Zookeeper: Zookeeper es un servicio de coordinación que se utiliza para gestionar el clúster de Kafka.
  • ∘ Zookeeper se encarga de mantener la información de configuración del clúster, como la lista de brokers, los topics y las particiones.

    ∘ También se encarga de la elección del líder de las particiones, que es el broker responsable de recibir las escrituras de los productores.

    ∘ Zookeeper es crucial para la estabilidad y la fiabilidad de Kafka, ya que garantiza que todos los componentes del clúster estén sincronizados.

Tecnologías Compatibles

Kafka es compatible con diversas tecnologías y frameworks, lo que lo hace una opción versátil en arquitecturas modernas:

  • Bases de Datos: Puede integrarse con bases de datos relacionales (MySQL, PostgreSQL) y NoSQL (MongoDB, Cassandra).
  • Sistemas de Big Data: Funciona con Apache Spark, Hadoop, y Flink para el procesamiento de datos a gran escala.
  • Lenguajes de Programación: Ofrece soporte para Java, Python, Scala, Go, y más.
  • Sistemas de Mensajería: Puede complementar o reemplazar soluciones como RabbitMQ y ActiveMQ.
  • Servicios en la Nube: Se puede implementar en AWS, Azure y Google Cloud Platform.

Flujo de Apache Kafka

Imagina una plataforma de comercio electrónico en tiempo real. Cada vez que un usuario realiza una compra, se genera un evento. Este evento, que contiene detalles como el ID del producto, el precio, la ubicación del usuario y la hora de la compra, es producido por una aplicación (el productor) y enviado a un topic de Kafka llamado "compras". Este topic está dividido en varias particiones para manejar el alto volumen de transacciones.

Los brokers de Kafka, que forman un clúster, reciben estos eventos y los almacenan de forma duradera en las particiones del topic "compras". Como el topic está particionado, los eventos se distribuyen entre múltiples brokers, lo que permite manejar una gran cantidad de datos y asegurar la disponibilidad. Zookeeper se encarga de coordinar el clúster, asegurando que todos los brokers estén sincronizados y que las particiones tengan líderes designados.

Ahora, imagina que el equipo de análisis de datos necesita procesar estas compras en tiempo real para generar informes y detectar anomalías. Tienen una aplicación (el consumidor) que se suscribe al topic "compras". El consumidor lee los eventos de las particiones y los procesa. Como el topic está particionado, pueden tener múltiples instancias del consumidor trabajando en paralelo, cada una procesando una o varias particiones. Esto permite un procesamiento en tiempo real y escalable de los datos de compra.

Además, el equipo de marketing tiene otra aplicación (otro consumidor) que también se suscribe al topic "compras". Esta aplicación utiliza los datos de compra para personalizar las recomendaciones de productos para los usuarios. Como tienen su propio grupo de consumidores, pueden procesar los mismos eventos de compra sin interferir con el trabajo del equipo de análisis de datos.

En resumen, Kafka actúa como un sistema de mensajería centralizado y escalable que permite la transmisión y el procesamiento de datos en tiempo real. Los productores generan eventos, los brokers los almacenan y los consumidores los procesan, todo ello coordinado por Zookeeper.

Configuración

Para instalar y configurar Kafka, se requieren algunos pasos básicos:

Antes de instalar Kafka, es necesario tener instalado Java y Apache Zookeeper:

Para instalar Apache Kafka en Linux, necesitas descargar los archivos binarios directamente desde el sitio web oficial de Apache Kafka.

Descarga y Configuración de Kafka:
Construir el proyecto:
Primero, asegúrate de crear el directorio de zookeeper:

El directorio /tmp está diseñado para archivos temporales. Los sistemas Linux suelen limpiar este directorio periódicamente, especialmente al reiniciar. Esto significa que los datos de Zookeeper podrían perderse, lo que podría provocar la corrupción de los datos de Kafka.

Para un entorno de producción crea un directorio dedicado para los datos de Zookeeper en una ubicación persistente, como /var/lib/zookeeper o un directorio dentro de tu directorio de inicio (/home/$USER/zookeeper).

Edita el archivo config/zookeeper.properties y modifica "dataDir=/var/lib/zookeeper" para que apunten a tu directorio dedicado:

Luego, cambia los permisos:

Nota: dar permisos 777 es muy permisivo, para un entorno de producción, se recomienda configurar permisos mas restrictivos.

Iniciar Zookeeper:
Iniciar Kafka:

❏ Crear un Topic en Kafka:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~bin/kafka-topics.sh --create --topic mi-topic --bootstrap-server localhost:9092 --partitions 1 --replication-factor 1
Created topic mi-topic.
  • topic mi-topic: Nombre del topic a crear.
  • partitions 3: Número de particiones del topic.
  • replication-factor 2: Número de réplicas del topic para tolerancia a fallos.

❏ Enviar Mensajes:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~bin/kafka-console-producer.sh --topic mi-topic --bootstrap-server localhost:9092
>testing >hello world >i am your father >

❏ Leer Mensajes:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~bin/kafka-console-consumer.sh --topic mi-topic --from-beginning --bootstrap-server localhost:9092
testing hello world i am your father
Para detener Zookeeper:
Para detener Kafka:

Para permitir conexiones remotas, edita el archivo config/server.properties:

listeners=PLAINTEXT://0.0.0.0:9092 advertised.listeners=PLAINTEXT://IP_DEL_SERVIDOR:9092
Después, reinicia Kafka:

En el host remoto, usa la IP del servidor para conectarte.

Cluster de Apache Kafka

Crear un clúster de Apache Kafka con Docker es una excelente manera de experimentar y desarrollar con Kafka de forma rápida y sencilla. Aquí te explico cómo puedes hacerlo, junto con algunas consideraciones importantes:

Creación de los contenedores con Docker:

Es necesario crear 3 contenedores en diferentes terminales, para cada uno de los nodos del cluster.

Verificar las direcciones IP:
Instalar las dependencias en los contenedores:
Descargar Kafka en los contenedores:
Crear la carpeta para zookeeper:

❏ Configurar Zookeeper.

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~nano config/zookeeper.properties
# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # the directory where the snapshot is stored. dataDir=/root/zookeeper-data # the port at which the clients will connect clientPort=2181 # disable the per-ip limit on the number of connections since this is a non-production config maxClientCnxns=0 # Disable the adminserver by default to avoid port conflicts. # Set the port to something non-conflicting if choosing to enable this admin.enableServer=false # admin.serverPort=8080
Construir el proyecto:
Iniciar Zookeeper:
Crear la carpeta para el nodo 1 y 2:

❏ Configurar el nodo 1:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~nano config/server.properties
############################# Server Basics ############################# # The id of the broker. This must be set to a unique integer for each broker. broker.id=1 ############################# Socket Server Settings ############################# # The address the socket server listens on. If not configured, the host name will be equal to the value of # java.net.InetAddress.getCanonicalHostName(), with PLAINTEXT listener name, and port 9092. # FORMAT: # listeners = listener_name://host_name:port # EXAMPLE: # listeners = PLAINTEXT://your.host.name:9092 listeners=PLAINTEXT://10.88.0.3:9092 ############################# Log Basics ############################# # A comma separated list of directories under which to store log files log.dirs=/root/kafka-logs ############################# Zookeeper ############################# # Zookeeper connection string (see zookeeper docs for details). # This is a comma separated host:port pairs, each corresponding to a zk # server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002". # You can also append an optional chroot string to the urls to specify the # root directory for all kafka znodes. zookeeper.connect=10.88.0.2:2181
  • broker.id: Este es el identificador único del broker de Kafka. Cada broker en un clúster debe tener un broker.id diferente.
  • listeners: Define las direcciones y puertos en los que el broker de Kafka escuchará las conexiones de los clientes y otros brokers (es la IP del contenedor en sí).
  • log.dirs: Especifica el directorio o directorios donde Kafka almacenará los archivos de registro (logs) de los mensajes.
  • zookeeper.connect: Define la cadena de conexión para el clúster de Zookeeper.
Construir el proyecto:
Iniciar el nodo 1:

❏ Configurar el nodo 2:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~nano config/server.properties
############################# Server Basics ############################# # The id of the broker. This must be set to a unique integer for each broker. broker.id=2 ############################# Socket Server Settings ############################# # The address the socket server listens on. If not configured, the host name will be equal to the value of # java.net.InetAddress.getCanonicalHostName(), with PLAINTEXT listener name, and port 9092. # FORMAT: # listeners = listener_name://host_name:port # EXAMPLE: # listeners = PLAINTEXT://your.host.name:9092 listeners=PLAINTEXT://10.88.0.4:9092 ############################# Log Basics ############################# # A comma separated list of directories under which to store log files log.dirs=/root/kafka-logs ############################# Zookeeper ############################# # Zookeeper connection string (see zookeeper docs for details). # This is a comma separated host:port pairs, each corresponding to a zk # server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002". # You can also append an optional chroot string to the urls to specify the # root directory for all kafka znodes. zookeeper.connect=10.88.0.2:2181
Construir el proyecto:
Iniciar el nodo 2:
Ahora, asegúrate de ir al directorio de kafka en una nueva terminal:
Construir el proyecto:

❏ Crear un Topic en el cluster Kafka:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~bin/kafka-topics.sh --create --topic test-cluster --bootstrap-server 10.88.0.3:9092 --partitions 2 --replication-factor 2
Created topic mi-topic.

❏ Listar los Topics en el cluster Kafka:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~bin/kafka-topics.sh --list --bootstrap-server 10.88.0.4:9092
test-cluster

❏ Enviar Mensajes:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~bin/kafka-console-producer.sh --topic test-cluster --bootstrap-server 10.88.0.3:9092
>123 >456 >789 >feeling good >

❏ Leer Mensajes:

ryuzak1@ubuntu: ~

ryuzak1@ubuntu:~bin/kafka-console-consumer.sh --topic test-cluster --bootstrap-server 10.88.0.4:9092 --from-beginning
123 456 789 feeling good