Nota

Migrazione del cluster Kafka e Zookeeper senza tempi di inattività

Introduzione

Molti servizi (cloud-native o on-premise) utilizzano i cluster Kafka per le loro esigenze di messaggistica asincrona in quanto è una tecnologia di messaggistica che si ridimensiona correttamente. Possono verificarsi situazioni in cui è necessario sostituire un set di nodi o l'intero cluster a causa di esigenze aziendali. Questa esercitazione descrive la migrazione del cluster Kafka e Zookeeper a un nuovo set di nodi senza tempi di inattività.

La dichiarazione del problema

Perché sostituire un nodo in un cluster con un altro potrebbe essere una sfida? L'aggiunta o la rimozione di un nodo da un set di nodi dietro un load balancer è onnipresente: aggiungere un nuovo nodo, svuotare il nodo esistente da rimuovere, una volta terminate tutte le connessioni in esecuzione, arrestarlo, rimuoverlo dalla configurazione del load balancer e così via.

La vera sfida sta nella gestione dello stato con un'applicazione. Di solito, le applicazioni sono stateless e delegano la persistenza dello stato a un sistema di gestione dei dati, ad esempio un sistema di gestione di database relazionale (RDBMS). A differenza di tali applicazioni, sia Kafka che Zookeeper gestiscono lo stato localmente, ovvero la persistenza dello stato viene eseguita utilizzando dischi locali. Ciò significa che non possiamo semplicemente sostituire un nodo con un altro senza occuparci dello stato locale del nodo esistente.

Inoltre, nel caso di Kafka, semplicemente aggiungendo un nodo, non avvia automaticamente alcun ribilanciamento del carico di lavoro, vale a dire, la ridistribuzione delle partizioni di argomento tra i broker. Il nuovo nodo partecipa solo alla condivisione del carico di lavoro per i nuovi argomenti creati da questo punto in poi.

Un problema operativo con i sistemi basati sul quorum (in questo caso Zookeeper) è che devono conoscere in anticipo le dimensioni del cluster, il che significa che ogni nodo deve avere conoscenza di tutti gli altri nodi del cluster. Inoltre, per complicare ulteriormente le cose, se si aggiungono più nodi (il numero esatto dipende dalla dimensione del cluster esistente) in un'unica operazione, è necessario assicurarsi che uno dei nuovi nodi aggiunti non diventi il leader altrimenti perdiamo i dati.

Obiettivi

Prerequisiti

Eseguire la migrazione del cluster Kafka

La sostituzione dei nodi nel cluster Kafka è relativamente semplice. Aggiungi nuovi broker e richiama la migrazione delle partizioni di argomento e una volta completata la migrazione, possiamo disattivare il vecchio broker. Kafka fornisce l'API di amministrazione per eseguire la migrazione della partizione. Il file alterPartitionReassignments funziona aggiungendo ulteriori repliche di partizione a un argomento, attende che diventino membri di ISR e quindi scambia il leader di partizione.

È necessario disabilitare le assegnazioni delle nuove partizioni argomento ai vecchi broker (se la logica dell'applicazione crea argomenti in runtime), altrimenti questo diventerebbe un loop infinito di migrazione. Per raggiungere questo obiettivo, è possibile utilizzare una variante dell'API di creazione dell'argomento in cui è possibile specificare l'assegnazione della partizione da soli. L'algoritmo di esempio che può essere seguito è elencato di seguito.

Passi di alto livello per la migrazione che possono essere seguiti con la contabilità (per il riavvio in caso di arresto o errore nel mezzo del processo di migrazione).

  1. È stato specificato e completato il mapping tra ID broker precedente e nuovo.

  2. Utilizzare AdminClient per verificare se sono disponibili nuovi broker. Se non tutti sono disponibili, generare un errore e terminare.

  3. Utilizzare AdminClient per verificare se l'argomento <kafka_topic_migration> esiste nel cluster.

    • Se l'argomento <kafka_topic_migration> non esiste, crearlo assegnando manualmente le repliche ai nuovi broker. Questo argomento viene utilizzato per la gestione dei registri di argomenti già riassegnati e indica che è stata eseguita la migrazione.
  4. Leggere l'argomento <kafka_topic_migration> dall'inizio utilizzando un consumer. Ogni messaggio è un nome di argomento che è stato riassegnato ai nuovi broker.

  5. Utilizzare AdminClient per elencare tutti gli argomenti disponibili nel cluster. Da questa lista, rimuovere l'argomento <kafka_topic_migration>.

  6. Dai due passaggi precedenti, trova gli argomenti da riassegnare ai nuovi broker.

  7. Per ogni argomento:

    1. Creare una mappa Map<TopicPartition,Optional<NewPartitionReassignment>> reassignment = new HashMap<>();.

    2. Utilizzando AdminClient, descrivere l'argomento per trovare le relative partizioni.

    3. Per ciascuna partizione:

      1. Preparare un oggetto NewPartitionReassignment sostituendo ogni vecchio ID replica (vecchio ID broker) con il corrispondente nuovo ID broker. Se il mapping degli ID broker non contiene la chiave corrispondente all'ID replica, registrare un'avvertenza e utilizzare l'ID corrente (il motivo più probabile è che questo argomento sia già stato migrato e che non sia stata eseguita la contabilità).

      2. Aggiungere questa voce alla mappa.

    4. Utilizzare AdminClient per avviare la riassegnazione richiamando il metodo alterPartitionReassignments.

    5. Eseguire un loop per verificare se la riassegnazione è stata completata elencando le riassegnazione in corso (listPartitionReassignments) e verificandone le dimensioni pari a zero. Dormi di N secondi tra un ciclo e l'altro.

    6. Verificare che le nuove repliche di ciascuna partizione corrispondano alle repliche desiderate.

    7. Eseguire il PUSH del nome di questo argomento come messaggio nell'argomento <kafka_topic_migration>.

  8. Ripetere i passi da 4 a 6, se non ci sono più argomenti da riassegnare e terminare.

Una volta completata la migrazione, possiamo disattivare i vecchi broker e disabilitare la logica personalizzata della creazione dell'argomento.

Nota: prima di disattivare i vecchi broker, assicurarsi che tutti i client per questo cluster abbiano aggiornato la configurazione bootstrap.servers con uno o più nuovi broker.

Esegui migrazione cluster Zookeeper

Essendo un sistema basato sul quorum (per eseguire qualsiasi operazione, abbiamo bisogno di un quorum minimo di voti) e data la rielezione del leader, le operazioni di scrittura vengono arrestate, la migrazione del Zookeeper è la parte più difficile. Ci sono un paio di approcci per la sostituzione dei nodi. Un semplice approccio consiste nell'eseguire più cicli di riavvio in sequenza dell'intero cluster e nell'aggiungere un nuovo nodo in ogni ciclo. Questo approccio potrebbe non essere accettabile a causa di più cicli di riavvio del nodo leader e del ritardo nell'esecuzione della migrazione complessiva.

Nota: non è possibile aggiungere tutti i nuovi nodi (come partecipanti) in un'unica operazione a causa del rischio che un nuovo nodo diventi leader senza sincronizzare tutti i dati (causando la perdita di dati).

Non specificare mai più server di join nella stessa configurazione iniziale dei partecipanti. Attualmente, i server di join non sanno che si stanno unendo a un ensemble esistente, se più joiner sono elencati come partecipanti possono formare un quorum indipendente creando una situazione di split-brain come le operazioni di elaborazione indipendentemente dal tuo ensemble principale. È possibile elencare più joiner come osservatori in una configurazione iniziale.

Nella versione Zookeeper sopra 3.5.0, abbiamo il supporto per la riconfigurazione dinamica dell'ensemble Zookeeper. Il flag reconfigEnabled deve essere impostato su true per consentire il funzionamento della riconfigurazione dinamica. Per ulteriori informazioni, vedere Riconfigurazione dinamica dell'insieme ZooKeeper.

È possibile aggiungere nuovi nodi all'insieme con il ruolo Observer con la configurazione iniziale dei join composti da server nell'ultima configurazione di cui è stato eseguito il commit. Ad esempio, se i server 4 e 5 vengono aggiunti contemporaneamente a (1, 2, 3), la configurazione iniziale di 4 sarà (1, 2, 3, 4, 5), dove 4 e 5 sono elencati come osservatori. Analogamente, la configurazione di 5 sarà (1, 2, 3, 4, 5), dove 4 e 5 sono elencati come osservatori.

Nota: elencare i membri come osservatori non li renderà osservatori, ma solo impedirà loro di formare accidentalmente un quorum con altri membri. Contatteranno invece i server nella configurazione corrente e adotteranno l'ultima configurazione di cui è stato eseguito il commit (1, 2, 3), in cui i joiner sono assenti. Dopo la connessione al leader attuale, i membri diventano follower non votanti fino a quando il sistema non viene riconfigurato e vengono aggiunti all'insieme (come partecipante o osservatore, come desiderato).

Una volta che tutti i nodi sono attivi e in esecuzione, viene chiamata l'API di riconfigurazione per aggiungere dinamicamente nuovi nodi come partecipanti e rimuovere i vecchi nodi dall'insieme. Ad esempio, utilizzando l'interfaccia CLI.

reconfig -remove 1,2,3 -add
server.5=hostA:2111:2112;2113,6=hostB:2111:2112:participant;2113,7=
hostC:2111:2112:participant;2113*

Dopo questo passo, è possibile disattivare i vecchi nodi.

Nota:

Conferme

Altre risorse di apprendimento

Esplora altri laboratori su docs.oracle.com/learn o accedi a più contenuti gratuiti sulla formazione su Oracle Learning YouTube channel. Inoltre, visita education.oracle.com/learning-explorer per diventare un Oracle Learning Explorer.

Per la documentazione del prodotto, visita l'Oracle Help Center.