Note :

Migrer une grappe Kafka et Zookeeper sans temps d'arrêt

Présentation

De nombreux services (natifs en nuage ou sur place) utilisent des grappes Kafka pour leurs besoins de messagerie asynchrone, car il s'agit d'une technologie de messagerie qui s'adapte bien. Il peut arriver que vous deviez remplacer un ensemble de noeuds ou l'ensemble du cluster en raison de besoins métier. Ce tutoriel explique comment migrer une grappe Kafka et Zookeeper vers un nouvel ensemble de noeuds sans aucun temps d'arrêt.

L'énoncé du problème

Pourquoi remplacer un noeud d'un cluster par un autre peut être un défi? L'ajout ou la suppression d'un noeud d'un ensemble de noeuds derrière un équilibreur de charge est omniprésente : ajoutez un nouveau noeud, drainez le noeud existant à supprimer, une fois toutes les connexions en cours terminées, arrêtez-le, supprimez-le de la configuration de l'équilibreur de charge, etc.

Le véritable défi réside dans la gestion de l'état avec une application. En général, les applications sont sans état et déléguent la persistance d'état à un système de gestion de données, par exemple un système de gestion de base de données relationnelle (SGBDR). Contrairement à de telles applications, Kafka et Zookeeper gèrent l'état localement, c'est-à-dire que la persistance de l'état est effectuée à l'aide de disques locaux. Cela signifie que nous ne pouvons pas simplement remplacer un nœud par un autre sans prendre soin de l'état local du nœud existant.

En outre, dans le cas de Kafka, l'ajout d'un noeud ne démarre pas automatiquement le rééquilibrage de la charge de travail, c'est-à-dire la redistribution des partitions de sujet entre les courtiers. Le nouveau noeud ne prend part au partage de la charge globale que pour les nouveaux sujets créés à partir de ce point.

Un problème opérationnel avec les systèmes basés sur quorum (Zookeeper dans ce cas) est qu'ils doivent connaître la taille du cluster à l'avance, ce qui signifie que chaque noeud doit avoir connaissance de tous les autres noeuds du cluster. Et, pour compliquer davantage les choses, si vous ajoutez plusieurs nœuds (le nombre exact dépend de la taille du cluster existant) en une seule fois, vous devez vous assurer que l'un des nœuds nouvellement ajoutés ne devient pas le leader sinon nous perdons les données.

Objectifs

Préalables

Migrer la grappe Kafka

Il est relativement facile de remplacer des noeuds dans une grappe Kafka. Ajoutez de nouveaux courtiers et appelez la migration des partitions de sujet. Une fois la migration terminée, nous pouvons mettre hors service l'ancien courtier. Kafka fournit une API d'administration pour effectuer la migration de partition. alterPartitionReassignments fonctionne en ajoutant des répliques de partition supplémentaires à un sujet, attend qu'elles deviennent membres d'ISR, puis échange le chef de partition.

Vous devez désactiver les nouvelles affectations de partition de sujet aux anciens courtiers (si la logique de l'application crée des sujets lors de l'exécution), sinon cela deviendrait une boucle sans fin de migration. Pour ce faire, on peut utiliser une variante de l'API de création de sujet où nous pouvons spécifier l'affectation de partition nous-mêmes. L'exemple d'algorithme qui peut être suivi est listé ci-dessous.

Étapes de haut niveau pour la migration qui peuvent être suivies avec la tenue des comptes (pour le redémarrage en cas d'arrêt ou d'échec du processus de migration au milieu).

  1. Le mappage de l'ancien au nouveau code de courtier est indiqué et terminé.

  2. Utilisez AdminClient pour vérifier si de nouveaux courtiers sont disponibles. S'ils ne sont pas tous disponibles, générer une erreur et mettre fin.

  3. Utilisez AdminClient pour vérifier si le sujet <kafka_topic_migration> existe dans la grappe.

    • Si le sujet <kafka_topic_migration> n'existe pas, créez-le en affectant manuellement des répliques aux nouveaux courtiers. Cette rubrique est utilisée pour la tenue des livres des sujets qui sont déjà réaffectés.
  4. Lisez le sujet <kafka_topic_migration> dès le début en utilisant un consommateur. Chaque message est un nom de sujet qui a été réaffecté à de nouveaux courtiers.

  5. Utilisez AdminClient pour lister tous les sujets disponibles dans la grappe. Dans cette liste, supprimez la rubrique <kafka_topic_migration>.

  6. À partir des deux étapes ci-dessus, recherchez les sujets à réaffecter aux nouveaux courtiers.

  7. Pour chaque sujet :

    1. Créez un mappage Map<TopicPartition,Optional<NewPartitionReassignment>> reassignment = new HashMap<>();.

    2. À l'aide de AdminClient, décrivez la rubrique pour rechercher ses partitions.

    3. Pour chaque partition :

      1. Préparez un objet NewPartitionReassignment en remplaçant chaque ancien ID réplique (ancien ID courtier) par le nouvel ID courtier correspondant. Si le mappage d'ID courtier ne contient pas la clé correspondant à l'ID réplique, enregistrez un avertissement et utilisez l'ID courant (la raison la plus probable serait que ce sujet a déjà été migré et que nous avons manqué la tenue des comptes).

      2. Ajoutez cette entrée à la carte.

    4. Utilisez AdminClient pour lancer la réaffectation en appelant la méthode alterPartitionReassignments.

    5. Exécutez une boucle pour vérifier si cette réaffectation est terminée en listant les réaffectations en cours (listPartitionReassignments) et en vérifiant que sa taille est nulle. Dormez de N secondes entre chaque boucle.

    6. Vérifiez que les nouvelles répliques de chaque partition correspondent aux répliques souhaitées.

    7. Poussez le nom de ce sujet en tant que message vers le sujet <kafka_topic_migration>.

  8. Répétez les étapes 4 à 6, s'il ne reste plus de sujets pour la réaffectation et la fin.

Une fois la migration terminée, nous pouvons mettre hors service les anciens courtiers et désactiver la logique personnalisée de création de sujet.

Note : Avant de mettre hors service les anciens courtiers, assurez-vous que tous les clients de cette grappe ont mis à jour la configuration bootstrap.servers avec de nouveaux courtiers.

Migrer la grappe Zookeeper

Étant un système basé sur le quorum (pour valider n'importe quelle opération, nous avons besoin d'au moins un quorum de votes) et étant donné que la réélection du leader entraîne l'arrêt des opérations d'écriture, la migration de Zookeeper est la partie la plus difficile. Il existe plusieurs approches pour remplacer les nœuds. Une approche simple consiste à effectuer plusieurs cycles de redémarrage non simultané de l'ensemble du cluster et à ajouter un nouveau noeud à chaque cycle. Cette approche peut ne pas être acceptable en raison de multiples cycles de redémarrage du noeud principal et de retards dans l'exécution de la migration globale.

Note : Nous ne pouvons pas ajouter tous les nouveaux noeuds (en tant que participants) en une seule fois en raison du risque qu'un nouveau noeud devienne un chef de file sans synchroniser toutes les données (ce qui entraîne une perte de données).

N'indiquez jamais plus d'un serveur de jointure dans la même configuration initiale que les participants. Actuellement, les serveurs de jointure ne savent pas qu'ils rejoignent un ensemble existant, si plusieurs jointures sont répertoriées en tant que participants, ils peuvent former un quorum indépendant créant une situation à cerveau partagé telle que les opérations de traitement indépendamment de votre ensemble principal. Il est acceptable de répertorier plusieurs jointures en tant qu'observateurs dans une configuration initiale.

Dans la version Zookeeper au-dessus de 3.5.0, nous prenons en charge la reconfiguration dynamique de l'ensemble Zookeeper. L'indicateur reconfigEnabled doit être réglé à true pour que la reconfiguration dynamique fonctionne. Pour plus d'informations, voir Reconfiguration dynamique de l'ensemble ZooKeeper.

Vous pouvez ajouter de nouveaux noeuds à l'ensemble avec le rôle Observer avec la configuration initiale de jointures composées de serveurs dans la dernière configuration validée. Par example, si les serveurs 4 et 5 sont ajoutés en même temps à (1, 2, 3), la configuration initiale de 4 sera (1, 2, 3, 4, 5), où 4 et 5 sont répertoriés comme observateurs. De même, la configuration de 5 sera (1, 2, 3, 4, 5), où 4 et 5 sont répertoriés comme observateurs.

Note : Lister les jointures en tant qu'observateurs ne les rendra pas réellement observateurs - cela ne les empêchera que de former accidentellement un quorum avec d'autres jointures. Au lieu de cela, ils contacteront les serveurs dans la configuration actuelle et adopteront la dernière configuration validée (1, 2, 3), où les joiners sont absents. Après la connexion au leader actuel, les adhérents deviennent des adeptes sans droit de vote jusqu'à ce que le système soit reconfiguré et qu'ils soient ajoutés à l'ensemble (en tant que participant ou observateur, au besoin).

Une fois tous les noeuds en cours d'exécution, l'API de reconfiguration est appelée pour ajouter dynamiquement de nouveaux noeuds en tant que participants et supprimer les anciens noeuds de l'ensemble. Par exemple, utiliser l'interface de ligne de commande.

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

Après cette étape, les anciens noeuds peuvent être mis hors service.

Note :

Confirmation

Autres ressources d'apprentissage

Explorez d'autres laboratoires sur la page docs.oracle.com/learn ou accédez à plus de contenu d'apprentissage gratuit sur le canal YouTube d'Oracle Learning. De plus, visitez education.oracle.com/learning-explorer pour devenir un explorateur Oracle Learning.

Pour obtenir de la documentation sur le produit, visitez Oracle Help Center.