7 de outubro de 2011

Script, "oneliner", para teste de performance de sistemas de arquivos distribuidos

Muitos de vocês já devem ter se deparado com sistemas de arquivos distribuídos. Diferente de sistemas de arquivos locais, como ext3, NTFS, XFS, JFS, Fat32, e etc, os sistemas de arquivos distribuídos (ex: IBM GPFS, PanFS, PVFS2) se utilizam de vários servidores conectados à um disco comum entre eles (ou cada um à um disco dedicado) e conseguem atingir níveis de performance muito maiores que os esperados por sistemas de arquivos tradicionais (até mesmo quando comparando com sistemas como NFS e CIFS).

Existem muitas soluções que se beneficiam destes sistemas de arquivos, tais como: SAP Netweaver, SAP BW Accelerator, Web Servers (apache, tomcat, etc), e-mail (Exchange, Lotus Notes), Servidores de Arquivos, Computação de Alta Performance (HPC), Computação em Nuvem (Cloud Computing) e etc.

Costumeiramente, quando estou trabalhando em um cliente e quero demonstrar a performance deste sistema, uso um script básico para gerar uma carga neste sistema de arquivos. No mundo Linux temos uma terminologia que, quando escrevemos um mini-script na linha de comando, e não em um arquivo, chamamos, em inglês, de "oneliner script", ou seja, "script em uma linha".

Para podermos rodar este script que uso, basta:

1. Criar um arquivo com a lista de servidores (aqui será o nodes.list) e copiá-lo para os outros servidores

2. Garantir que há comunicação entre eles sem a necessidade do uso de senha para um usuário (veja no meu outro post como fazer isso)

3. Garantir que o sistema de arquivos distribuídos está montado (aqui será o diretório /gpfsFS1)

4. Rodar o script abaixo:

# for i in `cat /tmp/nodes.list`; do ssh -f $i 'for j in `cat /tmp/nodes.list`; do ssh -f $j dd if=/dev/urandom of=/gpfsFS1/$j.$(hostname).wrk bs=1048576 count=4000 ; done' ; done

onde temos:
if=/dev/urandom   :   o local onde vamos buscar informações para gerar um arquivo de teste. Pode ser também o /dev/zero, se quiser, ou /dev/random

of=/gpfsFS1/         :   o local onde vamos gravar os arquivos de teste. Importante que seja o diretório onde o seu sistema de arquivos paralelo está montado

bs=1048576          :    o tamanho do block size do seu sistema de arquivos. Aqui coloquei como 1M (ou 1048576 bytes)

count=4000          :     a quantidade de block sizes que iremos gravar, aqui sendo 4000. Ou seja, block size * count = tamanho do arquivo final. No caso acima, 1048576 * 4000 = 4Gbytes

O script irá ler o arquivo nodes.list e executar, para cada linha (cada servidor), um outro loop. Neste loop aninhado, ele irá, a partir de cada servidor da lista, acessar o outro servidor e mandar escrever um arquivo de 4GBytes no diretório do sistema de arquivos distribuídos.

Veja que, como há um loop aninhado, serão escritos muitos arquivos ao mesmo tempo e todos terão um total de 4Gbytes, ou seja, dependendo da quantidade de servidores que você tiver na lista o tamanho total de uso do sistema de arquivos poderá ser bem grande.

O paramêtro -f do ssh diz que é para cada interação ssh acontecer imediatamente e não esperar o término da execução do comando para voltar ao prompt. Ou seja, ao enviar o comando o ssh já irá retornar ao prompt fazendo com que o loop já envie o próximo comando sem esperar que o primeiro seja concluído. Dessa forma teremos, em paralelo, todos os processos escrevendo ao mesmo tempo e estressando o nosso sistema de arquivos paralelo.

Para medir a performance do sistema, use a sua ferramenta de análise preferida (seja uma linha de comando como o 'sar -b' - do pacote sysstat - ou seja uma ferramenta gráfica - por exemplo IBM Tivoli Monitoring).

obs: depois eu escrevo um post sobre como monitorar e analisar a performance de sistemas de arquivos, e como otimizá-los. ;)