Vou explicar como funciona o sistema de Computação Distribuída usado nos Supercomputadores e como configurar um HPC: Cluster de Alto Desempenho!
| Se você apoia nosso site, desative o AdBlock quando visitá-lo, inclusive em Mobile!
Os anúncios são poucos e não invasivos. Se quiser contribuir com nosso trabalho, clique em qualquer banner de sua preferência, exceto dos Parceiros. Mais detalhes clicando aqui.
1. Introdução
O sistema de computação distribuída é algo que remonta desde os tempos de glória do UNIX. Os chamados CLUSTER’s consistem em uma rede de computadores ligados por uma LAN que trabalham em conjunto, sem usar a Internet diretamente, somando seu poder computacional ou trabalhando com processos em paralelo.
De forma interessante eles são operados por cientistas, pesquisadores, desenvolvedores e instituições de ensino para, por exemplo, sequenciamento de genomas, mapeamentos de vírus como a COVID19, previsão do tempo e muito mais!
Para que isso tudo funcione bem, é preciso coordenação, e essa coordenação das máquinas em rede pode ser feita de 3 maneiras.
1.1 Tipos
Esse conjunto de computadores pode funcionar de 3 maneiras principais:
- cluster de alto desempenho: também conhecido como cluster de alta performance, ele funciona permitindo que ocorra uma grande carga de processamento com um volume baixo de gigaflops em computadores comuns e utilizando sistema operacional Linux, o que diminui seu custo drasticamente; São os mais usados em processamento pesado, como cálculos de genomas, sequenciamento de vírus, etc.
- cluster de alta disponibilidade: são clusters cujos sistemas conseguem permanecer ativos por um longo período de tempo e em plena condição de uso; sendo assim, podemos dizer que eles nunca param seu funcionamento; além disso, conseguem detectar erros se protegendo de possíveis falhas; São mais usados em servidores de mídias sociais que não podem sair do ar.
- cluster para balanceamento de carga: esse tipo de cluster tem como função controlar a distribuição equilibrada do processamento. Requer um monitoramento constante na sua comunicação e em seus mecanismos de redundância, pois, se ocorrer alguma falha, haverá uma interrupção no seu funcionamento. Ele mescla o melhor dos dois mundos: Redundância e alto desempenho.
1.2 Exemplo de Cluster de Alto Desempenho
Na época que o PlayStation 3 estava em seu auge, era comum que instituições num geral usassem diversos consoles da Sony®, ligados em rede, rodando Linux, para criar clusters de alto desempenho a um preço baixo. O hardware, para a época, era equivalente a um pequeno supercomputador – pela arquitetura do processador ser PowerPC Octa-Core – a um preço atraente.
Cluster com vários PS3 na University of Massachusetts, foto de 2013
1.3 O Software
De forma resumida existem várias formas de se criar um cluster. Até mesmo com Kubernetes e DOCKER. No tutorial de hoje vou explicar como iniciar um cluster caseiro com o protocolo MPICH, que é mais antigo porém ainda em uso, simples de implementar, que permite o usuário que configurá-lo ter uma boa ideia de como é manusear esse tipo de sistema.
O tipo de cluster que o MPICH mais comumente gerencia é o de alto desempenho, então o objetivo será ter vários computadores com seus respectivos poderes computacionais somados – Aqui chamamos cada máquina de Nó da Rede.
Porém preciso de fazer algumas ressalvas pra você aventureiro. Este tutorial requer conhecimentos prévios em:
- Terminal.
Vamos usa-lo o tempo todo, sem qualquer interface gráfica. - Raspberry Pi.
Seu funcionamento, configurações básicas e seus principais componentes. - Conhecimento básico em Redes LAN, DNS e DHCP.
Configurar roteador ou fazer conexões em switchs, fixar IP’s, definir gateways, etc. - Por fim mas não menos importante: Requer que você tenha um conhecimento básico de alguma linguagem de programação entre Fortran, Python, C ou C++, as linguagens utilizadas pelo sistema de computação distribuída neste exemplo.
A computação distribuída normalmente não admite programas prontos, você deve escrever e compilar programas para tirar proveito do sistema. Mas teremos alguns Exemplos/Demonstrações para vê-lo funcionando quando estiver pronto!
2. Materiais
Uma coisa que eu preciso esclarecer: O Raspberry será nosso objeto de estudos, porém o que é ensinado aqui vale pra qualquer máquina! Apenas faça as adaptações necessárias, em vez do Raspbian, use o Ubuntu Server ou Debian; em vez de ARM, use arquitetura x64. Mas a grosso modo o conceito é o mesmo.
De tal forma, é importante mencionar que um cluster caseiro de computadores menos potentes e não tão profissional, é também chamado de Cluster Beowulf!
Exemplo de cluster Beowulf
Para criar o Cluster você vai precisar de:
- Raspberry Pi 3
Duas ou mais unidades, com respectivos kits completos com cartão de memória, case e dissipadores pois os chips esquentam muito no momento das compilações e cálculos. Recomendo o Pi 3B+ que é um pouco mais potente que o Pi 3B convencional e mais barato que um Pi 4. - Switch ou um roteador de internet extra que faça o trabalho de distribuir portas de rede com a finalidade de criar uma segunda LAN, evitando estresse do seu atual roteador/switch doméstico evitando deixar seus familiares enfurecidos por atrapalhar a Netflix® deles! – Desculpe mãe 🙁
- PatchCords para cada Pi, nada de WiFi! Computação distribuída exige o máximo desempenho de rede que conseguir.
- MicroSD Card 8GB ou maior.
Vamos evitar problemas de armazenamento, serão várias compilações e um cartão de 4 Gb pode ficar inadequado. - Os meus Pi’s não têm coolers mas eu recomendo que os kits que você comprar contenham; os chips passam facilmente dos 70 graus em picos de calculos e isso gera throtling, ou seja, o processador mata o desempenho para não fritar. Aqui eu supri tudo apenas com dissipadores de melhor qualidade.
- (Opcional) Caso os Pi’s não tenham Fonte própria, recomendo 1 HUB USB Sobrealimentado.
As saídas USB devem ter no mínimo 1.5 A, ideal 2.0A. - (Opcional) Cabos MicroUSB para os Raspberries caso use o HUB.
Os cabos devem ser de boa qualidade do tipo que suportem FastCharge (2A). Por experiência própria, evitem os da marca Samsung® por terem FastCharge porém matam a energia quando não detectam um smartphone; e deem preferência aos da AOC ou Philco, esses fornecem 2.1A reais, ideais para os Pi’s.
2.1 Confecção
A montagem é bem simples, energizar os Raspberries, ligar os cabos de rede dos Raspberries para o Switch e um patch cord sai do Switch para sua rede principal, assim você terá internet no todo.
No meu exemplo eu fiz inicialmente um esquema com tudo horizontalmente, com um Switch de 5 portas e 3 Raspberries (um do tipo 3B+ e dois do tipo 3B):
Depois fiz as devidas alterações e criei uma estrutura vertical para ficar mais condizente com “ei, isto é um cluster!”:
Nesse aspecto não existe certo e errado: Você fará a confecção da estrutura como achar conveniente!
Apenas tenha cuidado com os equipamentos e dê preferência para operar num local amplo, como uma bancada; e bem arejado, devido ao aquecimento dos componentes.
O conceito da LAN aqui é que você faça um cascateamento: Um cabo sairá do seu Switch principal para o segundo Switch. Assim as transições do Cluster acontecerão no segundo Switch e você continuará com acesso á internet em todos os nós da rede.
3. ClusterSSH
Pelo cerne do tutorial, conforme acima citado, espero que você já tenha uma prévia experiencia em algumas áreas. Precisamos que você configure o básico em todos os Raspberries, instalando o Raspbian Lite, sem desktop! Essa versão tem o menor consumo de RAM, portanto você terá em torno de 900 Mb livres para usar nos serviços do MPICH.
De forma sintética, após baixar a ISO, gravar ela no SDCard e ligar o Raspberry, o sistema automaticamente irá realocar o espaço em todo o SDCard. Após isso você poderá fazer login inicial nos Raspberries. Essa primeira configuração é interessante ter um monitor e teclado para certificar que está tudo em ordem antes de deixa-lo headless.
Recomendo que use um computador normal extra, como um notebook, para acessa-los no restante deste tutorial; para isso faça-o usando o ClusterSSH:
$ sudo apt install clusterssh
Com ele você faz comandos em todos os sistemas ao mesmo tempo de uma só vez!
Basta digitar:
$ cssh pi@192.168.0.2 pi@192.168.0.3 pi@192.168.0.4
Considerando que você não tenha trocado os usuários deles, todos serão “pi”.
Se você definiu a mesma senha para todos, será ainda mais fácil logar e configura-los!
Exemplo de como fica o acesso. Na minha tela eu usei o ClusterSSH abrindo 3 terminais, um para cada Pi. Pelo CSSH eu posso dar 1 comando que vá para todos – na pequena janelinha que se abre; ou posso clicar no xterm de cada Pi e mandar comandos individuais. Tambem abri um quarto terminal ao lado, usando meu terminal favorito – o MATE Terminal – para comandos no sistema Principal.
4. Raspbian
Após o Login inicial, usando o ClusterSSH faça o seguinte em todos os Raspberries:
- Atualize o Sistema.
- Habilite o SSH pelo raspi-config.
- Mude o hostname de cada Raspberry.
Para este tutorial, vamos utilizar 3 Raspberry Pi’s mas você poderá usar quantos quiser, desde que esse valor seja acima de 1, no mínimo 2: o primeiro chamei de principal e os demais serão os secundario1, secundario2, etc. O nome você define como achar conveniente – Bom evitar os termos master e slave de antigamente, são inapropriados. - Fixe os IPs dos Raspberries.
Os IPs da minha rede defini como 192.168.0.2 (principal), 192.168.0.3 (secundario1) e 192.168.0.4 (secundario2). Cada modem/roteador possui uma configuração e você deverá adaptar o seu á isso. Você pode fixar os IP’s dentro do próprio Raspberry ou, como eu prefiro, fixar diretamente fora da faixa DHCP direto no modem/roteador. Assim você evita problemas. - Não precisa instalar nada adicional por enquanto, nem ajustar nada mais, como firewall por exemplo. Deixe tudo default.
Com a rede pronta, vamos configurar o MPICH.
5. MPICH
Conforme sugerido acima, continue usando o ClusterSSH para configurar o MPICH em todos os Raspberries de uma vez.
O MPICH, formalmente MPICH2, é uma implementação portátil e disponível gratuitamente baseado no MPI (Mesage Passing Interface), um padrão para passagem de mensagens para aplicativos de memória distribuída usados em computação paralela.
De forma resumida, o MPI é uma forma de comunicar computadores em rede de forma rápida e direta, com latência baixa, usando linguagens de baixo nível como Fortran e C.
O conceito de computação distribuída dita basicamente que a primeira máquina definirá os comandos e serão repassados ás próximas máquinas; Para essa tarefa, cada uma das máquinas terá uma cópia do MPICH, do MPI4PY (mais abaixo explico sobre ele) e dos scripts .py que executarão no Cluster. Assim você não estressa a rede e nem estressa a primeira máquina, a rede vai servir para transacionar dados de cálculos e não diretamente scripts ou softwares brutos. O que é bom pra diminuir ao máximo a latência!
Como o MPICH é mais complicado de ajustar, explicarei em detalhes o que você deve fazer!
Aviso: NÃO utilize o mpich do repositório do Raspbian!
Eu sei da tentação de tentar “atalhar” o tutorial e dar “apt install mpich” diretamente, não faça isso. O mpich vai dar erro de “segmentation fault” na hora de rodar códigos Python e você vai ficar sem o que fazer a respeito.
O ideal é compilar o MPICH para o Raspberry (e qualquer hardware) como mostraremos abaixo.
Siga exatamente o seguinte, no ClusterSSH aberto, acessando todos os Pi’s ao mesmo tempo, digite:
- $ cd ~
- $ mkdir mpich2
- $ cd mpich2
- $ wget https://www.mpich.org/static/downloads/3.4.1/mpich-3.4.1.tar.gz
Até a data desta publicação a versão mais nova é a 3.4.1. Se houver uma mais nova, baixe a mais nova!
Não baixe as versões com a b c d no nome. - $ tar xfz mpich-3.4.1.tar.gz
- $ sudo mkdir /home/rpimpi/
- $ sudo mkdir /home/rpimpi/mpi-install
- $ sudo mkdir /home/pi/mpi-build
- $ sudo apt install gfortran
- $ sudo /home/pi/mpich2/mpich-3.4.1/configure -prefix=/home/rpimpi/mpi-install
Esse comando vai pré-configurar o MPICH. Aguarde. – Demora! - $ sudo make
Essa é a compilação do MPICH. Aqui no meu Raspberry Pi 3B 1.4Ghz demorou 2:30h aprox.
Vá tomar um ar puro! - $ sudo make install
- $ cd ..
- $ nano .bashrc
Adicione esta linha no final do arquivo:
PATH=$PATH:/home/rpimpi/mpi-install/bin
Salve com CTRL+O, ENTER, feche com CTRL+X - $ sudo reboot
5.1 Sintaxe
O MPICH é executado sempre com o binário mpiexec + parâmetro de quantos núcleos de processador você tem e gostaria de usar + comando a ser executado. Assim:
$ mpiexec -n 1 hostname
Ao fim do comando, se deu certo, você verá uma saída com o respectivo hostname de cada Raspberry:
Por enquanto, é apenas Localhost. Se isso aqui deu certo, seu MPICH2 está configurado corretamente!
5.2 MPI4PY
O MPI4PY é um tradutor de Python para MPICH, permitindo que o MPICH execute scripts Python 2.7 e 3.0+. Tal qual o MPICH anteriormente, o MPI4PY também requer ser compilado para que funcione adequadamente.
Siga exatamente o seguinte, no ClusterSSH aberto, acessando todos os Pi’s ao mesmo tempo, digite:
- $ wget https://bitbucket.org/mpi4py/mpi4py/downloads/mpi4py-3.0.3.tar.gz
Até a data desta publicação a versão mais nova é a 3.4.1. Se houver uma mais nova, baixe a mais nova! - $ tar -zxf mpi4py-3.0.3.tar.gz
- $ cd mpi4py-3.0.3
- $ sudo apt install python-dev
- $ python setup.py build
- $ sudo python setup.py install
- $ cd ~
- $ nano .bashrc
Adicione esta linha no final do arquivo:
export PYTHONPATH=/home/pi/mpi4py-3.0.3
Por fim, teste:
$ mpiexec -n 1 python /home/pi/mpi4py-3.0.3/demo/helloworld.py
Se tudo deu certo, após o último comando você verá o script executando corretamente! Observe a adição do comando python dentro da sintaxe de comando do mpiexec.
Por enquanto, é apenas Localhost. Se isso aqui deu certo e exibiu uma linha de Hello World em cada Raspberry, seu MPICH2 está configurado corretamente!
O MPICH e o MPI4PY estão compilados e executam bem localmente em todos os nós. Agora, vamos configura-los para se comunicarem!
6. Definindo o Cluster: SSH
O protocolo MPICH utiliza o SSH para se comunicar com os nós. Assim, todos os cálculos e comando enviados de um para outro passarão pelo túnel do SSH, o que trará segurança e também bom desempenho ao sistema.
Para que o MPICH opere adequadamente, todos os nós devem ter a chave PublicKey SSH de todos, salva, em authotized_keys. Assim, quando o Principal for contactar o Segundário1 para rodar algum comando, este deverá fazer diretamente, sem que peça senha.
Ainda no ClusterSSH, vamos gerar as chaves públicas pra cada Pi:
$ ssh-keygen
Quando perguntar “Enter file in which to save the key” apenas tecle Enter; quando perguntar “Enter passphrase” também aperte apenas Enter, sem uma senha.
Daqui em diante, os comandos não podem ser feitos no ClusterSSH, porque diferem de Pi para Pi.
A estrutura de comandos será essa, adapte conforme o Raspberry configurado (faça isso individualmente com todos):
No Pi Principal:
- $ cd ~/.ssh
- $ cp id_rsa.pub Principal
Dê o mesmo nome que o seu hostname. Aqui no exemplo, Principal. Repita para os demais.
Agora que você tem a chave pública com o respectivo nome de cada Pi, transfira essas chaves para dentro de cada Pi!
De forma didática, a configuração ficará assim:
- Principal < recebe as chaves públicas SSH dos Pi’s Secundário1 e Secundário2
- Secundário1 < recebe as chaves públicas SSH dos Pi’s Principal e Secundário2
- Secundário2 < recebe as chaves públicas SSH dos Pi’s Secundário1 e Principal
Transfira entre as máquinas da forma que achar melhor: SFTP, SCP, SMB, FTP, etc.
Deixe elas dentro de:
$ ~/.ssh
Uma vez que você tem as chaves de todas as máquinas em todas as máquinas, adicione elas ao final do arquivo authotized_keys.
No exemplo, dentro do Pi cujo hostname é Principal você deve ter as chaves já copiadas, então faça:
- $ cd ~/.ssh
- $ cat secundario1 >> authorized_keys
- $ cat secundario2 >> authorized_keys
Repita esse procedimento seguindo a mesma lógica nos demais Pis.
7. MachineFile
Para se comunicar com os demais Raspberries, todos devem ter o “machinefile”, um pequeno arquivo de texto com os IP’s das máquinas. No exemplo, eu havia definido os IP’s 192.168.0.2, 192.168.0.3 e 192.168.0.4 para meu Cluster. Então:
- $ cd ~
- $ nano machinefile
Digite de forma direta os IP’s, 1 por linha:
192.168.0.2 192.168.0.3 192.168.0.4
Faça conforme sua configuração!
Salve com CTRL+O, Enter, feche com CTRL+X.
8. Hora dos Cálculos!
Cluster configurado e operando, vamos testar!
Aqui você pode acessar o Principal com SSH diretamente. O Hello World no meu exemplo é o seguinte:
$ cd ~
$ mpiexec -n 3 -f /home/pi/machinefile python /home/pi/mpi4py-3.0.3/demo/helloworld.py
Se tudo correr bem você será contemplado com a seguinte saída de comando:
Oficialmente o Raspberry “principal” deu um comando HelloWorld para todos os nós (inclusive a si mesmo), os Raspberries fizeram o que foi pedido, devolveram o resultado ao Principal, que exibiu tudo no terminal.
O cluster está operante!
Explicando e fazendo observações pertinentes:
- -n 3
Número de núcleos de processamento, proporcional ao número de nós.\
O MPICH sempre pega 1 núcleo por vez, distribuindo entre todos os nós. Por exemplo, se definir número = 3, ele criará 1 processo pra cada Pi. Se você definir número = 6, serão 2 processos para cada Pi; e se definir número = 7, Os processos serão distribuidos Pi a Pi, até que o primeiro Pi ficará com 1 a mais que os demais. Para usar tudo, potência máxima, no exemplo, use número = 12, assim ele usará 12 núcleos dos 3 processadores quad-core de cada Pi do Cluster.
Essa lógica vale também para qualquer arquitetura e computador usado. Se você fizer um cluster com 2 computadores octa-core, os processos serão distribuídos núcleo a núcleo alternando entre os 2 PC’s; Ao fim, número = 16 fará o Cluster operar em potência máxima.
- -f machinefile
É o arquivo que define quais os IP’s dos Nós.
Do jeito que configuramos tecnicamente você pode usar qualquer Pi como Principal, depende apenas de você e do que desejar realizar. O MPICH não faz nada se o usuário não ordenou e não executa nada em segundo plano até que o comando seja dado manualmente ou programado no Cron.
O mpiexec gerou 3 processos, 1 para cada nó e pelo script apontou qual computador fez qual processo. O Principal por sua vez coleta os resultados de todos, exibindo-os para você.
Ou seja: O Secundário2 é meu Pi (3b+ de 1.4 Ghz), mais poderoso que o Principal (3B de 1.2 Ghz) e o Secundário1 (também 3B de 1.2 Ghz). Isso afeta a ordem de exibição dos resultados. O Secundário2 vai responder rapidamente, sendo o primeiro da lista, o Principal será o segundo, porque apesar de lento é o Localhost; e o Secundário1 responderá por último, porque é um Nó na rede e é igualmente lento. – Aqui o delay do Switch vai contar pontos de desempenho.
O fato dos resultados serem exibidos fora de ordem, por ordem de “quem processou e terminou primeiro” é uma prova natural de que o Cluster está operando, dentro dos limites de cada hardware que o compõe!
8.1 Exemplo 2
Dentro da pasta Demo tem um cálculo que usa todos os núcleos do Cluster para chegar ao valor mais próximo de Pi.
O comando aqui será dado com -n = 12 para termos máximo desempenho.
$ mpiexec -n 12 -f /home/pi/machinefile python /home/pi/mpi4py-3.0.3/demo/compute-pi/cpi-rma.py
O comando HTOP, com o ClusterSSH, nos permitirá ver que todos os Raspberries estão operando com os 4 núcleos em 100%:
Ao fazer o comando, ele perguntará quantos intervalos você deseja para o cálculo. Quanto maior o valor, mais próximo de PI o resultado será. Considerando que Pi vale 3,14159 26535 89793 23846 26433 83279, qualquer valor próximo disso é interessante.
Observe que com apenas 1000 intervalos, a margem de erro é de 0.0000000833333331 gerando o valor de PI de “3.1415927369231262”, enquanto que com 1000000, a margem de erro é de 0.0000000000000830 e o valor encontrado é “3.1415926535898762”.
Bem próximo do valor exato!
Os Raspberries não toleram um valor absurdo demais como “1.000.000.000” no Intervalo e vai dar erro de calculo por inanição de recursos. Porém se o Cluster for com mais Nós e/ou com nós mais potentes, tipo Intel Core i3 ou mesmo i5, o resultado será dado satisfatoriamente.
E mais: Se você fizer o mesmo calculo com número = 1 (1 processo de 1 Pi) o resultado vai demorar vários minutos pra sair, coisa que aparece em segundos com número = 12.
9. Demonstrações
O GitHub tem alguns scripts de demonstração; mas se você quiser testar mais, dentro da pasta /home/pi/mpi4py-3.0.3/demo/ existem várias demos de vários tipos.
Inclusive os scripts começando em .osu_ são benchmarks de rede, para você ver o nível de desempenho que seu cluster possui nas transmissões de dados.
Essa latência no Exemplo é a soma da ponte entre todos os Nós, retornando ao Principal.
10. Considerações Finais
Tirando o “python” da sintaxe do comando, você poderá rodar scripts em C, Fortran e C++ normalmente com o Cluster. Inclusive até comandos em Bash rodam diretamente pelo MPICH, que é um Mensageiro de sistema então quase qualquer coisa ali vai ser reencaminhado.
Mas somente um script que faça as chamadas apropriadas vai dividir os processos em partes iguais entre todos os Nós para que os cálculos que um Cluster fizer tenham real ganho de desempenho.
Não vou entrar em muitos detalhes aqui porque eu realmente não tenho muito conhecimento nessas linguagens. E a Python, que eu domino bem, pode ser para você, como foi para mim, um pontapé para iniciar em projetos e desenvolvimento de sistemas Cluster!
Sejam em aplicações militares, científicas de sequenciamento de Genomas até mesmo previsão do tempo, os Clusters são uma forma interessante e barata de se ter grande poder computacional sem necessariamente precisar investir tempo e dinheiro em 1 computador absurdamente poderosos que custe uma fortuna. E agora você teve a oportunidade de confeccionar um em casa, lembre-se: O que mostrei aqui pode ser feitos com vários notebooks, gabinetes, Linux em um PS3, etc… A imaginação será seu limite.
Fontes:
rasmurtech
cluster
Autodidata, me aprofundei em sistemas operacionais baseados em UNIX®, principalmente Linux. Também procuro trazer assuntos correlacionados direta ou indiretamente, como automação, robótica e embarcados.
O assunto é muito interessante, porém a linha: “$ sudo /home/pi/mpich2/mpich-3.4.1/configure -prefix=/home/rpimpi/mpi-install”, após a intalação do Fortran, não fez sentido. Poderia rever esse passo, por gentileza?
Essa linha possui um espaço após “configure”.
Explicação: O comando executará o binário CONFIGURE usando o /home/rpimpi/mpi-install como PREFIX, passando-o como argumento com 1 hífen.
Assim sendo: $ sudo /home/pi/mpich2/mpich-3.4.1/configure [ESPAÇO] -prefix=/home/rpimpi/mpi-install