Apache Kafka se ha consolidado como un estándar indispensable para el procesamiento distribuido de mensajes y flujos de datos en tiempo real. Desde su lanzamiento como código abierto, Kafka ha escalado de ser una herramienta interna en LinkedIn a una plataforma ampliamente adoptada a nivel mundial, apoyando casos de uso que van desde mensajería hasta procesamiento de logs y streams complejos. Sin embargo, a pesar de su éxito, Kafka fue conceptualizado en una era donde los centros de datos locales predominaban frente a los entornos en la nube, lo que ocasiona retos significativos cuando se despliega en infraestructuras cloud modernas. Uno de los principales desafíos radica en la acoplación estrecha entre cómputo y almacenamiento dentro de Kafka, donde la escala del almacenamiento obliga a incrementar la cantidad de nodos de cómputo, ocasionando un uso ineficiente de recursos y mayores costos operativos. Además, Kafka emplea replicación para garantizar durabilidad y disponibilidad, lo que implica un fuerte intercambio de datos entre nodos, especialmente costoso en la nube debido a las tarifas por transferencia entre zonas de disponibilidad (AZ) cobradas por proveedores como AWS o Google Cloud.
La tendencia reciente para superar estos contratiempos ha sido la exploración de soluciones Kafka-compatibles que despliegan el almacenamiento completamente en servicios de almacenamiento de objetos como Amazon S3. Esta estrategia promete ahorrar costos, desacoplar el escalado de cómputo y almacenamiento y eliminar la replicación manual debido a que S3 proporciona durabilidad y alta disponibilidad intrínsecas al sistema. Varios proveedores han lanzado propuestas en esta línea, incluida AutoMQ, la única alternativa open-source que garantiza compatibilidad total con el protocolo Kafka. Sin embargo, construir Kafka sobre S3 no es tarea sencilla y presenta una serie de desafíos técnicos profundos. El primero de ellos es la latencia.
Mientras que el acceso a discos SSD NVMe puede ser del orden de microsegundos, las operaciones de lectura (GetObject) y escritura en S3 presentan latencias que pueden llegar a milisegundos, multiplicando por mil esta demora y afectando directamente la experiencia en términos de escritura y lectura de mensajes en tiempo real. Algunos sistemas optan por sacrificar la latencia al confirmar la persistencia del mensaje solo después de escribir en S3, pero esto no cumple con las expectativas de aplicaciones que requieren baja latencia estricta. La solución de AutoMQ para este problema es implementar un sistema de log de adelantado de escritura (Write Ahead Log o WAL) que actúa sobre almacenamiento local como AWS EBS, capaz de garantizar confirmaciones rápidas al productor mientras la escritura a S3 ocurre en segundo plano. Esta arquitectura híbrida permite alcanzar latencias de escritura en el orden de 10 ms en el percentil 99, acercándose más a los requerimientos de baja latencia sin renunciar a los beneficios de escalabilidad y durabilidad de S3. Otro aspecto crítico es el manejo de gran volumen de operaciones de escritura en S3, cuya facturación se calcula a partir del número de solicitudes PUT, lo que puede generar gastos millonarios para servicios con alta tasa de mensajes producidos por segundo.
Para mitigar esta demanda, el buffering y la agrupación de datos en objetos más grandes se convierten en una práctica fundamental. Al combinar segmentos de datos de múltiples particiones o flujos en un único objeto, se reduce la cantidad de peticiones y se optimiza tanto el costo como la performance. No obstante, esta estrategia complica la lectura, pues los datos de una misma partición quedan repartidos en múltiples objetos, lo que podría degradar la eficiencia de lectura por fragmentación. Para contrarrestar esto, AutoMQ incorpora procesos asíncronos de compactación que consolidan la información dispersa en la menor cantidad posible de objetos, facilitando accesos secuenciales rápidos a partir de un número reducido de archivos. El almacenamiento en S3 introduce además consideraciones complejas en la gestión de caché.
Un acceso eficiente a los datos requiere minimizar las solicitudes GET para evitar latencias adicionales y costos elevadas. La solución adopta distintas capas de caché: una para manejar escrituras y lecturas recientes (log cache) y otra para accesos históricos menos frecuentes (block cache). Estrategias como prefetching y lectura por lotes mejoran la probabilidad de aciertos en caché y reducen la presión sobre el almacenamiento de objetos. El manejo de metadatos representa otro reto fundamental. Mientras Kafka puede navegar directamente el sistema de archivos local para obtener información sobre segmentos y particiones, en S3 las operaciones LIST son costosas y lentas.
Por ello, distribuir y mantener metadatos adicionales que mapeen la relación entre streams, segmentos y objetos, así como optimizar su almacenamiento, es indispensable para preservar eficiencia y coherencia. AutoMQ utiliza mecanismos de metadatos organizados en flujos especiales que almacenan relaciones segmentadas, evitando realizar consultas frecuentes y costosas a S3. La compatibilidad absoluta con Kafka es un requisito clave para las alternativas que quieren facilitar la migración sin fricción de los usuarios. Sin embargo, Kafka fue pensado para sistemas de archivos locales con capacidad de acceder y extender archivos de forma secuencial y eficiente, cosa que no es posible con objetos inmutables como los de S3. Mientras proyectos como WarpStream y Bufstream optan por construir un protocolo propio desde cero para optimizarlo para almacenamiento de objetos, AutoMQ adopta la estrategia de reescribir únicamente la capa de almacenamiento, conservando intacto el protocolo Kafka y sus módulos superiores.
Esta decisión permite que todas las funcionalidades, balanceo, coordinación, y manejo de particiones sigan funcionando de manera transparente para los clientes y reduce el esfuerzo de mantener el sistema actualizado con las innovaciones de Kafka. Para ello, AutoMQ redefine internamente conceptos como segmentos y flujos, estructurando la información en múltiples tipos de componentes (meta stream, data stream, transaccional y temporal) que mimetizan las funcionalidades de los archivos indexados y segmentados de Kafka. En cuanto a la arquitectura, la convergencia entre los modelos de almacenamiento compartido (shared disk) y sin estado (shared nothing) se expresa claramente. Kafka tradicionalmente asigna cada partición a un nodo específico para preservar la localización de datos y eficiencia. Con S3, existe la posibilidad teórica de que cualquier nodo acceda a los datos directamente desde el almacenamiento compartido, desatando la necesidad de implementar estrategias de localización para mantener rendimiento y balanceo.
AutoMQ preserva esta localización asignando brokers responsables por partición, facilitando caché local y manteniendo coherencia lógica aunque el almacenamiento resida en un sistema compartido y distribuido. Este enfoque contrasta con otros que optan por omitir la localización durante escrituras para aprovechar el hecho de que cualquier nodo pueda escribir en S3, aunque mantienen restricciones para lecturas para garantizar consistencia. Otro factor notable es el manejo eficiente del throughput y las limitaciones de ancho de banda. La adopción de un modelo sin estado impone que los brokers no solo dirigen mensajes sino que también manejan carga adicional para cálculo, memorización, compactación y gestión de datos en memoria, actividades que requieren separar y priorizar el tráfico de red para evitar congestionamientos. AutoMQ implementa un sistema asíncrono de limitación por niveles de prioridad, utilizando un algoritmo de token bucket y colas de prioridad que otorgan máxima prioridad a flujos de envío de mensajes mientras penalizan operaciones con menor criticidad como la compactación y lecturas históricas.
Finalmente, uno de los mayores beneficios y retos en la nube es la gestión de costos relacionados con la transferencia entre zonas de disponibilidad. Kafka tradicional genera costos elevados por su mecanismo de replicación y la obligatoriedad de que los productores escriban en el líder, que puede estar en una AZ diferente. Mediante el uso de almacenamiento compartido en S3, se elimina el costo de replicación, pero la comunicación inicial entre productor y broker líder puede seguir implicando transferencias interzonas. AutoMQ atenúa este problema implementando un esquema que mapea productores a brokers locales dentro de la misma AZ mediante un algoritmo de hash consistente. Este broker local actúa como intermediario temporal, almacenando los mensajes en un WAL local o en S3 y notificando asíncronamente al líder correcto ubicado en otra AZ.