Opções para sincronizar com eficiência 1 milhão de arquivos com servidores remotos?

27

Em uma empresa em que trabalho, temos uma coisa chamada "playlists", que são pequenos arquivos ~ 100 a 300 bytes cada. Há cerca de um milhão deles. Cerca de 100.000 deles são trocados a cada hora. Essas listas de reprodução precisam ser carregadas em outros 10 servidores remotos em diferentes continentes a cada hora e precisam acontecer rapidamente em menos de 2 minutos, idealmente. É muito importante que os arquivos excluídos no mestre também sejam excluídos em todas as réplicas. Atualmente, usamos o Linux para nossa infraestrutura.

Eu estava pensando em tentar o rsync com a opção -W para copiar arquivos inteiros sem comparar o conteúdo. Ainda não tentei, mas talvez as pessoas com mais experiência com o rsync possam me dizer se é uma opção viável?

Que outras opções vale a pena considerar?

Atualização: eu escolhi a opção lsyncd como resposta, mas apenas porque era a mais popular. Outras alternativas sugeridas também são válidas à sua maneira.

Zilvinas
fonte
11
Você tem um log indicando quais arquivos foram alterados ou excluídos?
Oliver
3
Se apenas as listas de reprodução fossem registros mysql. Você pode usar a replicação do banco de dados e fazer com que o mysql decida o que é necessário para ser enviado / recebido.
Matt
@oliver fazemos. No entanto, você precisa confiar nesse log, o que significa que o código que o gera deve estar correto e, em seguida, o código personalizado para processar esse log, que também precisa estar correto. Prefiro evitar o código interno para fazê-lo sobre algo que foi extensivamente testado pela comunidade.
Zilvinas
Deseja que a alteração seja aplicada apenas a cada hora? Ou a replicação instantânea também é aceitável?
faker
11
Não subestime o tempo que leva para o rsync trabalhar com um milhão de arquivos. Apenas tente e você verá o que está fazendo. Se você possui esse log, use-o ou tente qualquer outra das soluções propostas.
Oliver

Respostas:

39

Como atualizações instantâneas também são aceitáveis, você pode usar o lsyncd .
Ele assiste diretórios (inotify) e rsyncmuda para escravos.
Na inicialização, ele ficará cheio rsync, de modo que levará algum tempo, mas depois disso somente as alterações serão transmitidas.
A observação recursiva dos diretórios é possível, se um servidor escravo estiver inativo, a sincronização será repetida até que ele volte.

Se tudo isso estiver em um único diretório (ou em uma lista estática de diretórios), você também poderá usar o incron .
A desvantagem é que ele não permite a visualização recursiva de pastas e você precisa implementar a funcionalidade de sincronização.

falsificador
fonte
Mais uma vez uma ponta brilhante :)
Zilvinas
11
+1 Esse é essencialmente um problema de coerência do cache, um monitor que aperta as alterações é a solução mais fácil. lsyncdimplementos que ...
Chris S
11
Eu investigaria lsyncde inotifyaplicaria profundamente o seu sistema operacional de servidor específico. Há um limite no número de relógios inotify disponíveis. Acredito que o padrão seja em torno de 1500 ou 8000, dependendo da sua versão específica do Linux. A maioria dos kernels permite aumentar o limite, mas o monitoramento de 1 milhão de arquivos pode ser mais do que é prático. Não funcionou para mim em 2008. Além disso, a fila de eventos inotify pode transbordar, causando a perda de eventos, e você precisa ter uma maneira de se recuperar disso. Uma lsyncdimplementação cuidadosamente ajustada e um diário rsyncpodem funcionar agora em 2012 para cobrir suas bases.
Old Pro
2
Na verdade, ele faz um iontifysobre o diretório não os arquivos individuais. Quantos diretórios você pode assistir? Verifique /proc/sys/fs/inotify/max_user_watches(geralmente 8192).
faker
2
Com ~ 50k diretórios, o inotify provavelmente não será bem dimensionado. Quando tentamos uma abordagem semelhante em 2009 com diretórios de 100k, demorou muito tempo para o kernel assinar todos os diretórios. Quanto ao @OldPro, não funcionou para nós.
Neovatar
11

Considere usar um sistema de arquivos distribuído, como o GlusterFS . Sendo projetado com replicação e paralelismo em mente, o GlusterFS pode escalar até 10 servidores de maneira muito mais suave do que as soluções ad-hoc envolvendo inotify e rsync.

Para esse caso de uso específico, é possível criar um volume GlusterFS de 10 servidores com 10 réplicas (ou seja, 1 réplica / bloco por servidor), para que cada réplica seja um espelho exato de todas as outras réplicas do volume. O GlusterFS propagaria automaticamente as atualizações do sistema de arquivos para todas as réplicas.

Os clientes em cada local entrariam em contato com o servidor local, portanto, o acesso de leitura aos arquivos seria rápido. A questão principal é se a latência de gravação pode ser mantida aceitavelmente baixa. A única maneira de responder a isso é tentar.

Steven segunda-feira
fonte
+1 para Glusterfs
Tom O'Connor
8

Duvido rsyncque funcionaria para isso da maneira normal, porque a digitalização de um milhão de arquivos e a comparação com o sistema remoto 10 vezes levaria muito tempo. Eu tentaria implementar um sistema com algo assim inotifyque mantém uma lista de arquivos modificados e os envia para os servidores remotos (se essas alterações não forem registradas de outra maneira). Você pode usar essa lista para identificar rapidamente os arquivos que precisam ser transferidos - talvez até com o rsync (ou melhor, 10 instâncias paralelas).

Edit: Com um pouco de trabalho, você pode até usar essa abordagem de inotify / log watch para copiar os arquivos assim que a modificação acontecer.

Sven
fonte
5

Mais algumas alternativas:

  • Insira um trabalho no RabbitMQ ou no Gearman para desativar de forma assíncrona e excluir (ou adicionar) o mesmo arquivo em todos os servidores remotos sempre que você excluir ou adicionar um arquivo no servidor principal.
  • Armazene os arquivos em um banco de dados e use a replicação para manter os servidores remotos sincronizados.
  • Se você possui o ZFS, pode usar a replicação do ZFS .
  • Algumas SANs têm replicação de arquivos. Não faço ideia se isso pode ser usado pela Internet.
Ladadadada
fonte
4

Este parece ser um caso de uso ideal de livro de histórias para o MongoDB e talvez o GridFS . Como os arquivos são relativamente pequenos, o MongoDB por si só deve ser suficiente, embora possa ser conveniente usar a API do GridFS.

O MongoDB é um banco de dados nosql e o GridFS é uma compilação de armazenamento de arquivos. O MongoDB possui muitas opções internas de replicação e sharding , portanto deve ser muito bem dimensionado no seu caso de uso.

No seu caso, você provavelmente começará com um conjunto de réplicas que consiste no mestre localizado no seu datacenter primário (talvez um segundo, caso deseje fazer failover no mesmo local) e seus dez "escravos" distribuídos pelo mundo. Em seguida, faça testes de carga para verificar se o desempenho de gravação é suficiente e verifique os tempos de replicação em seus nós. Se você precisar de mais desempenho, poderá transformar a configuração em fragmentada (principalmente para distribuir a carga de gravação para mais servidores). O MongoDB foi projetado com a expansão de grandes configurações com hardware "barato", para que você possa instalar um lote de servidores baratos para melhorar o desempenho.

neovatar
fonte
0

Eu usaria um S3 Backend e montaria isso em todos os servidores necessários - dessa forma, todos estarão sincronizados instantaneamente de qualquer maneira

Mister IT Guru
fonte
Enquanto o armazenamento estiver sincronizado, você deverá notificar o aplicativo, voltando à estaca zero ou o aplicativo terá que pesquisar o armazenamento sempre que alguém acessar essas listas de reprodução. O desempenho seria horrível em ambos os casos.
Chris S
O aplicativo não precisa pesquisar o armazenamento toda vez que alguém acessa as listas de reprodução, apenas o suficiente dentro de uma hora para garantir que o aplicativo esteja sendo executado sem dados antigos. Além disso, se o S3 é usado como back-end, por que o aplicativo precisaria pesquisar os arquivos em primeiro lugar? Eles sempre estarão atualizados
Mister IT Guru
0

Uma opção que parece não ter sido mencionada ainda é arquivar todos os arquivos em um arquivo compactado. Isso deve reduzir significativamente o tamanho total e remover toda a sobrecarga que você recebe ao lidar com milhões de arquivos individuais. Ao substituir todo o conjunto de arquivos em uma grande atualização, você também pode ter certeza de que os arquivos removidos são removidos nas réplicas.

A desvantagem é que você está transferindo muitos arquivos desnecessariamente. Isso pode ou não ser compensado pelo tamanho reduzido graças à compressão. Também não tenho idéia de quanto tempo levaria para compactar tantos arquivos.

Supr
fonte