Como usar clusters na computação técnica em grande escala no Google Cloud

Nesta solução, você verá orientações para executar computação técnica em grande escala no Google Cloud. Muitos aplicativos de computação técnica requerem um grande número de nós de computação individuais, conectados a um cluster, além de coordenação da computação e acesso aos dados pelos nós.

Os conceitos e as tecnologias subjacentes à computação em cluster se desenvolveram-se nas últimas décadas e, agora, estão maduros e são predominantes. Migrar a pilha de software para o Google Cloud talvez traga alguns problemas, mas também oferecerá várias oportunidades para diminuir custos e aliviar gargalos nos ambientes de computação de alto desempenho atuais. Neste guia, há uma visão geral das tecnologias, dos desafios e do atual conjunto de soluções para executar clusters computacionais no Google Cloud.

A computação em cluster agrega e coordena um grupo de máquinas para trabalhar em conjunto e resolver uma tarefa. Os clusters geralmente têm um único nó de cabeçalho (às vezes chamado de nó mestre), alguns nós de computação e possivelmente outros nós de especialidade. O node principal é o "cérebro" do sistema e é responsável por:

  • registrar os nodes de computação no sistema;
  • monitorar os nodes;
  • alocar jobs a nós específicos.
Um cluster é composto por um nó de cabeçalho e um conjunto de nós de computação.
Figura 1. Um cluster é composto por um nó de cabeçalho e um conjunto de nós de computação. Os usuários interagem com o nó de cabeçalho, que, então, coordena o funcionamento dos nós de computação.

Os usuários enviam jobs, compostos por muitas tarefas. Cada tarefa é a unidade básica de trabalho. Alguns aplicativos requerem que todas as tarefas em um job sejam executadas simultaneamente, além de permitirem a comunicação entre elas para a implementação de um algoritmo paralelo. Alguns jobs têm um conjunto complexo de dependências de tarefas, de tal modo que determinadas tarefas sejam executadas antes de outras. É provável que algumas tarefas exijam determinadas configurações de nó em termos de memória, CPUs ou outro hardware específico para que sejam executadas. As tarefas são executáveis que leem dados de entrada do armazenamento, processam esses dados para produzir um resultado e, em seguida, gravam os resultados finais novamente no armazenamento.

Há dois tipos principais de cargas de trabalho de computação em cluster:

  • Computação de alto desempenho (HPC, na sigla em inglês): um tipo de computação que usa muitos nós de trabalho, bem integrados e em execução simultânea para realizar uma tarefa. Essas máquinas normalmente precisam de baixa latência de rede para se comunicar de maneira eficaz. Os aplicativos de exemplo neste espaço incluem modelagem meteorológica, dinâmica computacional de fluidos (CFD, na sigla em inglês), modelagem de estresse em engenharia e design eletrônico.

  • Computação de alta capacidade (HTC, na sigla em inglês): um tipo de computação em que os aplicativos têm várias tarefas processadas de maneira independente entre si, não havendo a necessidade de comunicação entre cada nó de computação. Às vezes, essas cargas de trabalho são chamadas de embaraçosamente paralelas ou cargas de trabalho em lote. Entre os exemplos comuns estão a renderização de mídia, a transcodificação, a genômica e o processo de simulação e processamento de eventos de física de partículas. Se você precisa processar muitos arquivos individuais, provavelmente a carga de trabalho é de HTC.

Pilha de software de computação em cluster

Uma pilha de software de computação em cluster é composta por:

  • software de gerenciamento de sistema que provisiona e cria clusters;
  • programadores que fazem a orquestração da execução do job;
  • aplicativos do usuário final.

As seções a seguir abordam o software de gerenciamento de sistema e os programadores.

Software de gerenciamento de sistema

É possível executar o software de cluster diretamente no hardware bare-metal, como no caso de clusters no local, ou em ambientes virtualizados, como ambientes em nuvem. O controle manual de vários nodes em um cluster é um processo demorado e propenso a erros. É possível usar software de gerenciamento de cluster especializado para provisionar e configurar vários nós juntamente com recursos, de maneira determinista e que possibilite a repetição.

O software de código aberto ElastiCluster, da Universidade de Zurique, apresenta uma abordagem nativa em nuvem para o gerenciamento de clusters. É compatível com nós de provisionamento com o uso do Compute Engine e com a configuração de nós com o uso de um conjunto de manuais do Ansible. Com o ElastiCluster, os nós são provisionados e uma pilha de software de base é instalada, incluindo NFS para disponibilizar arquivos, gerenciamento de conta de usuário NIS e um programador de job para executar aplicativos de usuário. O ElastiCluster é compatível com uma variedade de programadores. É possível usá-lo imediatamente ou personalizá-lo para atender às necessidades de equipes de pequeno e médio portes.

Se você usa outros sistemas de gerenciamento de configuração para gerenciar os clusters de HPC, como Chef, Puppet ou Terraform, é possível aproveitar esses investimentos ao migrar para o Google Cloud usando as ferramentas e os plug-ins disponíveis.

O Google Cloud oferece serviços nativos de provisionamento e implantação de sistemas de software de vários nós. O Cloud Deployment Manager permite provisionar um conjunto de recursos na nuvem, incluindo o Compute Engine, grupos de instâncias gerenciadas do Compute Engine e o Cloud Storage. O tutorial do HTCondor mostra como usar o Cloud Deployment Manager e os grupos de instâncias gerenciadas para provisionar e configurar um cluster.

Programadores de job

Depois que o cluster entra em operação, o software que gerencia a execução da tarefa e a alocação do node é chamado de programador de jobs. Às vezes ele também é chamado de gerente de carga de trabalho ou gerenciador de filas. Muitas vezes, um gerenciador de cluster vem com um programador de jobs integrado. Os programadores de job oferecem uma variedade de recursos para ajudar a gerenciar jobs e tarefas, como:

  • suporte às prioridades de job entre usuários e grupos, o que ajuda a fornecer uma programação de job baseada em políticas;
  • suporte às tarefas com falhas, fazendo filas e reagendamento de tarefas;
  • consideração de dependências de tarefas e necessidades de recursos para alocação de tarefas;
  • dimensionamento do tamanho do cluster, dependendo do número de jobs na fila.

Há vários gerenciadores de carga de trabalho conhecidos, tanto comerciais quanto de código aberto. Entre os exemplos estão o HTCondor, da Universidade de Wisconsin, o Slurm, da SchedMD, o Univa Grid Engine e o LSF Symphony, da IBM (páginas em inglês). Cada um tem seus pontos fortes.

O HTCondor é desenvolvido com uma filosofia sem compartilhamento e é usado em recursos compartilhados para programar jobs de modo oportuno em recursos ociosos. Ele tem o próprio movimento de dados, por isso, não requer sistemas de arquivos compartilhados. Assim, o HTCondor é escalado para centenas de milhares de núcleos e pode ser usado em várias zonas e regiões. O HTCondor foi utilizado para cargas de trabalho híbridas, em que o trabalho é compartilhado ou dividido entre sistemas locais e baseados em nuvem. No entanto, como o próprio nome indica, ele é focado em jobs de alto rendimento, não jobs paralelos e com grande integração.

No Slurm e no Univa Grid Engine, há um ambiente de cluster de HPC mais tradicional, compatível com aplicativos paralelos de alta capacidade e alto desempenho. Ambos partem do princípio de que há um sistema de arquivos compartilhados em todos os nós, o que elimina a necessidade de mover os dados. Nos dois há um ambiente de usuário conveniente e familiar para o desenvolvimento de aplicativos, porque muitas vezes são as mesmas ferramentas usadas no local. Esses programadores de job tradicionais são suficientes para clusters de pequeno e médio portes, mas, à medida que o tamanho do cluster aumenta, a carga no servidor de arquivos se torna o gargalo de desempenho. Sistemas de arquivos paralelos e distribuídos (veja a próxima seção) ajudam com esse problema ao trabalhar em alta escala. Como alternativa, quando o acesso ao arquivo de baixa latência não for obrigatório, utilize o Cloud Storage, que permite o acesso ao objeto paralelo por meio da API ou do gcsfuse, em que é necessário ter compatibilidade com o POSIX (páginas em inglês).

Por fim, o Google Cloud inclui um serviço simples de programação de tarefas com base em Docker no Compute Engine para cargas de trabalho de alta capacidade: a API Pipelines do Cloud Life Sciences. Esse serviço requer que você decomponha o job em tarefas, gerencie as dependências entre elas e gerencie o ciclo de vida das tarefas. O projeto de código aberto dsub fornece uma ferramenta de linha de comando para lançar jobs em lote e é compatível com a API Pipelines do Cloud Life Sciences.

Armazenamento

A maioria dos aplicativos de HPC exige uma solução de armazenamento de arquivos compatível com a API POSIX. Para clusters menores, o FileStore fornece um serviço de armazenamento de arquivos baseado em NFS gerenciado pelo Google. No entanto, para maiores, é possível que a E/S do aplicativo se torne um gargalo de desempenho. Sistemas de arquivos paralelos e de escalonamento horizontal, como o Elastifile (comprado pelo Google), o Lustre ou o Quobyte (páginas em inglês), ajudam a escalonar para clusters grandes (ou mesmo clusters menores com E/S intensa).

Como alternativa, quando o acesso ao arquivo de baixa latência não for obrigatório, utilize o Cloud Storage, que permite o acesso ao objeto paralelo por meio da API ou do gcsfuse, em que é necessário ter compatibilidade com o POSIX (páginas em inglês).

Oportunidades para computação em cluster na nuvem

Há várias razões para executar clusters de computação na nuvem:

  • Tempo de solução. O lançamento de um cluster de qualidade de produção na nuvem leva apenas alguns minutos: de um pequeno cluster de dez nós com centenas de núcleos disponíveis a clusters em grande escala com cem mil núcleos ou mais. Em contraste, a criação de novos clusters no local pode levar meses para ficar pronta para operação. Mesmo quando os clusters no local estão disponíveis, normalmente eles têm uma alta utilização e tempos longos de espera de filas, às vezes de horas ou dias, antes que os jobs estejam programados para execução. Em vez disso, é possível criar seus próprios clusters na nuvem, usá-los para as cargas de trabalho e finalizá-los quando a análise estiver concluída.

  • Custo total de propriedade mais baixo. O Google Cloud reduz o tempo de solução e o custo total por execução ao utilizar VMs preemptivas, descontos de uso a longo prazo e escalonamento dinâmico. É possível adicionar nós quando os jobs estão em fila e removê-los quando não são mais necessários.

  • Suporte à colaboração. Em muitas situações, a análise de computação é desenvolvida em colaboração com pessoas diferentes, de várias organizações. O Google Cloud oferece as ferramentas de gerenciamento de identidade e acesso para envolvidos no projeto, o que permite o acesso controlado aos dados e às ferramentas analíticas. Os usuários autorizados têm acesso aos mesmos aplicativos, dados e clusters para garantir que todas as pessoas estejam alinhadas, sem a necessidade de copiar dados, gerenciar versões ou sincronizar configurações de cluster.

  • Recursos personalizados para tarefas. Como o custo de um job depende apenas do total de horas por núcleo e não das instâncias numéricas, a execução de clusters na nuvem permite que cada equipe ou grupo tenha o próprio cluster dedicado. Essa abordagem alivia outro problema importante do desenvolvimento de políticas relacionado ao uso de vários grupos. Em seguida, é possível personalizar cada cluster de nuvem dedicado para ajustá-lo ao app de destino. Os clusters no local tendem a ser compostos por um recurso universal compartilhado entre os vários grupos e apps. Nesse ambiente, políticas de compartilhamento entre os grupos tendem a ser complexas de configurar e manter.

  • Integração. Antes de executarem grandes jobs de computação, os pesquisadores realizam a importante tarefa de preparar os conjuntos de dados. Após transferir para a nuvem, esses pesquisadores usam as ferramentas de Big Data disponíveis ali. Também é necessário analisar as saídas dos sistemas de computação. Ferramentas como o BigQuery e o Datalab oferecem vantagens significativas em comparação com as de sistemas no local.

Clusters no local típicos são compartilhados entre usuários e grupos, sendo compatíveis com muitas necessidades diferentes dos aplicativos.
Figura 2.Clusters no local típicos são compartilhados entre usuários e grupos, sendo compatíveis com muitas necessidades diferentes dos aplicativos. Por outro lado, ao migrar para o Google Cloud, os usuários podem personalizar as propriedades do cluster de acordo com as necessidades do aplicativo, o que reduz custos e aumenta o desempenho.

Considerações sobre a arquitetura

As vantagens descritas até agora são atraentes. Porém, há alguns desafios técnicos que muitas vezes dificultam os projetos de migração.

  • Movimentação de dados. Os conjuntos de dados processados pelos nós de computação de um cluster geralmente precisam ser testados na nuvem antes da execução dos jobs. O gerenciamento da movimentação de dados é complexo, dependendo do volume de dados e de como ele é feito. Ferramentas como o Avere são úteis no fornecimento de uma camada de cache em nuvem que move os dados automaticamente quando necessário. No entanto, para muitos apps, é necessário que os conjuntos de dados sejam testados manualmente.

  • Acesso aos dados. Muitos aplicativos de HPC exigem acesso compartilhado a um conjunto de arquivos e diretórios. O modo como esse acesso é fornecido afeta significativamente o desempenho do aplicativo. É possível utilizar dados compartilhados armazenados no Cloud Storage, em servidores NFS como o FileStore, ou que usam sistemas de arquivos paralelos, conforme discutido na seção Armazenamento.

  • Segurança. Para dados confidenciais, confira se o acesso está sempre autorizado e os dados estão criptografados corretamente em repouso e em trânsito. Enquanto o Google Cloud Storage criptografa dados em repouso e em trânsito, é possível aplicar outra camada de controle e gerenciar chaves no Cloud Key Management Service ou por conta própria. As chaves precisam ser recuperadas ou instaladas nos nós de computação antes da execução do job.

  • Latência entre nós. Em aplicativos de HPC com grande integração, o desempenho é afetado pela latência entre os nós no cluster. Como o Google Cloud fornece nós com tamanhos de até 64 núcleos, é possível executar jobs paralelos de 64 vias sem transferir nós. Na maioria dos casos, os jobs com cerca de 1.000 núcleos ou menores são executados razoavelmente bem em hardware de rede não especializado.

  • Gerenciamento de licenças de software. Muitos aplicativos comerciais exigem um servidor de licenças, também conhecido como servidor de chaves. Alguns aplicativos vêm com um servidor de licenças incorporado ou recomendado e outros são compatíveis com as ofertas de servidor de licenças atuais. Alguns programadores de jobs ajudam no gerenciamento de licenças e evitam que os jobs sejam executados até que uma licença esteja disponível.

A computação técnica fornece muitas ferramentas e abordagens para diferentes circunstâncias. Com tantas opções, talvez seja difícil começar. Independentemente da escolha do software de gerenciamento de cluster e do programador, há várias práticas recomendadas a serem seguidas ao executar no Google Cloud.

  • Aproveite as VMs preemptivas sempre que possível. As VMs preemptivas são exatamente como as VMs normais no Google Compute Engine, mas com preços até 80% mais baixos e com a ressalva de que são passíveis de recuperação sem aviso prévio. Para cargas de trabalho de alta capacidade, os programadores de job detectam a perda do nó e a tratam como uma falha dele. As tarefas em execução nesse nó são reprogramadas em um recurso diferente. Mesmo sendo provável que qualquer trabalho realizado nesses nós perdidos também se perca, a probabilidade de perda do nó é suficientemente baixa para que o preço menor justifique o risco. A taxa de perda esperada é de 5% a 15%. As VMs preemptivas são limitadas a, no máximo, 24 horas de uso antes de serem recuperadas.
  • Aproveite o custo e a largura de banda do Cloud Storage em vez de executar o próprio sistema de arquivos paralelo. O Cloud Storage oferece consistência forte e desempenho paralelo escalonável com baixo custo geral. Mesmo que a latência do primeiro byte seja alta, em cerca de 100 ms, os aplicativos que usam o Cloud Storage, em vez de executarem um servidor de arquivos paralelo no Compute Engine, são mais econômicos. A largura de banda disponível entre o Cloud Storage e os nós de computação é suficiente para muitos aplicativos. Alguns clientes relataram largura de banda agregada sustentada superior a 23 GB/s.
  • Crie um cluster de um único aplicativo ou de um único grupo. Os clusters tradicionais são compartilhados entre vários usuários, grupos e aplicativos, o que resulta em longas filas para os jobs e uso ineficiente de recursos por aplicativos. No Google Cloud, considere criar vários clusters para cada grupo ou projeto e usar clusters otimizados para determinados aplicativos executados neles. Ao executar um cluster por duas horas ou dois clusters por uma hora cada, o custo total será o mesmo, mas o segundo padrão reduz o tempo de espera na fila e melhora o desempenho do aplicativo.

Cada implementação é única. Porém, as seções a seguir fornecem algumas recomendações gerais para três casos comuns.

Pesquisador independente tentando processar dados

Em geral, os pesquisadores tentam executar o aplicativo em todos os dados e concluir o mais rápido possível. Mesmo sendo especialistas nos respectivos aplicativo, não pretendem ser especialistas em administração ou gerenciamento de clusters.

Se você for executar cargas de trabalho de alta capacidade, avalie o uso da API Pipelines do Cloud Life Sciences. Ela requer que você coloque o aplicativo em um contêiner do Docker e os arquivos de entrada em um bucket do Cloud Storage. Depois disso, use a ferramenta de linha de comando gcloud para iniciar o aplicativo em cada um dos arquivos no bucket do Cloud Storage. É possível colocar os resultados em outro bucket do Cloud Storage.

Veja um exemplo de um comando de execução de uma tarefa que usa SAMtools para gerar um arquivo de índice BAM a partir de um arquivo BAM de entrada:

gcloud alpha genomics pipelines run --pipeline_id [PIPELINE_ID] \
--logging gs://[YOUR_BUCKET/YOUR_DIRECTORY]/logs \
--inputs inputFile=gs://genomics-public-data/gatk-examples/example1/NA12878_chr22.bam \
--outputs outputFile=gs://[YOUR_BUCKET]/[YOUR_DIRECTORY]/output/NA12878_chr22.bam.bai

Em que

  • [PIPELINE_ID] representa o ID do app na API Pipelines;
  • [YOUR_BUCKET] representa o nome do bucket do Cloud Storage;
  • [YOUR_DIRECTORY] representa o nome do diretório.

Não há cluster para provisionar ou gerenciar. As tarefas simplesmente são executadas até a conclusão em uma VM que é provisionada e gerenciada pela API Pipelines. Isso é econômico porque o Compute Engine é faturado por segundo de uso.

Cluster de pequeno a médio porte para um único projeto ou equipe

Em um projeto ou equipe, os membros têm acesso a um cluster executado por uma equipe central de usuários em toda a empresa ou a recursos em grande escala em um centro de HPC fora da empresa. Nas duas situações, os clusters são gerenciados profissionalmente e acessados com o uso de ferramentas padrão. Por exemplo, talvez os usuários usem ssh para se conectar a um nó de cabeçalho e scripts submit do Grid Engine para enviar jobs para execução.

Uma abordagem para essa equipe é usar o ElastiCluster para definir um ambiente de cluster semelhante aos sistemas locais. É possível personalizar o cluster selecionando um tipo de máquina do Compute Engine mais adequado ao aplicativo, bem como personalizar os scripts de inicialização para instalar as dependências de software do aplicativo. Ainda será possível organizar os dados de entrada no Cloud Storage e instalar o gcsfuse (em inglês) nos nós de computação para montar os dados de entrada.

Esses dados são registrados no arquivo de configuração do ElastiCluster e, quando é necessário computação, um cluster é criado usando a ferramenta de linha de comando, por exemplo:

% elasticluster start astrocluster1

O cluster, nomeado no arquivo de configuração como astrocluster1, será provisionado e configurado conforme especificado. As definições em um arquivo de configuração são flexíveis e compatíveis com diferentes tipos de nós de cabeçalho e de computação, discos permanentes do Compute Engine para o espaço de rascunho, VMs preemptivas para reduzir o custo de cargas de trabalho de alta capacidade, bem como GPUs para operação acelerada. Um exemplo de uma configuração básica de um cluster em Slurm com 10 nós de computação e um nó principal, usando máquinas virtuais de 32 núcleos com base em CentOS, seria como a seguir:

[cluster/astrocluster1]
 cloud=google
 login=google
 setup=ansible-slurm
 security_group=default
 image_id=centos-7-v20170327
 flavor=n1-standard-32
 frontend_nodes=1
 compute_nodes=10
 ssh_to=frontend
 boot_disk_size=50
 

Por último, quando não há mais jobs em execução no sistema, o cluster pode ser interrompido:

% elasticluster stop astrocluster1

Para cargas de trabalho maiores, é possível:

  • tentar personalizar os tipos de máquinas de cluster para reduzir ainda mais os custos;
  • adicionar um filtro paralelo externo para aumentar o desempenho em escala;
  • acrescentar recursos de escalonamento automático para adicionar e remover nós extras com base na profundidade da fila.

Adição de capacidade de burst a clusters atuais por centrais de HPC

As centrais de HPC têm uma enorme capacidade de computação. Porém, como são usadas por muitos grupos na empresa ou organização, as centrais de HPC tendem a ter uma utilização consistentemente elevada e longos tempos de espera de fila. Em geral, elas são compradas com uma determinada capacidade de produção e, quando cargas de trabalho imprevistas forem enviadas na combinação, é possível que o progresso seja reduzido consideravelmente.

Nessas situações, use o burst no ambiente do Google Cloud adicionando temporariamente os nós de computação ao cluster. O cluster se torna um híbrido, com o nó de cabeçalho e alguns nós de computação em execução no local, além de outros de computação em execução no Google Cloud. Quando as filas de jobs tiverem sido reduzidas, será possível liberar os outros nós.

Executar o burst na nuvem é conveniente por alguns motivos:

  • Ele mantém um ambiente de usuário final consistente para envio e gerenciamento de jobs. Os usuários não sabem ou não se importam com a adição de outros nós.
  • Ele permite que os gerentes de TI definam políticas de quando usar o burst, com o objetivo de controlar os custos.

O maior desafio é fornecer um namespace de dados e arquivos consistente para os jobs de usuários em todos os nós do Google Cloud e no local. Os nós do Google Cloud talvez não tenham acesso aos mesmos sistemas de arquivos internos que os nós no local. Nessa situação, os jobs que fazem referência a esses arquivos não são executados.

Caso os nós do Google Cloud estejam configurados com permissões de acesso a arquivos internos, os jobs serão executados. No entanto, talvez não funcionem da mesma maneira e gerem cobranças adicionais por largura de banda e saída de rede. Além disso, os jobs paralelos divididos em nós locais e nós na nuvem talvez não funcionem bem com a latência adicionada entre as diferentes partes do aplicativo.

Para jobs de alto rendimento, o uso do HTCondor para o burst em recursos da nuvem evita muitos desses desafios. O HTCondor é compatível com o provisionamento dinâmico usando o GlideInWMS (em inglês). À medida que os jobs são enviados para uma fila, é possível que eles acionem os nós que estão sendo provisionados e adicionados ao cluster. Quando eles forem adicionados, o programador do Condor transferirá os arquivos de entrada para o nó designado e usará mais nós para executar as tarefas e diminuir a fila.

A seguir

Leia mais sobre casos de uso de computação em cluster no Google Cloud (páginas em inglês):

Leia mais sobre:

Primeiros passos com o cluster:

Exemplo de projetos no GitHub: