Explica la arquitectura de Kafka — brokers, particiones y grupos de consumidores — y cómo logran escalar sin perder el orden
Kafka escala dividiendo los topics en particiones repartidas entre brokers, y usa grupos de consumidores para paralelizar la lectura — pero el orden solo está garantizado dentro de una partición, no en todo el topic.
APRENDE HACIENDOPon a prueba tu intuición3 pasos
Explica la arquitectura de Kafka — brokers, particiones y grupos de consumidores — y cómo logran escalar sin perder el orden
Usa los ejemplos y la explicación de la lección para comprobar tu idea.
Reflexión personal. No se envía a ningún servicio de IA.Apache Kafka no es una cola de mensajes tradicional: es un log de commits distribuido y de solo-append que además soporta semántica de publicación/suscripción. Esa distinción explica casi todas las decisiones de arquitectura que vienen después, y suele ser el punto donde una respuesta de nivel senior se separa de una de principiante.
#Topics, particiones y brokers
Un topic es un flujo de eventos con nombre, por ejemplo order-events. Kafka divide cada topic en una o más particiones, y son las particiones —no los topics— la unidad real de almacenamiento, paralelismo y orden. Cada partición es una secuencia ordenada e inmutable de registros, identificados por un offset que crece de forma monótona. Las particiones se reparten entre los brokers (los servidores del clúster); para tolerar fallos, cada partición se replica en N brokers, uno de los cuales es elegido líder. Todas las lecturas y escrituras de esa partición pasan por el líder; el resto son réplicas (followers) que copian el log y pueden asumir el liderazgo si el líder cae.
El número de réplicas sincronizadas (ISR, in-sync replicas) que ya alcanzaron al líder determina qué tan durable puede ser una escritura. El parámetro acks del productor controla ese trade-off directamente:
| acks | Comportamiento | Durabilidad | Latencia |
|---|---|---|---|
0 | Dispara y olvida | Ninguna — posible pérdida silenciosa de datos | La más baja |
1 | El líder escribe en su log local | Se pierde si el líder falla antes de replicar | Media |
-1 / all | Todas las réplicas sincronizadas confirman la escritura | Sobrevive a la caída del líder | La más alta |
#El orden es por partición, no por topic
Este es el detalle que más exploran los entrevistadores: Kafka garantiza el orden solo dentro de una misma partición. Si un topic tiene 6 particiones, no existe un orden global entre ellas — mensajes producidos casi al mismo tiempo pueden leerse en órdenes relativos distintos según la partición. Si necesitas que todos los eventos de una misma entidad (un usuario, una orden, una cuenta) se procesen en el orden en que ocurrieron, debes enrutarlos a la misma partición usando la misma clave de partición. Kafka aplica un hash a la clave para elegir la partición de forma determinista, así que orderId=123 siempre cae en la misma partición, y un único hilo consumidor la lee de vuelta en el orden en que se escribió.
#Escalar la lectura con grupos de consumidores
Un consumer group (grupo de consumidores) es el mecanismo de Kafka para escalar el consumo horizontalmente manteniendo cada partición asignada a un único consumidor a la vez. Cuando varios procesos consumidores comparten un groupId, el coordinador de grupo de Kafka asigna cada partición a exactamente un consumidor de ese grupo — así, un topic con 6 particiones puede consumirse en paralelo con hasta 6 consumidores del mismo grupo; un séptimo consumidor quedaría inactivo. Por eso el número de particiones es tu verdadero techo de escalado, no el número de consumidores.
Los distintos consumer groups son totalmente independientes entre sí: cada grupo recibe su propia copia de todo el stream y lleva sus propios offsets. Así es como un mismo topic puede alimentar a la vez a un servicio de facturación y a uno de analítica sin que uno afecte la posición de lectura del otro.
Cuando un consumidor se une, se retira o falla, Kafka dispara un rebalance: las particiones se reasignan entre los miembros restantes del grupo. Los rebalances pausan brevemente el consumo del grupo completo, por lo que reinicios frecuentes o un session.timeout.ms demasiado agresivo pueden dañar visiblemente el throughput en producción.
#Productor y consumidor en la práctica
const { Kafka, logLevel } = require('kafkajs');const kafka = new Kafka({clientId: 'orders-service',brokers: ['broker1:9092', 'broker2:9092', 'broker3:9092'],logLevel: logLevel.INFO,});// --- Productor: un mensaje con key garantiza orden por entidad ---async function publishOrderEvent(order) {const producer = kafka.producer({ allowAutoTopicCreation: false });await producer.connect();await producer.send({topic: 'order-events',messages: [{key: order.orderId, // misma key -> misma partición -> entrega en ordenvalue: JSON.stringify({ type: 'ORDER_CREATED', ...order }),headers: { 'event-version': '1' },},],acks: -1, // esperar a todas las réplicas sincronizadas antes de dar la escritura por durabletimeout: 30000,});await producer.disconnect();}// --- Consumidor: un miembro del consumer group, hace commit manual del offset ---async function startBillingConsumer() {const consumer = kafka.consumer({ groupId: 'billing-service' });await consumer.connect();await consumer.subscribe({ topic: 'order-events', fromBeginning: false });await consumer.run({autoCommit: false, // hacer commit solo después de aplicar el efecto de forma seguraeachMessage: async ({ topic, partition, message }) => {const event = JSON.parse(message.value.toString());await chargeCustomer(event); // debe ser idempotente — puede haber reentregasawait consumer.commitOffsets([{ topic, partition, offset: (Number(message.offset) + 1).toString() },]);},});}
La postura por defecto de Kafka es "at-least-once": si un consumidor falla después de procesar un mensaje pero antes de confirmar su offset, ese mensaje se reentrega y se reprocesa. Existe la semántica exactly-once (productores idempotentes más escrituras transaccionales entre topics), pero añade overhead real y solo cubre pipelines Kafka-a-Kafka — en el momento en que tu consumidor hace algo externo (cobra una tarjeta, envía un correo), vuelves a necesitar un handler idempotente sin importar lo que Kafka garantice por su cuenta.
🧠 Check your understanding
0/3 · 0/3 answered1. Un topic tiene 4 particiones. Un mismo consumer group tiene 6 instancias de consumidor suscritas. ¿Qué ocurre?
2. ¿Por qué Kafka solo garantiza el orden dentro de una misma partición y no en todo el topic?
3. ¿Qué te da configurar acks=-1 (o 'all') en el productor?