Broker di messaggi tradizionali e dati di streaming


13

Secondo il sito Kafka :

" Kakfa viene utilizzato per la creazione di pipeline di dati in tempo reale e app di streaming " .

Cercando su Internet in lungo e in largo, ho trovato la seguente definizione generalmente accettata di cosa sono i " dati di flusso ":

  • I dati di flusso sono dati che fluiscono contigui da un'origine a una destinazione su una rete; e
  • I dati di flusso non sono di natura atomica, il che significa che qualsiasi parte di un flusso di dati che scorre è significativa e processabile, al contrario di un file i cui byte non significano nulla a meno che non li possiate tutti; e
  • I dati di flusso possono essere avviati / arrestati in qualsiasi momento; e
  • I consumatori possono collegarsi e staccarsi da un flusso di dati a piacimento ed elaborarne solo le parti che desiderano

Ora, se qualcosa che ho detto sopra è errato, incompleto o totalmente sbagliato, per favore inizia correggendomi! Supponendo che io sia più o meno in pista, quindi ...

Ora che capisco cosa sono i "dati di streaming", allora capisco cosa significano Kafka e Kinesis quando si considerano middleware di elaborazione / intermediazione per applicazioni con dati di streaming. Ma ha suscitato i miei interessi: "streaming middleware" come Kafka o Kinesis può essere usato per dati non streaming, come i broker di messaggi tradizionali? E viceversa: possono / dovrebbero essere usati MQ tradizionali come RabbitMQ, ActiveMQ, Apollo, ecc. Per lo streaming dei dati?

Facciamo un esempio in cui un'applicazione invierà la sua raffica costante di backend di messaggi JSON che devono essere elaborati e l'elaborazione è piuttosto complessa (convalida, trasformazioni sui dati, filtro, aggregazioni, ecc.):

  • Caso n. 1: i messaggi sono ciascuno dei fotogrammi di un film; si tratta di una messaggistica JSON per frame video contenente i dati del frame e alcuni metadati di supporto
  • Caso n. 2: i messaggi sono dati di serie temporali, forse il battito del cuore di qualcuno in funzione del tempo. Quindi viene inviato il messaggio n. 1 che rappresenta il mio battito cardiaco a t = 1, il messaggio n. 2 contiene il mio battito cardiaco a t = 2, ecc.
  • Caso n. 3: i dati sono completamente diversi e non correlati dal tempo o come parte di qualsiasi "flusso di dati". Forse eventi di controllo / sicurezza che vengono generati mentre centinaia di utenti navigano nei pulsanti dell'applicazione facendo clic su azioni

In base alla fatturazione di Kafka / Kinesis e alla mia comprensione di cosa siano i "dati in streaming", sembrano essere ovvi candidati per i Casi n. 1 (dati video contigui) e n. 2 (dati contigui delle serie temporali). Tuttavia, non vedo alcun motivo per cui un broker di messaggi tradizionale come RabbitMQ non sia in grado di gestire in modo efficiente entrambi questi input.

E con il caso n. 3, ci viene fornito solo un evento che si è verificato e dobbiamo elaborare una reazione a tale evento. Quindi per me questo parla della necessità di un broker tradizionale come RabbitMQ. Ma non c'è nemmeno motivo per cui Kafka o Kinesis non possano gestire nemmeno l'elaborazione dei dati degli eventi.

Quindi, fondamentalmente, sto cercando di stabilire una rubrica che dice: ho dati X con caratteristiche Y. Dovrei usare un processore di flusso come Kafka / Kinesis per gestirlo. O, al contrario, uno che mi aiuta a determinare: ho dati W con caratteristiche Z. Dovrei usare un broker di messaggi tradizionale per gestirlo.

Quindi chiedo: quali fattori relativi ai dati (o altrimenti) aiutano a orientare la decisione tra il processore di flusso o il broker dei messaggi, dal momento che entrambi possono gestire i dati di streaming ed entrambi possono gestire i dati dei messaggi (non di streaming)?

Risposte:


5

Kafka si occupa di registri ordinati di messaggi atomici. Puoi visualizzarlo in un modo simile alla pub/submodalità dei broker di messaggi, ma con un ordinamento rigoroso e la possibilità di riprodurre o cercare il flusso di messaggi in qualsiasi punto del passato che è ancora stato conservato sul disco (che potrebbe essere per sempre).

Il sapore dello streaming di Kafka si oppone alla chiamata di procedura remota come Thrift o HTTP e all'elaborazione batch come nell'ecosistema Hadoop. A differenza di RPC, i componenti comunicano in modo asincrono: possono passare ore o giorni tra l'invio di un messaggio e il momento in cui il destinatario si sveglia e agisce su di esso. Potrebbero esserci molti destinatari in diversi punti nel tempo, o forse nessuno si prenderà mai la briga di consumare un messaggio. Più produttori potrebbero produrre sullo stesso argomento senza la conoscenza dei consumatori. Kafka non sa se sei abbonato o se un messaggio è stato consumato. Un messaggio viene semplicemente impegnato nel registro, dove qualsiasi parte interessata può leggerlo.

A differenza dell'elaborazione batch, ti interessano i singoli messaggi, non solo le gigantesche raccolte di messaggi. (Anche se non è raro archiviare i messaggi di Kafka in file Parquet su HDFS e interrogarli come tabelle Hive).

Caso 1 : Kafka non conserva alcuna relazione temporale particolare tra produttore e consumatore. È inadeguato per lo streaming video perché Kafka può rallentare, accelerare, spostarsi in forma e inizia, ecc. Per lo streaming multimediale, vogliamo scambiare il throughput complessivo in cambio di una latenza bassa e, soprattutto, stabile (altrimenti noto come jitter basso). Kafka fa anche molta fatica a non perdere mai un messaggio. Con lo streaming video, in genere utilizziamo UDP e siamo contenti di rilasciare un frame qua e là per mantenere il video in esecuzione. Lo SLA su un processo sostenuto da Kafka è in genere da secondi a minuti quando è sano, da ore a giorni quando è sano. Lo SLA sui media in streaming è in decine di millisecondi.

Netflix potrebbe usare Kafka per spostare i frame in un sistema interno che transcodifica terabyte di video all'ora e lo salva su disco, ma non per spedirli sullo schermo.

Caso 2 : assolutamente. Usiamo Kafka in questo modo presso il mio datore di lavoro.

Caso 3 : puoi usare Kafka per questo tipo di cose, e lo facciamo, ma stai pagando un sovraccarico non necessario per preservare l'ordinazione. Dal momento che non ti interessa l'ordine, probabilmente potresti spremere qualche prestazione in più da un altro sistema. Se la tua azienda gestisce già un cluster Kafka, probabilmente è meglio riutilizzarlo anziché assumersi l'onere della manutenzione di un altro sistema di messaggistica.


1
Grazie @closeparen (+1) - Ricevo quasi tutto quello che dici, con una grande eccezione. Nel tuo paragrafo che inizia con la frase " Il sapore dello streaming di Kafka si oppone ... ", sono propenso a pensare che potrei sostituire la maggior parte delle istanze della parola "Kafka" con "RabbitMQ" e la frase sarebbe vera. Per RabbitMQ: i produttori potrebbero inviare un messaggio e un consumatore lo tirerebbe giù e lo elaborerebbe ore / giorni dopo. I consumatori possono collegarsi a una coda ogni volta che lo desiderano, e quindi per RabbitMQ possono esserci molti destinatari diversi in diversi punti nel tempo.
smeeb

1
Pensa a Kafka come a un motore di database con una particolare struttura orientata ai log. I produttori aggiungono, i consumatori leggono. La lettura non influisce in alcun modo sullo stato di Kafka. Un consumatore può mantenere un cursore incrementale per creare una semantica identica al pub / sub RabbitMQ, e questo è un caso d'uso comune, ma non è l'unico caso d'uso.
closeparen,

1
Pensa a RabbitMQ come a una versione distribuita di una struttura di dati in coda in memoria. Una volta che fai uscire qualcosa da una coda, non è più in coda. Certo, potresti avere una topologia in cui è stata replicata in altre code a beneficio di altri consumatori, ma in genere non potresti dire "dammi il messaggio che ho gestito 500 messaggi fa" o "avvia la coda B come copia della coda A dal punto in cui ieri era la coda A. "
closeparen,

2
Un sistema basato su Kafka sta perdonando. Se non ti piace come si è comportato il tuo programma, puoi fare una modifica al codice e riavvolgerne l'input. Potresti fermare un consumatore RabbitMQ senza influire sui produttori, ma non potresti rivisitare il passato.
closeparen

1
Ahhh: lampadina: grazie (+1 per tutti e 3)! Quindi questo è sicuramente un caso convincente per Kafka: la capacità di rivisitare il passato. Presumo che ci debba essere qualche limite superiore o troncamento in corso giusto? Altrimenti il ​​ricordo di Kafka sarebbe sempre salito. Anche se i dati si riversano sul disco, i file in cui sono archiviati i dati degli argomenti riempirebbero il disco molto rapidamente, sì?
smeeb

5

Kafka / Kinesis è modellato come un flusso. Uno stream ha proprietà diverse rispetto ai messaggi.

  • Gli stream hanno un contesto. Hanno ordine. È possibile applicare le funzioni della finestra sui flussi. Sebbene ogni elemento in uno stream sia significativo, potrebbe essere più significativo con il contesto circostante
  • Poiché gli stream hanno ordine, è possibile utilizzarlo per fare alcune affermazioni sulla semantica dell'elaborazione. Ad esempio, Apache Trident ha una semantica esattamente una volta quando consuma da un flusso Kafka.
  • È possibile applicare funzioni ai flussi. È possibile trasformare uno stream senza effettivamente consumarlo. Puoi consumare pigramente un flusso. Puoi saltare parti di un flusso.
  • Puoi riprodurre intrinsecamente i flussi in Kafka, ma non puoi (senza software aggiuntivo) riprodurre le code dei messaggi. Questo è utile quando non sai ancora cosa vuoi fare con i dati. È anche utile per allenare l'IA.

In genere, utilizzare Kafka per l'elaborazione in streaming offline, utilizzare le code dei messaggi per i messaggi client-server in tempo reale.

Esempi di casi d'uso da pivotal :

Kafka: monitoraggio delle attività del sito Web, metriche, aggregazione dei registri, elaborazione dei flussi, reperimento di eventi e registri di commit

RabbitMQ: messaggistica per scopi generici ..., spesso utilizzato per consentire ai server Web di rispondere rapidamente alle richieste invece di essere costretti a eseguire procedure pesanti in termini di risorse mentre l'utente attende il risultato. Utilizzare quando è necessario utilizzare protocolli esistenti come AMQP 0-9-1, STOMP, MQTT, AMQP 1.0

A volte può essere utile usare entrambi! Ad esempio, nel caso d'uso n. 2, se si trattasse di un flusso di dati proveniente da un pacemaker, avrei un pacemaker che trasmette i dati del battito cardiaco a una coda di messaggi RabbitMQ (utilizzando un protocollo interessante come MQTT) dove viene immediatamente elaborato vedere se il cuore della fonte batte ancora. Ciò potrebbe alimentare un cruscotto e un sistema di risposta alle emergenze. La coda dei messaggi depositerebbe anche i dati delle serie temporali in Kafka in modo da poter analizzare i dati del battito cardiaco nel tempo. Ad esempio, potremmo implementare un algoritmo per rilevare le malattie cardiache osservando le tendenze nel flusso del battito cardiaco.


1
Grazie @ Samuel (+1) - questa è una risposta meravigliosa e aiuta a mettere le cose nel contesto un po 'meglio. In realtà ho alcune domande di follow-up per te (se non ti dispiace), ma sono tutte incernierate / dipendono da un chiarimento iniziale di cui ho bisogno: quando dici " Puoi applicare funzioni ai flussi. Puoi trasformare un flusso senza effettivamente consumarlo ... ", queste funzioni / trasformazioni vengono eseguite su Kafka o devono essere consumate prima che i flussi vengano elaborati tramite funzioni / trasformazioni?
smeeb

1
Significato, si ha KafkaProducer, Kafkae KafkaConsumer. Diciamo che KafkaProducervive all'interno di un'app Java e che KafkaConsumerè in esecuzione su alcune app / backend Ruby. KafkaProducerinvia Message1a Kafka che deve essere trasformato tramite Function1. Dove Function1vive il codice? Su Kafka (corretto) o all'interno di KafkaConsumer(l'app Ruby)?
smeeb

2
Non è possibile eseguire funzioni o eseguire alcuna elaborazione in Kafka stesso. Apache Spark Streaming e Apache Storm sono due framework di elaborazione del flusso distribuito che possono essere utilizzati da Kafka. Funzionano al di fuori di Kafka e si connettono ad esso come se fosse un database. I framework espongono funzioni utili come la divisione, l'aggregazione, il windowing, ecc. Potresti implementare le funzioni di base nel tuo consumatore Ruby, ma consiglio vivamente uno dei framework. spark.apache.org/streaming storm.apache.org/releases/2.0.0-SNAPSHOT/Trident-tutorial.html
Samuel

1
OK, grazie e ancora +1 - sarebbe stato fantastico se Kafka fosse in grado di elaborare i flussi stessi! Quindi, per interpretare l'avvocato del diavolo, non potresti semplicemente avere un consumatore RabbitMQ che tira giù i messaggi da una coda, li aggrega in base al timestamp (o in realtà qualsiasi altro criterio / attributo) ed esegue la stessa finestra e trasforma le funzioni nei dati che Spark Streaming o Storm forniscono?
smeeb

1
Sì, penso che potresti farlo con RabbitMQ perché RabbitMQ ha garanzie sull'ordine dei messaggi. Potresti non essere in grado di farlo con ogni coda di messaggi. E sarebbe complesso da costruire. Ad esempio, se il tuo consumatore RabbitMQ che sta aggregando si arresta in modo anomalo? Con Kafka, puoi tenere traccia di dove nello stream hai elaborato, in modo da poter avviare il tuo consumatore nel punto in cui l'avevi interrotto
Samuel,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.