Corredores de mensajes tradicionales y datos de transmisión

13

Según el sitio de Kafka :

" Kakfa se utiliza para construir canalizaciones de datos en tiempo real y aplicaciones de transmisión " .

Buscando en Internet a lo largo y ancho, he encontrado la siguiente definición generalmente aceptada de lo que es " transmisión de datos ":

  • Los datos de flujo son datos que fluyen de manera contigua desde un origen a un destino a través de una red; y
  • Los datos de flujo no son de naturaleza atómica, lo que significa que cualquier parte de un flujo de datos que fluye es significativa y procesable, a diferencia de un archivo cuyos bytes no significan nada a menos que tenga todos ellos; y
  • Los datos de flujo se pueden iniciar / detener en cualquier momento; y
  • Los consumidores pueden adjuntar y desconectarse de una secuencia de datos a voluntad, y procesar solo las partes que deseen

Ahora bien, si algo de lo que dije anteriormente es incorrecto, incompleto o totalmente incorrecto, ¡comience por corregirme! Asumiendo que estoy más o menos encaminado, entonces ...

Ahora que entiendo qué es la "transmisión de datos", entiendo lo que Kafka y Kinesis quieren decir cuando se consideran a sí mismos como middleware de procesamiento / intermediación para aplicaciones con transmisión de datos. Pero ha despertado mis intereses: ¿se puede / debe "transmitir middleware" como Kafka o Kinesis para datos que no se transmiten, como los corredores de mensajes tradicionales? Y viceversa: ¿pueden / deberían usarse MQ tradicionales como RabbitMQ, ActiveMQ, Apollo, etc. para transmitir datos?

Tomemos un ejemplo en el que una aplicación enviará su constante descarga de mensajes JSON que deben procesarse, y el procesamiento es bastante complejo (validación, transformación de los datos, filtrado, agregaciones, etc.):

  • Caso n. ° 1: los mensajes son cuadros de una película; es un mensaje JSON por cuadro de video que contiene los datos del cuadro y algunos metadatos de soporte
  • Caso # 2: Los mensajes son datos de series de tiempo, tal vez el latido de alguien en función del tiempo. Entonces, el mensaje n. ° 1 se envía representando mi latido en t = 1, el mensaje n. ° 2 contiene mi latido en t = 2, etc.
  • Caso # 3: Los datos son completamente dispares y no están relacionados por tiempo o como parte de cualquier "flujo de datos". Quizás eventos de auditoría / seguridad que se disparan cuando cientos de usuarios navegan por la aplicación haciendo clic en los botones y realizando acciones

Basado en cómo se facturan los Kafka / Kinesis y en mi comprensión de lo que son los "datos de transmisión", parecen ser candidatos obvios para los Casos n. ° 1 (datos contiguos de video) y n. ° 2 (datos contiguos de series de tiempo). Sin embargo, no veo ninguna razón por la cual un agente de mensajes tradicional como RabbitMQ no pueda manejar eficientemente ambas entradas también.

Y con el Caso # 3, solo se nos proporciona un evento que ha ocurrido y necesitamos procesar una reacción a ese evento. Entonces, para mí esto habla de necesitar un corredor tradicional como RabbitMQ. Pero tampoco hay razón para que Kafka o Kinesis no puedan manejar el procesamiento de datos de eventos.

Básicamente, estoy buscando establecer una rúbrica que diga: Tengo datos X con características Y. Debería usar un procesador de flujo como Kafka / Kinesis para manejarlo. O, por el contrario, uno que me ayuda a determinar: tengo datos W con características Z. Debería usar un agente de mensajes tradicional para manejarlo.

Entonces, pregunto: ¿Qué factores sobre los datos (o de otro modo) ayudan a dirigir la decisión entre el procesador de flujo o el intermediario de mensajes, ya que ambos pueden manejar datos de transmisión y ambos pueden manejar datos de mensajes (sin transmisión)?

smeeb
fuente

Respuestas:

5

Kafka trata en registros ordenados de mensajes atómicos. Puede verlo como el pub/submodo de los corredores de mensajes, pero con un orden estricto y la capacidad de reproducir o buscar en la secuencia de mensajes en cualquier momento en el pasado que aún se conserva en el disco (lo que podría ser para siempre).

El sabor de Kafka de la transmisión se opone a la llamada a procedimientos remotos como Thrift o HTTP, y al procesamiento por lotes como en el ecosistema Hadoop. A diferencia de RPC, los componentes se comunican de forma asíncrona: pueden pasar horas o días entre el momento en que se envía un mensaje y cuando el destinatario se despierta y actúa sobre él. Podría haber muchos destinatarios en diferentes momentos, o tal vez nadie se molestará en consumir un mensaje. Múltiples productores podrían producir para el mismo tema sin el conocimiento de los consumidores. Kafka no sabe si está suscrito o si se ha consumido un mensaje. Un mensaje simplemente se confirma en el registro, donde cualquier parte interesada puede leerlo.

A diferencia del procesamiento por lotes, le interesan los mensajes individuales, no solo las colecciones gigantes de mensajes. (Aunque no es raro archivar mensajes de Kafka en archivos de Parquet en HDFS y consultarlos como tablas de Hive).

Caso 1 : Kafka no conserva ninguna relación temporal particular entre productor y consumidor. No es adecuado para la transmisión de video porque a Kafka se le permite reducir la velocidad, acelerar, adaptarse y comenzar, etc. Para la transmisión de medios, queremos cambiar el rendimiento general a cambio de una latencia baja y, lo que es más importante, estable conocido como bajo jitter). Kafka también se esfuerza mucho para nunca perder un mensaje. Con la transmisión de video, generalmente usamos UDP y estamos contentos de soltar un cuadro aquí y allá para mantener el video en funcionamiento. El SLA en un proceso respaldado por Kafka es típicamente de segundos a minutos cuando está sano, de horas a días cuando está sano. El SLA en los medios de transmisión está en decenas de milisegundos.

Netflix podría usar Kafka para mover fotogramas en un sistema interno que transcodifica terabytes de video por hora y lo guarda en el disco, pero no para enviarlos a su pantalla.

Caso 2 : absolutamente. Usamos Kafka de esta manera en mi empleador.

Caso 3 : Puede usar Kafka para este tipo de cosas, y lo hacemos, pero está pagando algunos gastos generales innecesarios para preservar el pedido. Como no le importa el orden, probablemente podría exprimir un poco más el rendimiento de otro sistema. Sin embargo, si su empresa ya mantiene un clúster de Kafka, probablemente sea mejor reutilizarlo en lugar de asumir la carga de mantenimiento de otro sistema de mensajería.

closeparen
fuente
1
Gracias @closeparen (+1): entiendo la mayoría de lo que dices, con una gran excepción. En su párrafo que comienza con la oración " El sabor de transmisión de Kafka se opone ... ", me inclino a pensar que podría reemplazar la mayoría de las instancias de la palabra "Kafka" con "RabbitMQ", y la oración sería cierta. Para RabbitMQ: los productores podrían enviar un mensaje y un consumidor lo retiraría y lo procesaría horas / días después. Los consumidores pueden adjuntar a una cola en cualquier momento que deseen, por lo que para RabbitMQ, puede haber muchos destinatarios diferentes en diferentes momentos.
smeeb
1
Piense en Kafka como un motor de base de datos con una estructura peculiar orientada a registros. Los productores agregan, los consumidores leen. La lectura no afecta el estado de Kafka de ninguna manera. Un consumidor puede mantener un cursor incremental para crear una semántica idéntica a RabbitMQ pub / sub, y este es un caso de uso común, pero no es el único caso de uso.
closeparen
1
Piense en RabbitMQ como una versión distribuida de una estructura de datos de cola en memoria. Una vez que saca algo de la cola, ya no está en la cola. Claro, es posible que tenga una topología en la que se haya replicado en otras colas para beneficio de otros consumidores, pero generalmente no podría decir "dame el mensaje que manejé hace 500 mensajes" o "iniciar la cola B como una copia de la cola A desde donde estaba ayer la cola A ".
closeparen
2
Un sistema basado en Kafka es indulgente. Si no le gusta cómo se comportó su programa, puede impulsar un cambio de código y luego rebobinar su entrada. Podría detener a un consumidor de RabbitMQ sin afectar a los productores, pero no podría volver a visitar el pasado.
closeparen
1
Ahhh: bombilla: ¡gracias (+1 por las 3)! Así que este es definitivamente un caso convincente para Kafka: la capacidad de volver a visitar el pasado. Supongo que tiene que haber algún límite superior o truncamiento, ¿verdad? De lo contrario, la memoria de Kafka siempre estaría escalando. Incluso si los datos se vierten al disco, los archivos donde se almacenan los datos del tema llenarían el disco muy rápidamente, ¿sí?
smeeb
5

Kafka / Kinesis se modela como una secuencia. Una secuencia tiene propiedades diferentes que los mensajes.

  • Las corrientes tienen contexto para ellos. Tienen orden Puede aplicar funciones de ventana en secuencias. Aunque cada elemento en una secuencia es significativo, puede ser más significativo con el contexto que lo rodea
  • Debido a que las transmisiones tienen orden, puede usar eso para hacer ciertas declaraciones sobre la semántica del procesamiento. Por ejemplo, Apache Trident supuestamente tiene una semántica exactamente única cuando se consume de una corriente de Kafka.
  • Puede aplicar funciones a las secuencias. Puede transformar una secuencia sin consumirla realmente. Puedes perezosamente consumir una corriente. Puede omitir partes de una secuencia.
  • Inherentemente puede reproducir transmisiones en Kafka, pero no puede (sin software adicional) reproducir colas de mensajes. Esto es útil cuando aún no sabe qué quiere hacer con los datos. También es útil para entrenar IA.

En general, use Kafka para el procesamiento de flujo fuera de línea, use colas de mensajes para mensajes cliente-servidor en tiempo real.

Ejemplos de casos de uso de pivotal :

Kafka: seguimiento de actividad del sitio web, métricas, agregación de registros, procesamiento de flujo, aprovisionamiento de eventos y registros de confirmación

RabbitMQ: mensajería de propósito general ..., a menudo utilizada para permitir que los servidores web respondan a las solicitudes rápidamente en lugar de verse obligados a realizar procedimientos con muchos recursos mientras el usuario espera el resultado. Úselo cuando necesite usar protocolos existentes como AMQP 0-9-1, STOMP, MQTT, AMQP 1.0

¡A veces puede ser útil usar ambos! Por ejemplo, en el caso de uso n.º 2, si se tratara de una secuencia de datos de un marcapasos, diría que el marcapasos transmita datos de latidos a una cola de mensajes RabbitMQ (usando un protocolo genial como MQTT) donde se procesa inmediatamente para mira si el corazón de la fuente aún late. Esto podría alimentar un tablero de instrumentos y un sistema de respuesta de emergencia. La cola de mensajes también depositaría los datos de series temporales en Kafka para que pudiéramos analizar los datos de latidos a lo largo del tiempo. Por ejemplo, podríamos implementar un algoritmo para detectar enfermedades del corazón notando tendencias en la corriente del latido del corazón.

Samuel
fuente
1
Gracias @Samuel (+1): esta es una respuesta maravillosa y ayuda a poner las cosas en contexto un poco mejor. De hecho, tengo algunas preguntas de seguimiento para usted (si no le importa), pero todas dependen de una aclaración inicial que necesito: cuando dice " Puede aplicar funciones a las secuencias. Puede transformar una secuencia sin consumirlo realmente ... ", ¿esas funciones / transformaciones se ejecutan en Kafka , o necesitan ser consumidas primero antes de que los flujos se procesen a través de funciones / transformaciones?
smeeb
1
Significado, tienes KafkaProducer, Kafkay KafkaConsumer. Digamos que KafkaProducervive dentro de una aplicación Java, y que KafkaConsumerse ejecuta en alguna aplicación / backend de Ruby. KafkaProducerenvía Message1a Kafka que necesita ser transformado a través de Function1. ¿Dónde vive Function1el código? ¿En Kafka (correcto) o dentro de KafkaConsumer(la aplicación Ruby)?
smeeb
2
No puede ejecutar funciones ni realizar ningún procesamiento en Kafka. Apache Spark Streaming y Apache Storm son dos marcos de procesamiento de flujo distribuido que pueden consumir desde Kafka. Se ejecutan fuera de Kafka y se conectan como si fuera una base de datos. Los marcos exponen funciones útiles como dividir, agregar, ventanas, etc. Puede implementar funciones básicas en su consumidor Ruby, pero le recomendaría uno de los marcos. spark.apache.org/streaming storm.apache.org/releases/2.0.0-SNAPSHOT/Trident-tutorial.html
Samuel
1
OK, gracias y +1 nuevamente, ¡eso hubiera sido increíble si Kafka pudiera hacer el procesamiento en las transmisiones en sí! Entonces, para jugar al abogado del diablo, ¿no podría simplemente hacer que un consumidor de RabbitMQ retire los mensajes de una cola, los agregue en función de la marca de tiempo (o realmente cualquier otro criterio / atributo), y realice la misma ventana y transforme las funciones a los datos que Spark ¿Streaming o Storm proporcionan?
smeeb
1
Sí, creo que podría hacer eso con RabbitMQ porque RabbitMQ tiene garantías sobre el orden de los mensajes. Es posible que no pueda hacerlo con cada cola de mensajes. Y sería complejo de construir. Por ejemplo, ¿qué pasa si su consumidor RabbitMQ que está agregando se bloquea? Con Kafka, puede realizar un seguimiento de en qué parte de la transmisión ha procesado, para que pueda iniciar su consumidor en el punto donde lo dejó
Samuel