Como Migrar Clusters Hadoop em Escala de Petabytes com Tempo de Inatividade Zero

Avance Network foi um dos primeiros a adotar o Hadoop e nós, adquirimos muita experiência na execução e produção em termos de ingestão, processamento, monitoramento, atualização de dados, etc.

Isso também significa que temos um ecossistema significativo em torno de cada um. cluster, com sistemas de código aberto e internos.

Há algum tempo, decidimos atualizar as versões de hardware e software de nossos clusters Hadoop.

"Por que isso é um grande problema?" você pode perguntar, então deixe-me explicar um pouco sobre nossa arquitetura atual do Hadoop. Temos dois clusters de 300 máquinas em dois data centers diferentes, produção e DR. Cada cluster tem um tamanho total do conjunto de dados de 1,5 PB com 5 TB de dados compactados carregados diariamente. Existem ~ 10.000 execuções de trabalho diariamente, com cerca de 1200 definições de trabalho que foram escritas por dezenas de desenvolvedores, cientistas de dados e várias outras partes interessadas da empresa, espalhadas por várias equipes ao redor do mundo. Essas tarefas fazem de tudo, desde mover dados para o Hadoop (por exemplo, Sqoop ou Mysql até cargas de dados do Hive), processar no Hadoop (por exemplo, executar tarefas do Hive, Scalding ou Pig) e enviar os resultados para repositórios de dados externos (por exemplo. Vertica, Cassandra, Mysql etc.).

Esse sistema precisava ser migrado para rodar em novo hardware, usando novas versões de vários componentes do ecossistema Hadoop, sem afetar os processos de produção e os usuários ativos. Uma lista parcial dos componentes e tecnologias que estão sendo usadas no momento e deve ser levada em consideração é HDFS, Redução de mapa, Hive, Pig, Scalding e Sqoop. Além disso, é claro, temos vários outros serviços internos para entrega, monitoramento e retenção de dados que desenvolvemos.

Tenho certeza que você concorda que isso é um elefante.

Invadindo Nossos Cérebros

Sentamos com nossos usuários e começamos a pensar em um processo para atingir esse objetivo e rapidamente chegamos a várias diretrizes que nosso processo selecionado deveria seguir:

  1. Ambos os clusters do Hadoop (produção e DR) devem sempre ser mantidos totalmente operacionais
  2. O processo de migração deve ser reversível
  3. Tanto o valor quanto o risco devem ser incrementais

Depois de coçar a cabeça por um bom tempo, chegamos a estas opções:

  1. No local: migração no local do cluster existente para a nova versão e, em seguida, rolar a atualização de hardware, empurrando gradualmente novas máquinas para o cluster e removendo as antigas. Essa é a abordagem mais simples e você provavelmente deve ter um bom motivo para escolher um caminho diferente se puder arcar com o risco. No entanto, uma vez que a atualização do sistema em vigor expõe os clientes a uma enorme mudança de maneira descontrolada e não é de forma alguma um processo facilmente reversível, tivemos que renunciar a essa opção.
  2. Ativando o comutador: A segunda opção é criar um novo cluster no novo hardware, sincronizar os dados necessários, interromper o processamento no cluster antigo e movê-lo para o novo. O problema aqui é que ainda não conseguimos gerenciar o risco, porque interromperíamos todo o processamento e o moveríamos para o novo cluster. Não saberíamos se o novo cluster pode lidar com a carga ou se o código de cada fluxo é compatível com a versão do novo componente. De fato, existem muitas incógnitas que deixaram claro que tivemos que dividir o problema em pedaços menores. A dificuldade com a divisão nessa abordagem é que, depois de mover um subconjunto do processamento do cluster antigo para o novo, esses resultados não serão mais acessíveis no cluster antigo. Isso significa que teríamos que migrar todas as dependências desse subconjunto inicial.
  3. Execução lado a lado: a terceira opção é iniciar o processamento no novo cluster sem interromper o cluster antigo. Essa é uma espécie de abordagem ativo-ativo, porque os clusters Hadoop, novos e antigos, conterão os resultados do processamento. Isso nos permitiria migrar partes da carga de trabalho sem o risco de interferir com qualquer pipeline de trabalho no cluster antigo. Parece bom, certo.

Primeiros passos

Para entender melhor a solução escolhida, vamos dar uma olhada em nossa arquitetura atual:

Temos uma estrutura que permite aos aplicativos enviar dados brutos de eventos para vários clusters do Hadoop. Por uma questão de simplicidade, o diagrama descreve apenas um cluster.

Quando os dados chegam ao Hadoop, o processamento começa a ocorrer usando uma estrutura para orquestrar fluxos de dados que desenvolvemos internamente que gostamos de chamar de Mecanismo de fluxo de trabalho.

Cada mecanismo de fluxo de trabalho pertence a um grupo de negócios diferente. Esse mecanismo de fluxo de trabalho é responsável por acionar e orquestrar a execução de todos os fluxos desenvolvidos e pertencentes a esse grupo. Cada execução de tarefa pode acionar mais tarefas em seu atual Workflow Engine ou acionar tarefas nos mecanismos de fluxo de trabalho de outros grupos de negócios. Usamos esse particionamento principalmente por motivos de gerenciamento e escala, mas durante o planejamento da migração, ele nos forneceu uma maneira natural de particionar a carga de trabalho, uma vez que existem muito poucas dependências entre grupos versus dentro de cada grupo.

Agora que você entende melhor o layout existente, pode ver que a primeira etapa é instalar um novo cluster Hadoop com todos os componentes necessários de seu ecossistema e começar a inserir dados nele.

Para conseguir isso, configuramos nosso sistema de pipeline de entrega dinâmica de dados para enviar todos os eventos para o novo cluster e o antigo, então agora temos um novo cluster com um pipeline de entrega de dados totalmente operacional:

Lado a lado

Vamos pensar um pouco sobre quais opções tínhamos para executar uma arquitetura de processamento lado a lado.

Poderíamos usar o mesmo conjunto de Mecanismos de fluxo de trabalho para executar seus trabalhos nos clusters, ativos e novos. Embora esse método tenha a vantagem de economizar máquinas e reduzir os custos operacionais, potencialmente dobrará a carga em cada máquina, pois os trabalhos são atribuídos às máquinas de maneira estática. Isso ocorre porque cada mecanismo de fluxo de trabalho recebe um grupo de negócios e todos os trabalhos pertencentes a esse grupo são executados a partir dele. Para isolar a execução atual dos trabalhos de produção daqueles do novo cluster, decidimos alocar máquinas independentes para o novo cluster.

Deixe o processamento começar!

Agora que temos um cluster Hadoop totalmente operacional em execução ao lado de nosso cluster de produção e agora temos dados brutos entregues nele, você pode ficar tentado a dizer: “Ótimo! Crie um conjunto de mecanismos de fluxo de trabalho e vamos começar o processamento lado a lado! ”.

Bem, na verdade não.

Como existem tantos trabalhos e eles realizam diversos tipos de operações, não podemos realmente assumir que deixá-los correr lado a lado é uma boa idéia. Por exemplo, se um trabalho calcula alguns resultados e os envia para o MySql, esses resultados serão enviados duas vezes. Além de dobrar a carga nos bancos de dados sem um bom motivo, isso pode causar, em alguns casos, corrupção ou inconsistências dos dados devido às condições de corrida. Em essência, todo trabalho que grava em uma fonte de dados externa deve ser executado apenas uma vez.

Então, descrevemos dois tipos de modos de execução que um WorkflowEngine pode ter:

Líder: Execute todos os trabalhos!

Secundário: execute todas as tarefas, exceto aquelas que possam ter um efeito colateral externo ao cluster Hadoop (por exemplo, gravar no banco de dados externo ou acionar um serviço de aplicativo). Isso será feito automaticamente pela estrutura, evitando assim qualquer esforço das equipes de desenvolvimento.

Quando um Mecanismo de Fluxo de Trabalho está no modo secundário, as tarefas executadas a partir dele podem ler de qualquer origem, mas gravar apenas em um cluster Hadoop específico. Dessa forma, eles estão essencialmente preenchendo e sincronizando (até certo ponto) com o outro cluster.

Vamos fazer isso…

A fase 1 da migração deve se parecer com isso:

Observe que incluí apenas um mecanismo de fluxo de trabalho para um grupo no diagrama por simplicidade, mas será semelhante para todos os outros grupos.

Portanto, a idéia é criar um novo mecanismo de fluxo de trabalho e atribuir a ele o papel de uma migração secundária. Dessa forma, ele executará todas as tarefas, exceto as que estão gravando em armazenamentos de dados externos, eliminando todos os efeitos colaterais externos ao novo cluster Hadoop.

Ao fazer isso, conseguimos atingir vários objetivos:

  1. Teste a integração básica de software com a nova versão do cluster Hadoop e todos os serviços do ecossistema (seção, porco, escaldamento etc.)
  2. Teste o novo hardware e desempenho do cluster em comparação com o cluster atualmente ativo
  3. Atualize com segurança cada mecanismo de fluxo de trabalho de cada grupo de negócios separadamente, sem afetar outros grupos.

Como o novo cluster está sendo executado em um novo hardware e com uma nova versão do ecossistema Hadoop, esse é um grande marco para validar nossa nova arquitetura. O fato de termos conseguido fazê-lo sem arriscar qualquer tempo de inatividade que poderia resultar de falhas nos fluxos de processamento, configurações incorretas de cluster ou qualquer outro problema em potencial foi fundamental para alcançar nossos objetivos de migração.

Quando estivéssemos confiantes de que todos os trabalhos da fase 1 estavam funcionando adequadamente no novo cluster, poderíamos continuar na fase 2, na qual um líder de migração se torna secundário e o secundário se torna um líder. Como isso:

Nesta fase, todos os trabalhos começarão a ser executados no novo Workflow Engine, impactando todos os sistemas de produção, enquanto o antigo Workflow Engine executará apenas trabalhos que criam dados no cluster antigo. Na verdade, esse método oferece uma maneira bastante fácil de reverter para o cluster antigo em caso de falha grave (mesmo após alguns dias ou semanas), pois todos os dados intermediários continuarão disponíveis no cluster antigo.

O plano geral

O processo geral é levar todos os mecanismos de fluxo de trabalho para a fase 1 e, em seguida, testar e estabilizar o sistema. Conseguimos executar 70% (!) De nossos trabalhos nesta fase. Isso representa 70% do nosso código, 70% de nossas integrações e APIs e pelo menos 70% dos problemas que você enfrentaria em uma mudança real ao vivo. Conseguimos corrigir problemas, analisar o desempenho do sistema e validar resultados. Somente quando tudo parece estar funcionando corretamente, podemos começar a empurrar os grupos para a fase 2, um por um, em um novo cluster estável e testado.

Mais uma vez nos beneficiamos da natureza incremental do processo. Cada grupo de negócios pode ser empurrado para a fase 2 independentemente de outros grupos, reduzindo assim os riscos e aumentando nossa capacidade de depurar e analisar problemas. Além disso, cada grupo de negócios pode começar a aproveitar os recursos do novo cluster (por exemplo, recursos da versão mais recente ou desempenho aprimorado) imediatamente após passar para a fase 2 e não depois de migrarmos cada uma das ~ 1200 tarefas para executar no novo cluster. . Um ponto problemático que não pode ser ignorado é que as dependências entre grupos podem tornar isso um feito significativamente mais complicado, pois você precisa levar em consideração o estado de vários grupos ao migrar.

O que alcançamos?

  1. Migração Incremental - Devido ao fato de termos uma migração ativo-ativa que poderíamos aplicar em cada grupo de negócios, nos beneficiamos em termos de mitigação de riscos e ganho de valor do novo sistema gradualmente.
  2. Processo reversível - como mantivemos todos os mecanismos de fluxo de trabalho antigos (que executavam suas tarefas no antigo cluster Hadoop) em um estado de modo de execução secundário, todos os dados intermediários ainda estavam sendo processados ​​e estavam disponíveis caso precisássemos reverter grupos independentemente um do outro .
  3. Impacto mínimo nos usuários - Como definimos uma transição automatizada de tarefas entre os usuários dos modos secundário e líder, não foi necessário duplicar nenhuma delas.

E agora?

Concluímos a atualização e a migração do nosso cluster principal e já iniciamos a migração do cluster de DR.

Há muito mais detalhes e preocupações a serem levados em consideração ao migrar um sistema de produção nessa escala. No entanto, as abstrações básicas que introduzimos aqui e os recursos em que infundimos nossos sistemas nos equiparam com as ferramentas para migrar elefantes.

 

Máxima comunicação com proteção ao extremo? Avance Network: A verdadeira rede social junte-se a nós


Strong

5178 Blog Postagens

Comentários