Note:

Migración del cluster de Kafka y Zookeeper en tiempo de inactividad cero

Introducción

Muchos servicios (nativos en la nube o locales) utilizan clusters de Kafka para sus necesidades de mensajería asíncrona, ya que es una tecnología de mensajería que se amplía bien. Puede haber situaciones en las que tenga que sustituir un juego de nodos o todo el cluster debido a las necesidades del negocio. En este tutorial se describe cómo migrar el cluster de Kafka y Zookeeper a un nuevo juego de nodos sin tiempo de inactividad.

Explicación del problema

¿Por qué sustituir un nodo de un cluster por otro podría ser un desafío? La adición o eliminación de un nodo de un juego de nodos detrás de un equilibrador de carga es omnipresente: agregue un nuevo nodo, drene el nodo existente que se va a eliminar, una vez terminadas todas las conexiones en curso, ciérrelo, elimínelo de la configuración del equilibrador de carga, etc.

El verdadero desafío radica en la gestión estatal con una aplicación. Normalmente, las aplicaciones no tienen estado y delegan la persistencia de estado a un sistema de gestión de datos, por ejemplo, un sistema de gestión de bases de datos relacionales (RDBMS). A diferencia de estas aplicaciones, tanto Kafka como Zookeeper gestionan el estado localmente, es decir, la persistencia del estado se realiza mediante discos locales. Esto significa que no podemos simplemente reemplazar un nodo por otro sin cuidar el estado local del nodo existente.

Además, en el caso de Kafka, la simple adición de un nodo no inicia automáticamente ningún nuevo equilibrio de la carga de trabajo, es decir, la redistribución de particiones de temas entre agentes. El nuevo nodo solo participa en el uso compartido de cargas de trabajo para los nuevos temas creados a partir de este punto.

Un problema operativo de los sistemas basados en quórum (Zookeeper en este caso) es que necesitan conocer el tamaño del cluster por adelantado, lo que significa que cada nodo debe tener conocimiento del resto de nodos del cluster. Y, para complicar aún más las cosas, si va a agregar más de un nodo (el número exacto depende del tamaño del cluster existente) de una sola vez, debe asegurarse de que uno de los nodos recién agregados no se convierta en el líder; de lo contrario, perderemos los datos.

Objetivos

Requisitos

Migrar cluster de Kafka

La sustitución de nodos en el cluster de Kafka es relativamente sencilla. Agregue nuevos agentes y llame a la migración de particiones de temas y, una vez finalizada la migración, podremos desactivar el agente antiguo. Kafka proporciona la API de administrador para realizar la migración de particiones. alterPartitionReassignments funciona agregando réplicas de particiones adicionales a un tema, espera a que se conviertan en miembros de ISR y, a continuación, intercambia el líder de particiones.

Debe desactivar las nuevas asignaciones de particiones de temas a brokers antiguos (si la lógica de la aplicación crea temas en tiempo de ejecución) de lo contrario, esto se convertiría en un bucle infinito de migración. Para ello, se puede utilizar una variante de la API de creación de temas donde podemos especificar la asignación de particiones nosotros mismos. A continuación se muestra un algoritmo de ejemplo que se puede seguir.

Pasos de alto nivel para la migración que se pueden seguir con la contabilidad (para el reinicio en caso de que el proceso de migración se detenga o falle en el medio).

  1. Se ha indicado y completado la asignación de ID de broker antiguo a nuevo.

  2. Utilice AdminClient para comprobar si hay nuevos agentes disponibles. Si no todas están disponibles, emita el error y finalícelas.

  3. Utilice AdminClient para comprobar si el tema <kafka_topic_migration> existe en el cluster.

    • Si el tema <kafka_topic_migration> no existe, créelo mediante la asignación manual de réplicas en nuevos agentes. Este tema se utiliza para la contabilidad de temas que ya están reasignados significa migrado.
  4. Lea el tema <kafka_topic_migration> desde el principio con un consumidor. Cada mensaje es un nombre de tema que se ha reasignado a nuevos agentes.

  5. Utilice AdminClient para mostrar todos los temas disponibles en el cluster. En esta lista, elimine el tema <kafka_topic_migration>.

  6. En los dos pasos anteriores, busque los temas que se van a reasignar a los nuevos agentes.

  7. Para cada tema:

    1. Cree una asignación Map<TopicPartition,Optional<NewPartitionReassignment>> reassignment = new HashMap<>();.

    2. Con AdminClient, describa el tema para buscar sus particiones.

    3. Para cada partición:

      1. Prepare un objeto NewPartitionReassignment sustituyendo cada ID de réplica antiguo (ID de broker antiguo) por el ID de broker nuevo correspondiente. Si la asignación de ID de intermediario no contiene la clave correspondiente al ID de réplica, registre una advertencia y utilice el ID actual (la razón más probable de esto sería que este tema ya se ha migrado y nos hemos perdido la contabilidad).

      2. Agregue esta entrada a la asignación.

    4. Utilice AdminClient para iniciar la reasignación llamando al método alterPartitionReassignments.

    5. Ejecute un bucle para comprobar si esta reasignación se ha completado enumerando las reasignaciones en curso (listPartitionReassignments) y comprobando que su tamaño es cero. Duerma N segundos entre cada bucle.

    6. Valide que las nuevas réplicas de cada partición coincidan con las réplicas deseadas.

    7. Envíe este nombre de tema como mensaje al tema <kafka_topic_migration>.

  8. Repita los pasos del 4 al 6 si no quedan más temas para reasignación y finalización.

Una vez finalizada la migración, podemos desactivar los brokers antiguos y desactivar la lógica personalizada de la creación de temas.

Nota: Antes de retirar los brokers antiguos, asegúrese de que todos los clientes de este cluster han actualizado la configuración bootstrap.servers con los nuevos brokers.

Migrar cluster de Zookeeper

Al ser un sistema basado en quórum (para comprometer cualquier operación, necesitamos al menos quórum de votos) y dado que la reelección de líderes hace que las operaciones de escritura se detengan, la migración de Zookeeper es la parte más difícil. Hay un par de enfoques para reemplazar los nodos. Un enfoque sencillo es realizar varias rondas de reinicio gradual de todo el cluster y agregar un nuevo nodo en cada ronda. Es posible que este enfoque no sea aceptable debido a varias rondas de reinicio del nodo principal y retraso en la realización de la migración general.

Nota: No podemos agregar todos los nodos nuevos (como participantes) de una sola vez debido al riesgo de que un nodo nuevo se convierta en líder sin sincronizar todos los datos (lo que provoca la pérdida de datos).

Nunca especifique más de un servidor de unión en la misma configuración inicial que los participantes. Actualmente, los servidores que se unen no saben que se están uniendo a un conjunto existente, si se enumeran varios miembros como participantes, pueden formar un quórum independiente creando una situación de "cerebro dividido", como operaciones de procesamiento independientemente de su conjunto principal. Es correcto mostrar varios elementos de unión como observadores en una configuración inicial.

En la versión de Zookeeper anterior a 3.5.0, tenemos soporte para la reconfiguración dinámica del conjunto de Zookeeper. El indicador reconfigEnabled se debe definir en true para que la reconfiguración dinámica funcione. Para obtener más información, consulte Dynamic Reconfiguration of the ZooKeeper Ensemble.

Puede agregar nuevos nodos para ensamblar con el rol Observer con la configuración inicial de unificadores compuestos por servidores en la última configuración confirmada. Por ejemplo, si los servidores 4 y 5 se agregan al mismo tiempo a (1, 2, 3), la configuración inicial de 4 será (1, 2, 3, 4, 5), donde 4 y 5 se muestran como observadores. Del mismo modo, la configuración de 5 será (1, 2, 3, 4, 5), donde 4 y 5 se enumeran como observadores.

Nota: La inclusión de los miembros como observadores no los convertirá en observadores; solo les impedirá formar quórum accidentalmente con otros miembros. En su lugar, se pondrán en contacto con los servidores de la configuración actual y adoptarán la última configuración confirmada (1, 2, 3), donde los elementos de unión están ausentes. Después de conectarse con el líder actual, los miembros se convierten en seguidores sin derecho a voto hasta que el sistema se reconfigura y se agregan al conjunto (como participante u observador, según lo desee).

Una vez que todos los nodos están activos y en ejecución, se llama a la API de reconfiguración para agregar dinámicamente nuevos nodos como participantes y eliminar los nodos antiguos del conjunto. Por ejemplo, con 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*

Después de este paso, los nodos antiguos se pueden desactivar.

Nota:

Agradecimientos

Más recursos de aprendizaje

Explore otros laboratorios en docs.oracle.com/learn o acceda a más contenido de aprendizaje gratuito en el canal YouTube de Oracle Learning. Además, visite education.oracle.com/learning-explorer para convertirse en Oracle Learning Explorer.

Para obtener documentación sobre el producto, visite Oracle Help Center.