Arquitectura de Kafka Explicada: Componentes Principales y Sus Roles

Explore los cimientos fundamentales de la arquitectura distribuida de transmisión de eventos de Apache Kafka. Esta guía explica claramente los roles de los Brokers de Kafka, Temas (Topics), Particiones, Productores, Consumidores y la función de coordinación de ZooKeeper. Descubra cómo interactúan estos componentes para garantizar un procesamiento y almacenamiento de datos de alto rendimiento y tolerante a fallos, un conocimiento esencial para cualquier implementación de Kafka.

Arquitectura de Kafka Explicada: Componentes Clave y Sus Roles

La arquitectura de Kafka puede parecer confusa al principio porque el mismo sistema maneja almacenamiento, transmisión, replicación y progreso del consumidor. Una vez que separas las partes principales, el modelo se vuelve mucho más fácil: los productores escriben registros en particiones de temas, los brokers almacenan esas particiones y los consumidores leen registros por desplazamiento.

Esta guía explica los componentes clave de Kafka y cómo trabajan juntos en un clúster real.

Brokers: Los Servidores de Kafka

Un clúster de Kafka está compuesto por uno o más brokers. Un broker es un servidor de Kafka que almacena datos de particiones y maneja solicitudes de clientes de productores y consumidores.

Cuando un productor envía un registro, escribe en el broker que actualmente lidera la partición objetivo. Cuando un consumidor lee registros, los obtiene del broker que sirve esa partición. En configuraciones normales, cada broker maneja muchas particiones de muchos temas.

Agregar brokers puede aumentar la capacidad de almacenamiento y distribuir el tráfico, pero no soluciona automáticamente todos los cuellos de botella. También necesitas suficientes particiones, colocación equilibrada de réplicas, discos saludables y capacidad de red.

Temas: Flujos Nombrados de Registros

Un tema es un flujo nombrado de registros, como pedidos, pagos o actividad_usuario. Los productores escriben en temas y los consumidores se suscriben a temas.

Un tema se divide en particiones. Cada partición es un registro ordenado y de solo añadidura. Kafka garantiza el orden de los registros dentro de una sola partición, no en todo el tema.

Ese detalle importa. Si todos los eventos de un cliente deben procesarse en orden, usa una clave estable como id_cliente. El particionador predeterminado de Kafka usa la clave para elegir una partición, por lo que los registros con la misma clave normalmente van a la misma partición.

Particiones y Desplazamientos

Cada registro en una partición obtiene un desplazamiento. El desplazamiento es un número que identifica la posición del registro en esa partición.

Por ejemplo, un tema llamado pedidos con tres particiones podría verse así:

pedidos-0: desplazamiento 0, desplazamiento 1, desplazamiento 2
pedidos-1: desplazamiento 0, desplazamiento 1
pedidos-2: desplazamiento 0, desplazamiento 1, desplazamiento 2, desplazamiento 3

Los desplazamientos solo tienen significado dentro de su propia partición. El desplazamiento 3 en pedidos-2 no está relacionado con el desplazamiento 3 en otra partición.

Las particiones le dan a Kafka paralelismo. Más particiones permiten que más consumidores en el mismo grupo de consumidores trabajen al mismo tiempo, hasta un consumidor activo por partición dentro de ese grupo.

Replicación y Líderes

Kafka usa replicación para mantener los datos disponibles cuando un broker falla. Cada partición puede tener múltiples réplicas en diferentes brokers.

Una réplica es el líder. Los productores y consumidores normalmente hablan con el líder de esa partición. Las otras réplicas son seguidores. Los seguidores copian datos del líder y están listos para asumir si el líder falla.

El factor de replicación controla cuántas copias mantiene Kafka. Un factor de replicación de 3 significa que Kafka almacena tres copias de cada partición en tres brokers, cuando hay suficientes brokers disponibles.

Puedes crear un tema así:

kafka-topics.sh --create \
  --topic actividad_usuario \
  --bootstrap-server localhost:9092 \
  --partitions 3 \
  --replication-factor 3

Ese comando requiere un clúster con al menos tres brokers. En una configuración local de un solo broker, usa un factor de replicación de 1.

Productores: Aplicaciones Que Escriben Eventos

Los productores envían registros a temas de Kafka. Un registro puede incluir una clave, valor, marca de tiempo y encabezados.

El productor primero solicita metadatos al clúster para saber qué broker lidera cada partición. Luego envía registros directamente al broker correcto.

La fiabilidad del productor depende en gran medida de configuraciones como:

Configuración Qué afecta
acks Cuántos acuses de recibo del broker se requieren antes de que una escritura cuente como exitosa
retries Si el productor reintenta fallos transitorios
enable.idempotence Ayuda a evitar duplicados causados por reintentos del productor
compression.type Reduce el uso de red y disco para muchas cargas de trabajo

Para datos importantes, acks=all es común porque el líder espera a las réplicas sincronizadas antes de acusar recibo de la escritura. El comportamiento exacto también depende de configuraciones del broker como min.insync.replicas.

Consumidores y Grupos de Consumidores

Los consumidores leen registros de temas. La mayoría de los consumidores en producción se ejecutan dentro de un grupo de consumidores.

Dentro de un grupo de consumidores, Kafka asigna cada partición a solo un consumidor activo a la vez. Así es como Kafka permite escalar el procesamiento mientras preserva el orden dentro de cada partición.

Por ejemplo, si pedidos tiene tres particiones y tu servicio tiene tres consumidores en el mismo grupo, cada consumidor puede procesar una partición. Si agregas un cuarto consumidor al mismo grupo, un consumidor quedará inactivo porque solo hay tres particiones para asignar.

Diferentes grupos de consumidores obtienen lecturas independientes. Tu servicio de facturación y servicio de análisis pueden leer ambos el tema pedidos sin robarse registros entre sí.

Desplazamientos y Progreso del Consumidor

Los consumidores rastrean el progreso confirmando desplazamientos. Kafka almacena los desplazamientos confirmados para grupos de consumidores en un tema interno llamado __consumer_offsets.

Si un consumidor falla y se reinicia, usa el desplazamiento confirmado para reanudar. El momento de las confirmaciones afecta el comportamiento del procesamiento:

Momento de confirmación Resultado posible
Confirmar antes de que termine el procesamiento Un fallo puede saltar registros
Confirmar después de que termine el procesamiento Un fallo puede reprocesar registros

Muchos sistemas eligen procesamiento al menos una vez: procesar el registro, luego confirmar el desplazamiento. Eso puede crear duplicados después de un fallo, por lo que las escrituras posteriores deben ser idempotentes cuando sea posible.

Metadatos del Clúster: ZooKeeper y KRaft

Los clústeres antiguos de Kafka usan Apache ZooKeeper para gestionar metadatos del clúster y elección del controlador. Muchas instalaciones existentes aún funcionan así.

Las implementaciones más nuevas de Kafka pueden usar el modo KRaft, el quórum de metadatos integrado de Kafka. En clústeres KRaft, Kafka ya no depende de ZooKeeper para la gestión de metadatos.

Cuando leas tutoriales antiguos de Kafka, verifica si asumen ZooKeeper o KRaft. Los comandos, archivos de configuración y pasos operativos pueden diferir.

Cómo se Mueve un Registro a Través de Kafka

Un flujo típico de escritura y lectura se ve así:

  1. Un productor se conecta a un broker bootstrap y obtiene metadatos.
  2. El productor elige una partición basada en la clave del registro o la estrategia de particionado.
  3. El productor envía el registro al broker líder de esa partición.
  4. El líder añade el registro a su registro y los seguidores lo replican.
  5. El líder acusa recibo de la escritura según la configuración acks del productor.
  6. Un consumidor consulta la partición y recibe registros comenzando desde su desplazamiento actual.
  7. El consumidor procesa registros y confirma desplazamientos para su grupo de consumidores.

Este flujo es por qué Kafka puede soportar tanto procesamiento en tiempo real como reproducción. Los consumidores no eliminan registros cuando los leen.

Retención: Kafka Mantiene Datos por Política

Kafka no es una cola tradicional donde un mensaje desaparece tan pronto como un consumidor lo lee. Kafka mantiene registros basándose en configuraciones de retención.

Configuraciones comunes de temas incluyen:

retention.ms=604800000
retention.bytes=10737418240

retention.ms controla la retención basada en tiempo. retention.bytes controla la retención basada en tamaño. La limpieza real también depende de la configuración de segmentos y la configuración del broker.

Algunos temas usan compactación de registros en lugar de, o junto con, la retención basada en eliminación. La compactación mantiene el valor más reciente para cada clave, lo cual es útil para temas similares a estados como perfiles de usuario o cambios de configuración.

Qué Recordar

La arquitectura de Kafka se basa en registros particionados. Los brokers almacenan particiones, los productores escriben en líderes de particiones, los consumidores leen por desplazamiento y los grupos de consumidores dividen el trabajo entre particiones.

Cuando diseñes un tema de Kafka, piensa en el orden, el número de particiones, el factor de replicación, la retención y el comportamiento del grupo de consumidores juntos. Esas elecciones determinan cómo tu sistema escala, se recupera de fallos y reproduce eventos antiguos.