Linee guida per il dimensionamento dei carichi di lavoro basati su Kafka

Apache Kafka è noto per la sua capacità di elaborare una enorme quantità di eventi in tempo reale. Tuttavia, per gestire milioni di eventi, è necessario seguire determinate best practice durante l’implementazione sia dei servizi produttori che dei servizi consumatori di Kafka.

Prima di iniziaread utilizzare Kafkanei tuoi progetti, cerchiamo di capire quando utilizzare Kafka:

  • Flussi di eventi ad alto volume.Quando la tua applicazione/servizio genera un flusso continuo di eventi come eventi di attività dell’utente, eventi di clic sul sito web, eventi di dati del sensore, eventi di logging o aggiornamenti del mercato azionario, la capacità di Kafka di gestire grandi volumi con bassa latenza risulta molto utile.
  • Analisi in tempo reale. Kafka è particolarmenteutile nella creazione di pipeline di elaborazione dei dati in tempo reale, dove i dati devono essere elaborati non appena arrivano. Consente di trasmettere dati a motori di analisi come Kafka Streams, Apache Spark o Flink per analisi/insight immediati e per l’elaborazione in streaming o batch.
  • Decoupling delle applicazioni. Agendo come un centro di messaggi centrale, può separare le diverse parti di un’applicazione, consentendo lo sviluppo e la scalabilità indipendenti dei servizi e promuovendo il principio della segregazione responsabile.
  • Integrazione dei dati tra i sistemi. Quando si integrano sistemi distribuiti, Kafka può trasferire efficientemente i dati tra diverse applicazioni tra squadre/progetti, agendo come un affidabile intermediario dei dati.

Differenze chiave rispetto ad altri sistemi di messaggistica.

Sotto sono elencate le differenze di Apache Kafka rispetto a sistemi come ActiveMQ, ZeroMQ e VerneMQ:

Archiviazione persistente

Kafka archivia gli eventi in un log distribuito, consentendo la possibilità di riprodurre i dati in qualsiasi momento e la persistenza dei dati anche in caso di guasti del sistema/nodo, a differenza di alcune code di messaggi tradizionali, che potrebbero fare affidamento su archiviazione in memoria come Redis.

Partizionamento

I dati sono partizionati tra i broker/argomenti, consentendo l’elaborazione parallela di grandi flussi di dati e un’elevata capacità di trasferimento. Questo aiuta i thread dei consumatori a connettersi a partizionamenti individuali, promuovendo la scalabilità orizzontale.

Gruppi di consumatori

Diversi consumatori possono sottoscriversi allo stesso argomento e leggere da offset diversi all’interno di una partizione, consentendo modelli di consumo duplicati per diverse squadre per consumare e elaborare gli stessi dati per scopi diversi. Alcuni esempi sono:

  • Attività degli utenti consumata dai team di ML per rilevare attività sospette
  • Squadra di raccomandazione per creare raccomandazioni
  • Squadra degli annunci per generare annunci pertinenti

Linee guida per il produttore Kafka

Dimensione del batch e tempo di attesa

Configurando batch.size e linger.ms, è possibile aumentare il throughput del tuo produttore Kafka. batch.size è la dimensione massima del batch in byte. Kafka cercherà di raggruppare i messaggi prima di inviarli ai produttori. 

Linger.ms determina il tempo massimo in millisecondi che il produttore aspetterà per aggiungere ulteriori messaggi al batch per l’elaborazione. 

La configurazione delle impostazioni batch size e linger.ms migliora significativamente le prestazioni del sistema controllando la quantità di dati accumulati prima dell’invio ai sistemi di elaborazione, consentendo un migliore throughput e latenze ridotte quando si gestiscono grandi volumi di dati. Può anche introdurre leggeri ritardi a seconda dei valori scelti. In particolare, una grande dimensione del batch con un linger.ms corretto può ottimizzare l’efficienza del trasferimento dei dati.

Compressione

Un altro modo per aumentare la velocità di trasferimento è abilitare la compressione tramite la configurazione compression.type. Il produttore può comprimere i dati con gzip, snappy o lz4 prima di inviarli ai broker. Per grandi volumi di dati, questa configurazione aiuta ad ottimizzare l’overhead di compressione con l’efficienza di rete. Inoltre, risparmia larghezza di banda e aumenta la velocità di trasferimento del sistema. Inoltre, impostando il serializzatore appropriato e il serializzatore di chiavi, possiamo garantire che i dati vengano serializzati in un formato compatibile con i consumatori.

Ritentativi e Idempotenza

Per garantire l’affidabilità del produttore di Kafka, è necessario abilitare i ritentativi e l’idempotenza. Configurando retries, il produttore può inviare automaticamente nuovamente qualsiasi batch di dati che non riceve l’ack dal broker entro un numero specificato di tentativi.

Acknowledgments

Questa configurazione controlla il livello di acknowledgment richiesto dal broker prima di considerare un messaggio inviato con successo. Scegliendo il livello di acks corretto, è possibile controllare l’affidabilità dell’applicazione. Di seguito sono riportati i valori accettati per questa configurazione.

  • 0 – il più veloce, ma senza garanzia di consegna del messaggio.
  • 1 – il messaggio viene riconosciuto una volta che è stato scritto sul broker leader, fornendo una affidabilità di base.
  • tutti – il messaggio viene considerato consegnato solo quando tutti i replica lo hanno riconosciuto, garantendo un’alta durabilità.

Configurazione-Tuning in base al carico di lavoro

dovresti iniziare a monitorare metriche come il tasso di invio dei messaggi, la dimensione dei batch e i tassi di errore per identificare i colli di bottiglia delle prestazioni. Controlla e regola regolarmente le impostazioni del produttore in base alle modifiche o agli aggiornamenti delle funzionalità/dei dati.

Pratiche Migliori per il Consumatore Kafka

Gruppi di Consumatori

Ogni consumatore Kafka dovrebbe appartenere a un gruppo di consumatori; un gruppo di consumatori può contenere uno o più consumatori. Creando più consumatori nel gruppo, puoi scalare per leggere da tutte le partizioni, consentendoti di elaborare un enorme volume di dati. La configurazione group.id aiuta aidentificare il gruppo di consumatori a cui appartiene il consumatore, consentendo il bilanciamento del carico tra più consumatori che consumano dallo stesso argomento. La migliore pratica è quella di utilizzare ID di gruppo significativi per identificare facilmente i gruppi di consumatori all’interno della tua applicazione.

Impegno degli Offset

Puoi controllare quando la tua applicazione impegna gli offset, il che può aiutare a evitare la perdita di dati. Ci sono due modi per impegnare gli offset: automatico e manuale. Per applicazioni ad alta capacità, dovresti considerare l’impegno manuale per un migliore controllo.

  • auto.offset.reset – definisce cosa fare quando un consumatore inizia a consumare un topic senza offset impegnati (ad esempio, un nuovo topic o un consumatore che si unisce a un gruppo per la prima volta). Le opzioni includono earliest (leggere dall’inizio), latest (leggere dalla fine) o none (generare un errore). Scegliere “earliest” per la maggior parte dei casi d’uso per evitare la perdita di dati quando un nuovo consumatore si unisce a un gruppo.Controlla come un consumatore inizia a consumare dati, garantendo un comportamento corretto quando un consumatore viene riavviato o aggiunto a un gruppo.
  • enable.auto.commitaiuta a configurare per impegnare automaticamente gli offset periodicamente. In generale, impostiamo il valore su false per la maggior parte degli scenari di produzione in cui non è necessaria un’elevata affidabilità e impegniamo manualmente gli offset all’interno della logica dell’applicazione per garantire un elaborazione esatta una volta sola. Fornisce il controllo per gestire i commit degli offset, consentendo un maggiore controllo sul processo dei dati.
  • auto.commit.interval.ms l‘intervallo in millisecondi in cui gli offset vengono automaticamente confermati se enable.auto.commit è impostato su true. Modifica in base al tempo di elaborazione della tua applicazione per evitare perdite di dati a causa di guasti imprevisti.

Dimensione di recupero e record massimi di polling

Questa configurazione aiuta a controllare il numero di record recuperati in ogni richiesta, configura fetch.min.bytes e max.poll.records. Aumentare questo valore può aiutare a migliorare il throughput delle tue applicazioni riducendo al contempo l’uso della CPU e il numero di chiamate effettuate ai broker.

  • fetch.min.bytes – il minimo numero di byte da recuperare da un broker in una singola richiesta di polling. Imposta un valore piccolo per evitare chiamate di rete non necessarie, ma non troppo piccolo per evitare polling eccessivo. Aiuta a ottimizzare l’efficienza della rete prevenendo richieste piccole e frequenti.
  • fetch.max.bytes il massimo numero di byte da recuperare da un broker in una singola richiesta di polling. Regolare in base alla memoria disponibile per evitare sovraccarichi ai lavoratori consumatori. Questo riduce la quantità di dati recuperati in un singolo sondaggio, evitando problemi di memoria.
  • max.poll.interval.ms – il tempo massimo da attendere per una richiesta di sondaggio prima di scadere. Impostare un timeout adeguato per evitare blocchi/ritardi dei consumatori se i dati non sono disponibili. Aiuta a evitare che i consumatori rimangano bloccati in attesa di messaggi per troppo tempo. (A volte, i pod k8s possono riavviarsi se le sonde di vitalità sono compromesse).

Assegnazione delle Partizioni

Questa è la strategia utilizzata per assegnare le partizioni (partition.assignment.strategy) ai consumatori all’interno di un gruppo (ad es., range, roundrobin). Utilizzare range per la maggior parte degli scenari per distribuire uniformemente le partizioni tra i consumatori. Questo consente una distribuzione equilibrata del carico tra i consumatori in un gruppo.

Ecco alcune considerazioni importanti prima di utilizzare Kafka:

  • ComplessitàImplementare Kafka richiede una comprensione più profonda dei concetti dei sistemi distribuiti come la partizione e la gestione degli offset a causa delle sue funzionalità avanzate e delle configurazioni.
  • Monitoraggio e gestione. Implementare il monitoraggio e la gestione del cluster Kafka è importante per garantire alta disponibilità e prestazioni.
  • SicurezzaImplementare pratiche di sicurezza robuste per proteggere i dati sensibili che scorrono attraverso i topic Kafka è anch’esso importante.

Implementare queste migliori pratiche può aiutarti a scalare le tue applicazioni basate su Kafka per gestire milioni/miliardi di eventi. Tuttavia, è importante ricordare che la configurazione ottimale può variare in base ai requisiti specifici della tua applicazione.

Source:
https://dzone.com/articles/best-practices-for-scaling-kafka-based-workloads