sincronizando servidores de armazenamento

4

temos um servidor de armazenamento, com atualmente cerca de 20TB de arquivos de mídia que queremos sincronizar com um segundo servidor de armazenamento, para backup e failover. os fatos são:

  • estamos armazenando atualmente cerca de 9.000.000 de arquivos
  • tamanhos de arquivo de vários KB até 1 GB
  • somente a sincronização unidirecional é necessária
  • os arquivos não são atualizados e não há exclusões - apenas novos arquivos para sincronizar
  • os servidores de armazenamento estão executando o open-e, eles são montados como volumes NFS na rede

atualmente usamos apenas o rsync simples em um terceiro servidor para executar a sincronização.

eu gostaria de saber, se existem ferramentas melhores para uma quantidade tão grande de arquivos - comerciais ou de código aberto?

thanx muito,

    
por harald 24.02.2010 / 13:33

2 respostas

3

Você poderá ver um aumento no desempenho se apenas usou um script manual rolado que verificou o tempo de criação do arquivo (e possivelmente o tamanho) e o comparou a uma lista (ou registro) de arquivos que já foram sincronizados com o servidor de backup.

O rsync pode estar gastando muito tempo procurando alterações em TODOS os seus arquivos quando uma verificação de um ou dois atributos de arquivo pode ser suficiente.

Fazemos algo semelhante, mas em uma escala muito menor, para sincronizar fotos entre dois servidores. Eu escrevi um script bash que mantém um registro ordenado de arquivos concatenados junto com tempos de criação de arquivos e tamanhos de arquivo. Toda vez que o script é executado, ele verifica o servidor do qual fazemos a sincronização (o servidor de origem) e gera uma lista classificada de arquivos concatenados com os tempos de criação e os tamanhos dos arquivos. Em seguida, uso o comando comm para comparar esses dois registros e só imprimo as entradas que aparecem no servidor de origem. Esta é a lista de arquivos que devem ser sincronizados com o novo servidor.

Então eu apenas scp os novos arquivos. Eu tenho alguns trapping, bloqueio e throttling lá para que ele não sobrecarregue as coisas, mas funciona e é muito rápido.

O bom é que você não precisa sincronizar tudo para começar, se já tiver muitos arquivos em ambos os lugares. Basta criar um registro inicial no servidor de destino, depois cronar o script e ele iniciará a sincronização a partir desse ponto. Se você acabar precisando sincronizar um arquivo que nunca pensou que faria, basta tocar nele (para alterar as informações de data) no servidor de origem e ele será sincronizado na próxima execução programada.

Portanto, para um diretório com esta aparência:

-rw-r----- 1 example example  38801 2010-01-21 11:45 1.JPG
-rw-r----- 1 example example  38801 2010-01-21 11:45 2.JPG
-rw-r----- 1 example example 757638 2010-01-21 11:45 3.JPG
-rw-r----- 1 example example  16218 2010-01-22 15:07 9.JPG

Esta listagem é transformada pelo script em um arquivo de registro com a seguinte aparência:

1.JPG_2010-01-21_11:45_38801
2.JPG_2010-01-21_11:45_38801
3.JPG_2010-01-21_11:45_757638
9.JPG_2010-01-22_15:07_16218

Eu armazeno esse registro (dos arquivos do servidor de origem) no servidor de destino. Toda vez que a tarefa cron funciona no servidor de destino, eu crio uma lista dos arquivos atualmente no servidor de origem usando o mesmo formato. Digamos que alguns novos arquivos, 10.JPG e 11.JPG apareceram na listagem.

-rw-r----- 1 example example  38801 2010-01-21 11:45 1.JPG
-rw-r----- 1 example example  38801 2010-01-21 11:45 2.JPG
-rw-r----- 1 example example 757638 2010-01-21 11:45 3.JPG
-rw-r----- 1 example example  16218 2010-01-22 15:07 9.JPG
-rw-r----- 1 example example  16218 2010-02-24 11:00 10.JPG
-rw-r----- 1 example example  16218 2010-02-24 11:00 11.JPG

O registro atual do arquivo será parecido com este:

1.JPG_2010-01-21_11:45_38801
2.JPG_2010-01-21_11:45_38801
3.JPG_2010-01-21_11:45_757638
9.JPG_2010-01-22_15:07_16218
10.JPG_2010_02_24_11:00_16218
11.JPG_2010_02_24_11:00_16218

Executando comm em relação ao registro antigo e ao registro atual e cortando o primeiro campo (o arquivo que precisa ser copiado) da seguinte forma:

comm -23 ${CURRENT_REG} ${OLD_REG} | cut -d'_' -f1 > ${SYNC_LIST}

Produzirá uma lista de arquivos (um por linha) que precisam ser copiados (eu uso o scp) para o servidor de backup (destino):

10.JPG
11.JPG

Depois, você processa a lista de arquivos por meio de um loop.

O comando comm acima está basicamente dizendo: mostre-me tudo o que SOMENTE existe no primeiro arquivo. As comparações feitas também são muito rápidas. É só comparar linhas em um arquivo de texto depois de tudo; mesmo que esse arquivo seja muito grande. Felizmente, você preencheu esse arquivo de texto com alguns meta-dados básicos sobre seus arquivos e, por meio de comm , estão comparando esses dados muito rapidamente.

O bom de colocar esses meta-dados na lista é que isso permitirá situações em que o arquivo foi alterado entre sincronizações. Digamos que uma nova versão do arquivo aparece ou houve um problema com o antigo. O nome do arquivo existirá no registro antigo, mas seus metadados (registro de hora e tamanho de criação de arquivo) serão diferentes. Portanto, o registro de arquivo atual mostrará que a diferença e a comparação comm dirão que essa informação existe somente no primeiro arquivo. Quando você criar a lista de arquivos a serem copiados, o nome do arquivo estará lá e o comando copy substituirá o arquivo desatualizado com o mesmo nome.

O resto é apenas detalhes:

  • Use o bloqueio de arquivo / semáforos para que você não tenha o script sendo executado se a última vez que ele foi executado não for feito na próxima vez que for executado.
  • Use arquivos temporários para armazenar sua lista de arquivos atual e sua lista de processos e, em seguida, use traps para limpá-los na saída do script.
  • Quando tudo estiver pronto, copie a lista de arquivos atual sobre a lista de arquivos antiga para estar pronto para a próxima comparação, mas faça-o somente se o registro tiver arquivos nele (caso contrário, você copiará um registro vazio e sincronizar TUDO da próxima vez).

Espero que ajude. Isso funciona muito bem para a nossa situação, mas, como acontece com todas as coisas, pode não funcionar dentro das restrições de sua organização ou configuração. Boa sorte, no mínimo, pode dar algumas idéias.

    
por 24.02.2010 / 17:51
1

Aqui estão algumas opções para analisar.

Procure no DBRD se não precisar acessar as duas cópias ao mesmo tempo. Isso se deve às limitações do sistema de arquivos, não às limitações do DBRD, e há um poucos trabalhos para acessar a segunda cópia se você preciso. Mas o projeto foi aceito recentemente no kernel, então o suporte para isso deve ser bem simples.

Outra opção seria um sistema de arquivos, como o GlusterFS . O que pode ser configurado em configuração replicada de 2 nós. Eu acho que isso seria ideal, pois deve permitir um melhor failover e escalabilidade. O MondoDB também parece interessante para esse tipo de coisa usando o GridFS, mas é um pouco mais novo.

    
por 24.02.2010 / 16:52