Observação:

Migrar Cluster do Kafka e do Zookeeper sem Tempo de Inatividade

Introdução

Muitos serviços (nativos da nuvem ou on-premises) usam clusters Kafka para suas necessidades de mensagens assíncronas, pois é uma tecnologia de mensagens que se dimensiona bem. Pode haver situações em que você precisa substituir um conjunto de nós ou todo o cluster devido às necessidades de negócios. Este tutorial fala sobre a migração do cluster do Kafka e do Zookeeper para um novo conjunto de nós sem tempo de inatividade.

A instrução do problema

Por que substituir um nó em um cluster por outro pode ser um desafio? A adição ou remoção de um nó de um conjunto de nós por trás de um balanceador de carga é onipresente: adicione um novo nó, drene o nó existente a ser removido, depois que todas as conexões em andamento forem encerradas, desligue-o, remova-o da configuração do balanceador de carga e assim por diante.

O verdadeiro desafio está no gerenciamento de estado com um aplicativo. Em geral, os aplicativos são sem monitoramento de estado e delegam persistência de estado a um sistema de gerenciamento de dados, por exemplo, um sistema de gerenciamento de banco de dados relacional (RDBMS). Ao contrário de tais aplicativos, tanto o Kafka quanto o Zookeeper gerenciam o estado localmente, ou seja, a persistência do estado é feita usando discos locais. Isso significa que não podemos simplesmente substituir um nó por outro sem cuidar do estado local do nó existente.

Além disso, no caso do Kafka, simplesmente adicionar um nó, não inicia automaticamente qualquer rebalanceamento da carga de trabalho, ou seja, redistribuição de partições de tópicos entre corretores. O novo nó só participa do compartilhamento de carga de trabalho para novos tópicos criados deste ponto em diante.

Um problema operacional com sistemas baseados em quorum (Zookeeper neste caso) é que eles precisam saber o tamanho do cluster antecipadamente, o que significa que cada nó precisa ter conhecimento de todos os outros nós do cluster. E, para complicar ainda mais as coisas, se você estiver adicionando mais de um nó (o número exato depende do tamanho do cluster existente) de uma só vez, você deve garantir que um dos nós recém-adicionados não se torne o líder; caso contrário, perderemos os dados.

Objetivos

Pré-requisitos

Migrar Cluster do Kafka

A substituição de nós no cluster Kafka é relativamente fácil. Adicione novos brokers e chame a migração de partições de tópicos e, quando a migração estiver concluída, poderemos desativar o broker antigo. O Kafka fornece a API admin para executar a migração de partição. O alterPartitionReassignments funciona adicionando réplicas de partição adicionais a um tópico, espera que elas se tornem membros do ISR e, em seguida, troca o líder da partição.

Você precisa desativar novas atribuições de partição de tópico para brokers antigos (se a lógica do aplicativo criar tópicos no runtime), caso contrário, isso se tornaria um loop infinito de migração. Para conseguir isso, pode-se usar uma variante da API de criação de tópico, onde podemos especificar a atribuição de partição nós mesmos. O algoritmo de amostra que pode ser seguido está listado abaixo.

Etapas de alto nível para migração que podem ser seguidas com escrituração contábil (para reiniciar no caso de o processo de migração ser interrompido ou falhar no meio).

  1. O mapeamento de ID de Assert antigo para novo corretor foi fornecido e concluído.

  2. Use AdminClient para verificar se novos corretores estão disponíveis. Se nem todos estiverem disponíveis, crie um erro e encerre.

  3. Use AdminClient para verificar se o tópico <kafka_topic_migration> existe no cluster.

    • Se o tópico <kafka_topic_migration> não existir, crie-o designando réplicas manualmente em novos brokers. Este tópico é usado para escrituração contábil de tópicos que já foram reatribuídos significa migrados.
  4. Leia o tópico <kafka_topic_migration> desde o início usando um consumidor. Cada mensagem é um nome de tópico que foi reatribuído a novos corretores.

  5. Use AdminClient para listar todos os tópicos disponíveis no cluster. Nessa lista, remova o tópico <kafka_topic_migration>.

  6. Nas duas etapas acima, localize os tópicos a serem reatribuídos a novos corretores.

  7. Para cada tópico:

    1. Crie um mapa Map<TopicPartition,Optional<NewPartitionReassignment>> reassignment = new HashMap<>();.

    2. Usando AdminClient, descreva o tópico para localizar suas partições.

    3. Para cada partição:

      1. Prepare um objeto NewPartitionReassignment substituindo cada ID de réplica antigo (ID de broker antigo) pelo novo ID de broker correspondente. Se o mapeamento de ID do corretor não contiver a chave correspondente ao ID da réplica, registre um aviso e use o ID atual (o motivo mais provável é que esse tópico já tenha sido migrado e tenhamos perdido a escrituração contábil).

      2. Adicione esta entrada ao mapa.

    4. Use AdminClient para iniciar a reatribuição chamando o método alterPartitionReassignments.

    5. Execute um loop para verificar se essa reatribuição está concluída listando as reatribuições em andamento (listPartitionReassignments) e verificando se seu tamanho é zero. Dormir de N segundos entre cada loop.

    6. Valide se as novas réplicas de cada partição correspondem às réplicas desejadas.

    7. Envie este nome de tópico como mensagem para o tópico <kafka_topic_migration>.

  8. Repita a etapa 4 a 6, se não houver mais tópicos para reatribuição e encerramento.

Uma vez concluída a migração, podemos desativar os corretores antigos e desativar a lógica personalizada da criação do tópico.

Observação: Antes de desativar os brokers antigos, certifique-se de que todos os clientes deste cluster atualizaram a configuração bootstrap.servers com novos broker(s).

Migrar Cluster do Zookeeper

Sendo um sistema baseado em quórum (para comprometer qualquer operação, precisamos de pelo menos Quórum de votos) e dada reeleição de líder faz com que as operações de gravação sejam interrompidas, a migração do Zookeeper é a parte mais difícil. Existem algumas abordagens para substituir nós. Uma abordagem simples é executar várias rodadas de reinicialização incremental de todo o cluster e adicionar um novo nó em cada rodada. Essa abordagem pode não ser aceitável devido a várias rodadas de reinicialização do nó do líder e atraso na execução da migração geral.

Observação: Não podemos adicionar todos os novos nós (como participantes) de uma só vez devido ao risco de um novo nó se tornar um líder sem sincronizar todos os dados (causando perda de dados).

Nunca especifique mais de um servidor de junção na mesma configuração inicial que os participantes. Atualmente, os servidores de junção não sabem que estão se juntando a um conjunto existente, se vários participantes forem listados como participantes, eles podem formar um quorum independente, criando uma situação de cérebro dividido, como operações de processamento independentemente do seu conjunto principal. Não há problema em listar vários joiners como observadores em uma configuração inicial.

Na versão do Zookeeper acima de 3.5.0, temos suporte para reconfiguração dinâmica do conjunto do Zookeeper. O flag reconfigEnabled deve ser definido como true para que a reconfiguração dinâmica funcione. Para obter mais informações, consulte Reconfiguração dinâmica do ZooKeeper Ensemble.

Você pode adicionar novos nós ao conjunto com a atribuição Observer com a configuração inicial de joiners compostos de servidores na última configuração confirmada. Por exemplo, se os servidores 4 e 5 forem adicionados ao mesmo tempo a (1, 2, 3), a configuração inicial de 4 será (1, 2, 3, 4, 5), onde 4 e 5 são listados como observadores. Da mesma forma, a configuração de 5 será (1, 2, 3, 4, 5), onde 4 e 5 são listados como observadores.

Observação: Listar os participantes como observadores não os tornará realmente observadores; isso apenas os impedirá de formar acidentalmente um quorum com outros participantes. Em vez disso, eles entrarão em contato com os servidores na configuração atual e adotarão a última configuração confirmada (1, 2, 3), onde os participantes estão ausentes. Depois de se conectar ao líder atual, os participantes se tornam seguidores sem direito a voto até que o sistema seja reconfigurado e sejam adicionados ao conjunto (como participante ou observador, conforme desejado).

Quando todos os nós estiverem ativos e em execução, a API reconfig será chamada para adicionar novos nós dinamicamente como participantes e remover nós antigos do conjunto. Por exemplo, usando a 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*

Após essa etapa, os nós antigos podem ser desativados.

Observação:

Confirmação

Mais Recursos de Aprendizagem

Explore outros laboratórios em docs.oracle.com/learn ou acesse mais conteúdo de aprendizado gratuito no canal Oracle Learning YouTube. Além disso, visite education.oracle.com/learning-explorer para se tornar um Oracle Learning Explorer.

Para obter a documentação do produto, visite o Oracle Help Center.