Brokers de mensagens tradicionais e dados de streaming

13

De acordo com o site Kafka :

"O Kakfa é usado para criar pipelines de dados em tempo real e aplicativos de streaming " .

Pesquisando na Internet em toda parte, encontrei a seguinte definição geralmente aceita do que são " dados de fluxo ":

  • Dados de fluxo são dados que fluem contiguamente de uma fonte para um destino em uma rede; e
  • Os dados do fluxo não são de natureza atômica, o que significa que qualquer parte do fluxo de dados é significativa e processável, em oposição a um arquivo cujos bytes não significam nada, a menos que você tenha todos eles; e
  • Os dados do fluxo podem ser iniciados / parados a qualquer momento; e
  • Os consumidores podem anexar e desanexar de um fluxo de dados à vontade e processar apenas as partes desejadas

Agora, se algo que eu disse acima estiver incorreto, incompleto ou totalmente errado, comece me corrigindo! Supondo que estou mais ou menos no caminho certo, então ...

Agora que entendo o que são "dados em fluxo", entendo o que Kafka e Kinesis querem dizer quando se autodenominam como middleware de processamento / intermediação para aplicativos com dados em fluxo. Mas isso despertou meus interesses: o "fluxo de middleware" como Kafka ou Kinesis pode / deve ser usado para dados que não são de fluxo contínuo, como os intermediários de mensagens tradicionais? E vice-versa: os MQs tradicionais como RabbitMQ, ActiveMQ, Apollo etc. podem ser usados ​​para transmitir dados?

Vamos dar um exemplo em que um aplicativo enviará sua barragem constante de mensagens JSON que precisam ser processadas e o processamento é bastante complexo (validação, transformações nos dados, filtragem, agregações etc.):

  • Caso nº 1: as mensagens são cada quadro de um filme; essa é uma bagagem JSON por quadro de vídeo que contém os dados do quadro e alguns metadados de suporte
  • Caso 2: As mensagens são dados de séries temporais, talvez os batimentos cardíacos de alguém em função do tempo. Portanto, a mensagem nº 1 é enviada representando meu batimento cardíaco em t = 1, a mensagem nº 2 contém meu batimento cardíaco em t = 2, etc.
  • Caso nº 3: os dados são completamente díspares e não relacionados ao tempo ou como parte de qualquer "fluxo de dados". Talvez os eventos de auditoria / segurança sejam disparados quando centenas de usuários navegam no aplicativo clicando nos botões e realizando ações

Com base em como o Kafka / Kinesis é cobrado e no meu entendimento sobre o que são "dados de streaming", eles parecem candidatos óbvios para os Casos 1 (dados de vídeo contíguos) e 2 (dados de séries temporais contíguas). No entanto, não vejo nenhuma razão para que um mediador de mensagens tradicional como o RabbitMQ não possa lidar com essas duas entradas com eficiência.

E no Caso # 3, somos fornecidos apenas a um evento que ocorreu e precisamos processar uma reação a esse evento. Então, para mim, isso diz respeito à necessidade de um corretor tradicional como o RabbitMQ. Mas também não há razão para que Kafka ou Kinesis não possam lidar com o processamento de dados de eventos.

Então, basicamente, estou procurando estabelecer uma rubrica que diz: Tenho X dados com características Y. Eu deveria usar um processador de fluxo como o Kafka / Kinesis para lidar com isso. Ou, inversamente, um que me ajude a determinar: eu tenho dados W com características Z. Eu devo usar um intermediário de mensagens tradicional para lidar com isso.

Por isso, pergunto: Quais fatores sobre os dados (ou não) ajudam a orientar a decisão entre o processador de fluxo ou o intermediário de mensagens, pois ambos podem lidar com dados de fluxo contínuo e ambos podem lidar com dados de mensagem (sem fluxo contínuo)?

smeeb
fonte

Respostas:

5

Kafka lida com registros ordenados de mensagens atômicas. Você pode vê-lo como o pub/submodo de intermediários de mensagens, mas com uma ordem estrita e a capacidade de reproduzir ou procurar o fluxo de mensagens em qualquer ponto do passado que ainda esteja sendo mantido em disco (o que pode ser para sempre).

O sabor de streaming de Kafka se opõe à chamada de procedimento remoto, como Thrift ou HTTP, e ao processamento em lote, como no ecossistema Hadoop. Ao contrário do RPC, os componentes se comunicam de forma assíncrona: podem passar horas ou dias entre o envio de uma mensagem e o momento em que o destinatário acorda e age sobre ela. Pode haver muitos destinatários em diferentes momentos, ou talvez ninguém se dê ao trabalho de consumir uma mensagem. Vários produtores poderiam produzir o mesmo tópico sem o conhecimento dos consumidores. Kafka não sabe se você está inscrito ou se uma mensagem foi consumida. Uma mensagem é simplesmente confirmada no log, onde qualquer parte interessada pode lê-la.

Ao contrário do processamento em lote, você está interessado em mensagens únicas, não apenas em coleções gigantes de mensagens. (Embora não seja incomum arquivar mensagens Kafka em arquivos Parquet no HDFS e consultá-las como tabelas do Hive).

Caso 1 : Kafka não preserva nenhuma relação temporal específica entre produtor e consumidor. É um ajuste inadequado para a transmissão de vídeo porque o Kafka pode desacelerar, acelerar, entrar em ação e iniciar, etc. Para a mídia de streaming, queremos trocar a taxa de transferência geral em troca da latência baixa e, mais importante, estável (caso contrário, conhecido como jitter baixo). Kafka também se esforça ao máximo para nunca perder uma mensagem. Com o streaming de vídeo, normalmente usamos UDP e nos contentamos em soltar um quadro aqui e ali para manter o vídeo em execução. O SLA em um processo suportado por Kafka geralmente é de segundos a minutos, quando íntegro, horas ou dias, quando íntegro. O SLA da mídia de streaming está em dezenas de milissegundos.

A Netflix pode usar o Kafka para mover quadros em um sistema interno que transcodifica terabytes de vídeo por hora e os salva em disco, mas não para enviá-los para a tela.

Caso 2 : Absolutamente. Usamos Kafka dessa maneira no meu empregador.

Caso 3 : você pode usar o Kafka para esse tipo de coisa, e nós o fazemos, mas você está pagando uma sobrecarga desnecessária para preservar os pedidos. Como você não se importa com a ordem, provavelmente poderá extrair um pouco mais de desempenho de outro sistema. Porém, se sua empresa já mantém um cluster Kafka, é melhor reutilizá-lo, em vez de assumir a carga de manutenção de outro sistema de mensagens.

perto
fonte
1
Obrigado @closeparen (+1) - Entendo muito do que você está dizendo, com uma grande exceção. No seu parágrafo que começa com a frase " O sabor de streaming de Kafka se opõe ... ", estou inclinado a pensar que poderia substituir a maioria das instâncias da palavra "Kafka" por "RabbitMQ", e a frase seria verdadeira. Para o RabbitMQ: os produtores poderiam enviar uma mensagem e um consumidor a retiraria e a processaria horas / dias depois. Os consumidores podem se conectar a uma fila a qualquer momento e, portanto, para o RabbitMQ, pode haver muitos destinatários diferentes em diferentes momentos.
21817 Sueeb
1
Pense no Kafka como um mecanismo de banco de dados com uma estrutura orientada a log peculiar. Os produtores acrescentam, os consumidores leem. A leitura não afeta o estado de Kafka de forma alguma. Um consumidor pode manter um cursor incremental para criar semântica idêntica à publicação / sub RabbitMQ, e esse é um caso de uso comum, mas não é o único caso de uso.
closeparen
1
Pense no RabbitMQ como uma versão distribuída de uma estrutura de dados da fila na memória. Depois que você tira algo de uma fila, ele não está mais na fila. Claro, você pode ter uma topologia em que foi replicada para outras filas para o benefício de outros consumidores, mas geralmente não seria capaz de dizer "me dê a mensagem que eu manusei há 500 mensagens atrás" ou "inicie a Fila B como uma cópia da fila A de onde estava a fila A ontem ".
closeparen
2
Um sistema baseado em Kafka é perdoador. Se você não gostar do comportamento do seu programa, poderá fazer uma alteração no código e depois retroceder sua entrada. Você pode parar um consumidor RabbitMQ sem afetar os produtores, mas não poderá revisitar o passado.
closeparen
1
Ahhh: lâmpada: obrigado (+1 para todos os 3)! Portanto, esse é definitivamente um caso convincente para Kafka: a capacidade de revisitar o passado. Eu suponho que tem que haver algum limite superior ou truncamento acontecendo certo? Caso contrário, a memória de Kafka sempre estaria subindo. Mesmo se os dados derramarem no disco, os arquivos nos quais os dados do tópico estão armazenados preencheriam o disco muito rapidamente, sim?
smeeb
5

Kafka / Kinesis é modelado como um fluxo. Um fluxo tem propriedades diferentes das mensagens.

  • Os fluxos têm contexto para eles. Eles têm ordem. Você pode aplicar funções de janela em fluxos. Embora cada item em um fluxo seja significativo, ele pode ser mais significativo com o contexto ao seu redor
  • Como os fluxos têm ordem, você pode usá-lo para fazer determinadas declarações sobre a semântica do processamento. Por exemplo, o Apache Trident supostamente tem semântica exata ao consumir de um fluxo Kafka.
  • Você pode aplicar funções aos fluxos. Você pode transformar um fluxo sem realmente consumi-lo. Você pode consumir preguiçosamente um fluxo. Você pode pular partes de um fluxo.
  • É possível reproduzir inerentemente os fluxos no Kafka, mas não é possível (sem software adicional) reproduzir as filas de mensagens. Isso é útil quando você nem sabe o que deseja fazer com os dados ainda. Também é útil para treinar IA.

Geralmente, use Kafka para processamento de fluxo offline, use filas de mensagens para mensagens cliente-servidor em tempo real.

Exemplos de casos de uso do pivotal :

Kafka: rastreamento de atividades do site, métricas, agregação de logs, processamento de fluxo, fornecimento de eventos e logs de confirmação

RabbitMQ: sistema de mensagens de uso geral ..., geralmente usado para permitir que os servidores da Web respondam às solicitações rapidamente, em vez de serem forçados a executar procedimentos com muitos recursos, enquanto o usuário aguarda o resultado. Use quando você precisar usar protocolos existentes, como AMQP 0-9-1, STOMP, MQTT, AMQP 1.0

Às vezes, pode ser útil usar os dois! Por exemplo, no Caso de Uso 2, se esse fosse um fluxo de dados de um marcapasso, eu faria com que o marcapasso transmitisse dados de pulsação para uma fila de mensagens RabbitMQ (usando um protocolo legal como o MQTT), onde são processados ​​imediatamente para veja se o coração da fonte ainda está batendo. Isso poderia alimentar um painel e um sistema de resposta a emergências. A fila de mensagens também depositaria os dados da série temporal no Kafka, para que pudéssemos analisar os dados da pulsação ao longo do tempo. Por exemplo, podemos implementar um algoritmo para detectar doenças cardíacas observando tendências no fluxo de batimentos cardíacos.

Samuel
fonte
1
Obrigado @Samuel (+1) - esta é uma resposta maravilhosa e ajuda a colocar as coisas em contexto um pouco melhor. Na verdade, tenho algumas perguntas de acompanhamento para você (se você não se importa), mas todas elas dependem de um esclarecimento inicial que preciso: quando você diz " Você pode aplicar funções a fluxos. Você pode transformar um fluxo" sem realmente consumi-lo ... ", essas funções / transformações são executadas no Kafka ou precisam ser consumidas primeiro antes que os fluxos sejam processados ​​por meio de funções / transformações?
S7e
1
Ou seja, você tem KafkaProducer, Kafkae KafkaConsumer. Digamos que KafkaProducermora dentro de um aplicativo Java, e isso KafkaConsumerestá sendo executado em algum aplicativo / back-end Ruby. KafkaProducerenvia Message1para Kafka que precisa ser transformado via Function1. Onde fica Function1o código? No Kafka (apropriado) ou dentro do KafkaConsumer(aplicativo Ruby)?
S7e
2
Você não pode executar funções ou fazer qualquer processamento no próprio Kafka. O Apache Spark Streaming e o Apache Storm são duas estruturas de processamento de fluxo distribuído que podem consumir do Kafka. Eles correm para fora do Kafka e se conectam a ele como se fosse um banco de dados. As estruturas expõem funções úteis como divisão, agregação, janelas, etc. Você pode implementar funções básicas no seu consumidor Ruby, mas eu recomendaria altamente uma das estruturas. spark.apache.org/streaming storm.apache.org/releases/2.0.0-SNAPSHOT/Trident-tutorial.html
Samuel
1
OK, obrigado e +1 novamente - isso seria incrível se o Kafka pudesse processar os próprios fluxos! Portanto, para interpretar o advogado do diabo, você não pode apenas ter um consumidor RabbitMQ puxando mensagens de uma fila, agregando-as com base no carimbo de data / hora (ou realmente em qualquer outro critério / atributo) e executando a mesma janela e transformando funções nos dados que o Spark Streaming ou Storm fornecer?
smeeb
1
Sim, acho que você poderia fazer isso com o RabbitMQ porque o RabbitMQ tem garantias sobre a ordem das mensagens. Talvez você não consiga fazer isso em todas as filas de mensagens. E seria complexo de construir. Por exemplo, e se o consumidor RabbitMQ que estiver agregando falhar? Com Kafka, você pode manter o controle de onde no fluxo você processados até, para que possa iniciar o seu consumidor no ponto em que parou
Samuel