El error más fácil en event streaming es tratar el número de particiones como algo que puedes corregir después. No puedes, al menos no en un topic con clave sin romper permanentemente las garantías de orden por clave. El segundo error más fácil es dimensionar los brokers a partir de cifras de throughput pico obtenidas de un benchmark que no refleja tu hardware, tu factor de replicación ni tu topología de consumidores. Ambos errores suelen aparecer en el peor momento posible: durante un pico de tráfico, no en una tranquila prueba del martes por la tarde.

Este artículo analiza las tres decisiones de dimensionamiento más importantes antes de llevar una carga de trabajo de producción a un clúster compatible con Kafka: el número de particiones, el diseño de los consumer groups y los recursos de los brokers. Los principios subyacentes aplican tanto si usas Kafka estándar como un servicio gestionado compatible; señalaremos en qué se comporta de forma diferente NATS JetStream, que utilizamos como backbone de event streaming en producción, y por qué esas diferencias importan a la hora de planificar capacidad.

Dimensionamiento de particiones: la decisión que no puedes deshacer fácilmente

El enfoque canónico para dimensionar particiones, que Jun Rao articuló en Confluent en 2015 y que sigue siendo la base de la documentación oficial de Confluent, es sencillo en principio: divide tu throughput objetivo por el throughput por partición que tu hardware puede sostener, una vez para el camino de producción y otra para el de consumo, y toma el mayor de los dos resultados. La fórmula te obliga a comprometerte con una constante de throughput por partición antes de conocer tu carga de trabajo real, que es donde la mayoría de los planes fallan.

El rango de cifras publicadas de throughput por partición es lo suficientemente amplio como para ser peligroso. El pipeline Keystone de Netflix utiliza entre 0,5 y 1 MB/s por partición como constante de planificación conservadora para su carga de trabajo específica. La guía de Conduktor para 2025, orientada a clústeres Kafka 3.0+ bien ajustados sobre hardware NVMe moderno, sitúa el techo en 50 a 100 MB/s por partición. Estas cifras no son contradictorias: la de Netflix es una subestimación deliberada diseñada para tener margen; la de Conduktor es un techo de hardware alcanzable solo con un ajuste cuidadoso. Usa la constante equivocada para tu contexto y terminarás con demasiadas particiones o con muy pocas.

Un punto de partida práctico para la mayoría de las cargas de trabajo de producción en hardware estándar es entre 1 y 3 MB/s por partición como constante de planificación; luego somete esa suposición a pruebas de estrés contra tu disco y red reales antes de finalizar la configuración del topic. La propia guía de Confluent recomienda mantenerse entre 100 y 200 particiones por broker como línea base, con una advertencia explícita de no superar las 4.000 particiones por broker, ya que la sobrecarga del controlador a esa escala puede desestabilizar el clúster. Conduktor señala que los clústeres Kafka 4.0 con CPU, memoria y E/S de disco adecuados pueden superar ese límite, pero se trata de una excepción para hardware ajustado, no de una suposición por defecto.

Añadir particiones a un topic con clave después de su creación es una puerta de un solo sentido. El particionador por defecto utiliza murmur2(key) % partition_count para enrutar mensajes, por lo que cambiar el número de particiones re-enruta silenciosamente claves que antes estaban colocadas juntas, rompiendo el orden para cualquier consumidor que asumía una asignación estable. Aprovisiona en exceso al crear el topic y no alteres los topics con clave.

El imperativo de aprovisionar en exceso no es precaución teórica: es el patrón de producción documentado en LinkedIn, Shopify, Cloudflare y Confluent. Los clústeres de LinkedIn ejecutaban más de 7 millones de particiones en más de 4.000 brokers procesando más de 7 billones de mensajes al día en 2023. Desarrollaron herramientas propias para emitir métricas de throughput por partición porque Kafka no las expone de forma nativa, y ejecutan Cruise Control en cada clúster para el rebalanceo de particiones. Si tus herramientas no te dan visibilidad por partición, estás volando a ciegas sobre la métrica que más importa.

Un detalle que con frecuencia genera bugs de ordenamiento en producción son las claves nulas. En Kafka 2.4 y versiones posteriores, las claves nulas activan el sticky partitioner, que agrupa mensajes en una sola partición durante una ventana configurable antes de cambiar. En versiones anteriores, las claves nulas se distribuyen en round-robin entre todas las particiones. En cualquier caso, los mensajes con clave nula no tienen garantía de orden entre particiones, y mezclar mensajes con clave y sin clave en el mismo topic es una forma fiable de introducir condiciones de carrera sutiles en el procesamiento posterior.

Los límites de descriptores de archivo son una preocupación a nivel de broker que el número de particiones impulsa directamente. La fórmula estándar es el número de particiones multiplicado por el tamaño de partición dividido por el tamaño de segmento. La recomendación habitual tanto de Cloudera como de LinkedIn es empezar con al menos 100.000 descriptores de archivo por broker y ajustar al alza a medida que crece el número de particiones. No tener esto en cuenta durante el aprovisionamiento produce errores crípticos bajo carga en lugar de fallos de capacidad claros.

Throughput de consumer groups: el techo de particiones y cómo sortearlo

Kafka impone un techo estricto al paralelismo de consumidores: un consumer group puede tener como máximo un consumidor activo por partición. Añadir un undécimo consumidor a un grupo asignado a un topic de diez particiones te da un standby inactivo, no más throughput. Este acoplamiento entre el número de particiones y el paralelismo de consumidores es la razón por la que las decisiones de dimensionamiento tomadas al crear el topic limitan tus opciones de escalado meses después.

El consumidor en standby no es inútil: proporciona failover rápido si un consumidor activo falla. Pero si tu requisito de throughput crece más allá de lo que soporta tu número actual de particiones, tus únicas opciones son aumentar las particiones (con la advertencia sobre el orden de claves mencionada antes), usar un modelo de consumidor multihilo o reestructurar el topic. Kafka 4.0 introdujo los Share Groups como un nuevo modelo de consumidores destinado a romper la restricción de un consumidor por partición, pero el estado GA y la semántica de producción de los Share Groups en 4.0 no estaban confirmados en las fuentes disponibles; trátalo como una funcionalidad a seguir, no como un dato de planificación actual.

El rebalanceo es la otra trampa de capacidad del lado del consumidor. Kafka pausa el procesamiento de todos los consumidores de un grupo durante un rebalanceo mientras recalcula las asignaciones de particiones. En entornos con auto-scaling o consumidores efímeros, los cambios frecuentes de membresía significan pausas frecuentes. La estrategia de asignación cooperative sticky reduce el coste del rebalanceo manteniendo las asignaciones existentes donde sea posible y migrando solo las particiones que necesitan moverse, lo que la convierte en el valor por defecto correcto para cualquier despliegue donde el número de consumidores cambia dinámicamente.

En cuanto al ajuste fino, tres parámetros dominan el throughput del consumidor. fetch.min.bytes indica al broker que espere hasta haber acumulado al menos esa cantidad de datos antes de responder, sacrificando latencia a cambio de eficiencia en lotes. fetch.max.wait.ms establece el límite superior de esa espera. max.poll.records controla cuántos registros procesa el consumidor por ciclo de poll; aumentarlo incrementa el throughput pero también el tiempo de procesamiento por ciclo, lo que puede disparar el timeout de sesión y provocar un rebalanceo si tu lógica de procesamiento es lenta. Estos tres parámetros interactúan entre sí, y ajustar uno sin los demás es una fuente habitual de rebalanceos inesperados.

Dimensionamiento de brokers: las tres restricciones que limitan tu clúster

El dimensionamiento de brokers se reduce a tres techos de throughput independientes, y el mínimo de los tres es el límite real de tu clúster. La fórmula documentada de AWS para esto tiene en cuenta: el throughput de almacenamiento multiplicado por el número de brokers dividido por el factor de replicación; el throughput de red entre brokers y almacenamiento (relevante para almacenamiento conectado en red) multiplicado por el número de brokers dividido por el factor de replicación; y el throughput de red del host o de EC2 multiplicado por el número de brokers dividido por la suma de consumer groups más el factor de replicación menos uno. Calcula los tres y tu clúster estará limitado por el menor de ellos.

El dimensionamiento de memoria sigue una heurística simple: reserva para 30 segundos de throughput de escritura. Un broker con 64 GB de RAM es un punto de partida razonable para cargas de trabajo moderadas, pero el principio más importante es que Kafka depende en gran medida de la page cache de Linux para el rendimiento de lectura. Un aprovisionamiento insuficiente de RAM degrada el throughput de lectura antes de que aparezca como presión sobre la CPU, lo que convierte a la memoria en el recurso más frecuentemente subestimado en los despliegues iniciales.

El throughput de red suele ser el primer cuello de botella en la práctica, no la CPU. Un topic con factor de replicación 3 y 5 consumer groups activos multiplica tu throughput de ingesta bruto por 8 en la red del broker: 3 por replicación y 5 por fan-out. Dimensiona las NICs de tus brokers y tu red entre brokers en consecuencia, no solo para la ingesta.

Operamos infraestructura gestionada compatible con Kafka bajo el mismo SLA de nivel Tier III, ISO 27001 y 99,9% de disponibilidad contractual que cubre el resto de nuestra plataforma, con la soberanía de datos como garantía contractual y no como argumento de marketing. Eso significa que el margen de capacidad que incorporamos al aprovisionamiento de brokers es auditable y consistente, no una función de ratios de sobrecompromiso en tenencia compartida que varían bajo carga. Las decisiones de dimensionamiento anteriores son las que nuestros ingenieros toman para cada nuevo despliegue de streaming; los principios se aplican independientemente de dónde ejecutes tu infraestructura.

Poniéndolo todo junto: una lista de verificación previa al lanzamiento

  • Define el número de particiones al crear el topic. Usa tu throughput objetivo dividido por una constante conservadora por partición (1 a 3 MB/s en hardware estándar) y redondea generosamente hacia arriba para topics con clave.
  • Nunca cambies el número de particiones de un topic con clave en producción. Si debes escalar, crea un nuevo topic y migra los consumidores.
  • Ajusta el número de consumidores al número de particiones por grupo. Los consumidores extra son standby para failover, no throughput adicional.
  • Usa la asignación cooperative sticky en cualquier entorno donde la membresía del consumer group cambie dinámicamente.
  • Ajusta fetch.min.bytes, fetch.max.wait.ms y max.poll.records de forma conjunta, no de forma independiente.
  • Dimensiona la memoria del broker pensando primero en la page cache, no solo en el heap de la JVM.
  • Calcula los tres techos de throughput (almacenamiento, red de almacenamiento, red del host) y diseña para el mínimo.
  • Configura los límites de descriptores de archivo en al menos 100.000 por broker antes de alcanzar los recuentos de particiones de producción.
  • Instrumenta el throughput por partición. Kafka no lo expone de forma nativa; implementa o adopta herramientas que lo hagan antes de necesitarlas.