En una arquitectura distribuida, las comunicaciones entre sistemas forman la base de toda la infraestructura. El rendimiento, la escalabilidad y la fiabilidad de la infraestructura dependen en gran medida de cómo se intercambian y persisten los eventos/mensajes/datos.
Kafka y NATS son dos herramientas populares para manejar streaming y mensajería. Tienen arquitecturas diferentes y diferentes características de rendimiento. Son adecuadas para casos de uso específicos. En este artículo, compararemos las características de NATS con Kafka y explicaremos los casos de uso que abordé en el trabajo.
1. Arquitectura y Complejidad
NATS
La infraestructura de NATS tiene dos componentes principales:
Core NATS
Core NATS es el marco base de mensajería. Esto soporta Publicar-Suscribir (permite que los mensajes se transmitan a múltiples suscriptores), Solicitud-Respuesta (habilita la comunicación sincrónica) y Grupos de Cola (facilita el balanceo de carga entre múltiples suscriptores dentro de un grupo).
Está diseñado para la simplicidad, baja latencia, alto rendimiento y escalabilidad. Funciona muy bien en escenarios que requieren baja latencia y alto rendimiento. Sin embargo, Core NATS por sí solo proporciona solo entrega no garantizada, lo que significa que los mensajes se entregan solo a suscriptores activos. Los datos se perderán si los suscriptores están desconectados. Core NATS es una buena opción cuando la velocidad y la escala tienen prioridad sobre la durabilidad.
JetStream
JetStream aporta capacidades de persistencia a la parte superior de Core NATS. Esto ayudó a proporcionar durabilidad y fiabilidad de los mensajes. Permite que los mensajes o eventos sean persistidos (en disco o memoria) y reproducidos. Los mensajes persistidos pueden ser reproducidos para nuevos suscriptores o suscriptores en recuperación. Con JetStream, los usuarios obtienen características adicionales:
- Retención de flujos: Cuánto tiempo se retienen los mensajes. Puede basarse en tamaño, tiempo o límites de consumidores.
- Durabilidad del consumidor: Permitiendo a los consumidores reanudar desde donde lo dejaron.
- Agradecimiento de mensajes: Esto garantiza la fiabilidad de la entrega.
JetStream añade una capa de complejidad a Core NATS. Sin embargo, esto aporta la característica importante de soportar casos de uso de entrega garantizada, persistencia y capacidad de reproducción.
Kafka
Kafka es un sistema de mensajería distribuida construido sobre una arquitectura de broker basada en registros. Los datos en Kafka se organizan en temas y pueden tener múltiples particiones. Los consumidores están conectados a estas particiones. Esta arquitectura permite a Kafka paralelizar el consumo de mensajes para un solo tema. Los datos se añaden a un tema/particiones de forma secuencial. Kafka garantiza el orden en una partición. En un clúster de Kafka, puede haber muchos brokers, cada uno gestionando una lista de temas y particiones. Para lograr alta disponibilidad y prevenir la pérdida de datos, Kafka se basa en un factor de replicación, donde las particiones se replican en múltiples brokers de Kafka. Como puedes ver, hay múltiples componentes que deben ser gestionados para lograr un alto rendimiento, tolerancia a fallos, retención de datos y escalabilidad horizontal. Esto aumenta la complejidad arquitectónica de Kafka.
2. Alta Disponibilidad y Rendimiento
NATS
Todos los nodos en un clúster están interconectados en una malla, y el cliente puede conectarse a cualquier nodo. Esta configuración evita un único punto de fallo. Si un nodo falla, el cliente se conecta automáticamente a los otros nodos sin ninguna intervención manual. Esto se llama auto-sanación en NATS. Un nodo habilitado para JetStream distribuye los flujos entre todos los nodos. Los flujos son altamente gestionados y equilibrados en carga entre los nodos habilitados para JetStream dentro de un clúster de malla.
JetStream también soporta la replicación de datos entre múltiples clústeres o nodos. En JetStream, se eligen líderes por flujo. La replicación de cada flujo puede ser configurada. Todas estas cosas aseguran la durabilidad y disponibilidad en NATS.
Kafka
La alta disponibilidad de Kafka se basa en la replicación. Cada tema puede tener una o más particiones. Cada partición se replica en los Brokers de Kafka. Esto asegura la redundancia y disponibilidad de los datos. Kafka sigue un mecanismo de replicación Líder-Seguidor. Un líder se encarga de la lectura y escritura. Y el seguidor trabaja en replicar los datos.
Kafka mantiene algo llamado ISR (In Sync Replicas) para cada partición. Si el líder falla, uno de los ISR se convierte en líder. Para la gestión de metadatos del clúster y la elección de líder, Kafka depende de Zookeeper (KRaft en las versiones más nuevas).
Performance and Scalability
|
||
---|---|---|
Característica
|
NATS
|
Kafka
|
Rendimiento
|
Alta o baja latencia. Optimizado para mensajes pequeños
|
Optimizado para alto rendimiento y mensajes grandes
|
Escala
|
Escalabilidad horizontal con clustering
|
Escalabilidad horizontal con particionamiento
|
Latencia
|
Sub milisegundos
|
Milisegundos
|
Recovery and FAILOver
|
||
---|---|---|
Característica
|
NATS
|
Kafka
|
Tiempo de conmutación
|
Sub-segundo (Clientes se reconectan más rápido)
|
Más lento (Depende del proceso de elección del líder)
|
Recuperación sin interrupciones
|
Los clientes se reconectan automáticamente sin interrupciones
|
Algo de tiempo de inactividad durante la elección del líder
|
Riesgo de pérdida de datos
|
Mínimo con replicación (JetStream)
|
Mínimo si la replicación y el ISR están configurados
|
3. Patrones de mensajes
NATS
NATS utiliza mensajería basada en sujetos. Esto permite a los servicios y flujos utilizar los patrones de Pub-Sub, Petición-Respuesta y Cola de Suscriptores. Los sujetos en NATS pueden ser construidos con jerarquía y comodines. Un solo flujo de NATS puede almacenar múltiples sujetos y las aplicaciones de cliente pueden utilizar filtrado en el lado del servidor para recibir solo los sujetos de interés. La conexión en NATS es bidireccional y permite a los clientes publicar y suscribirse al mismo tiempo. NATS también soporta encolamiento muy similar a RabbitMQ.
Kafka
Los flujos en Kafka admiten mensajería de Pub-Sub y basada en temas. El equilibrio de carga se puede lograr a través de grupos de consumidores y particionando los temas.
4. Garantías de entrega
NATS
NATS soporta varias garantías de entrega. NATS solo puede soportar una garantía de entrega de “a lo sumo una vez”. Los servidores de NATS con JetStream habilitado pueden soportar dos tipos adicionales de garantías. Son garantías de “al menos una vez” y “exactamente una vez”. NATS puede enviar ‘acks’ a mensajes individuales. Por favor, consulte la documentación oficial de NATS para conocer los diversos ‘acks’ que soporta. Basado en el tipo de ‘acks’, NATS puede volver a entregar mensajes.
Kafka
Kafka soporta garantías de “al menos una vez” y “exactamente una vez”. El orden de los mensajes está garantizado a nivel de partición. El orden global no es posible en Kafka.
5. Retención y Persistencia de Mensajes
NATS
NATS soporta persistencia en memoria y basada en archivos. Hay varias opciones para reproducir el mensaje. La reproducción de mensajes puede ser por tiempo, cantidad o número de secuencia.
Kafka
KAFKA solo admite persistencia basada en archivos. Los mensajes se pueden reproducir desde el último, el primero o un offset específico. La Compactación de Logs es compatible en KAFKA.
6. Idiomas y Plataforma
NATS
Cuarenta y ocho tipos de clientes conocidos. Cualquier arquitectura que admita GOLANG puede admitir servidores NATS.
Kafka
Dieciocho tipos de clientes conocidos. Los servidores de Kafka pueden ejecutarse en plataformas que admiten JVM.
Casos de Uso
Caso de Uso 1
Requisitos
Tenemos una plataforma de datos con un canal de transmisión. La plataforma utiliza el motor Apache Flink para la transmisión en tiempo real y Apache Beam para escribir el canal de análisis. A continuación se presentan los requisitos clave:
- Procesamiento de mensajes de alto rendimiento y baja latencia
- Soporte para control de checkpoint y presión inversa
- Manejar mensajes en MB
- Durabilidad y persistencia de mensajes
Comparación
Ventajas de Kafkas:
- Alto rendimiento
- Retención de datos con políticas de retención configurables y replicación de datos para tolerancia a fallos
- Soporte para al menos una garantía de entrega de mensajes
- Lectura de mensajes desde los desplazamientos más tempranos/más recientes/específicos
- ‘Acks’ del servidor para una entrega fiable
- Manejo de flujos de datos masivos y mensajes de gran tamaño
- Soporte para Tema de Compactación
Desventajas de Kafka:
- Alto uso de recursos. Nuestro clúster estaba en las instalaciones y con recursos limitados
- Kafka es solo casi en tiempo real
Ventajas de NATS:
- Alto rendimiento con un uso mínimo de recursos. El nuestro es un clúster en las instalaciones con restricciones de recursos
- Soporte para al menos una vez. Estábamos buscando una garantía de al menos una vez
- Procesamiento de mensajes de baja latencia
Desventajas de NATS:
- No hay conectores para Flink/Beam, por lo que la integración fue difícil
- Reducción de rendimiento con el tamaño del mensaje
Decisión final
Después de un análisis cuidadoso, se eligió Kafka. Tuvimos que hacer un compromiso entre el uso de recursos y los otros beneficios que ofrecía Kafka, especialmente la buena integración disponible con Apache Beam y Flink. Otra ventaja de Kafka fue su manejo de grandes tamaños de mensajes y el procesamiento de mensajes de alto rendimiento.
Caso de uso 2
Requisitos
Manejar los eventos generados en un clúster en las instalaciones, Ej: Registros de auditoría. Los eventos deben ser procesados con baja latencia. Y soportar la comunicación entre microservicios. La durabilidad y persistencia no eran un requisito. El tamaño del mensaje era pequeño. No era necesario hacer ningún análisis sobre los eventos. Estábamos en un entorno restringido. El uso de recursos y la huella de memoria deben ser mínimos.
Decisión
Por qué se eligió NATS:
- Uso eficiente de recursos
- Manejo de eventos de baja latencia.
- Dado que es una aplicación de Go, la huella de memoria es muy baja
- Capacidad para manejar tamaños de mensaje pequeños
- Soporte de solicitud-respuesta que puede ayudar en la comunicación entre Microservicios
- Cuando JetStream no está configurado, los mensajes no se almacenan
Por qué no se eligió Kafka:
- Por defecto, los mensajes se almacenan en disco
- El uso de recursos es alto en comparación con NATS
- Dado que necesita JVM, la huella de memoria es muy alta
Resumen
La elección entre Kafka y NATS depende de sus requisitos específicos en tres áreas clave: Arquitectura y Complejidad, Rendimiento y Escalabilidad, y Garantías de Entrega de Mensajes. Kafka es ideal para sistemas que requieren un robusto flujo de eventos, almacenamiento duradero y capacidades de procesamiento avanzadas, pero viene con una mayor complejidad. NATS, por otro lado, es ligero, fácil de gestionar y sobresale en escenarios de baja latencia y alto rendimiento con necesidades de mensajería más simples.
Cuando diseñe un sistema de mensajería distribuida, evalúe cuidadosamente estas áreas para alinear su elección con los objetivos y limitaciones de su aplicación. Tanto Kafka como NATS son herramientas poderosas, y la elección correcta dependerá de su caso de uso.
Áreas clave a considerar antes de elegir entre Kafka y NATS:
- Arquitectura y complejidad
- Alta disponibilidad y rendimiento
- Garantías de entrega de mensajes
Kafka es ideal para sistemas distribuidos que requieren transmisión de eventos, almacenamiento duradero y capacidades de procesamiento avanzadas. Sin embargo, Kafka viene con un alto uso de recursos y una huella de memoria. Y la complejidad de gestión es muy alta en comparación con NATS.
Por otro lado, NATS es ligero y fácil de gestionar. El procesamiento de mensajes de baja latencia es la capacidad distintiva de NATS.
En última instancia, tanto Kafka como NATS son herramientas poderosas para el manejo de eventos. La elección depende de casos de uso específicos.
Source:
https://dzone.com/articles/kafka-vs-nats-message-processing