Faça o Linux gravar no sistema de arquivos da rede simultaneamente com leituras de disco local

17

Sumário

Como você pode configurar o Linux para ler de um disco / sistema de arquivos local e gravar em um compartilhamento de rede ao mesmo tempo, em vez de ler enquanto nenhum dado estiver passando pela rede e enviá-lo pela rede enquanto o disco local estiver ocioso?

É muito mais rápido ler e escrever ao mesmo tempo, em vez de executar apenas uma operação e depois a outra de maneira alternada.

Detalhes

Estou movendo uma grande quantidade de dados de discos locais em uma máquina Linux para um dispositivo NAS.

Estou usando rsyncpara copiar basicamente /srv/datapara /mnt/nas, que é uma montagem CIFS.

Começou bem, lendo a 100 MB / s e gravando no NAS a 100 MB / s (limite de rede de gigabit), com a leitura e a gravação acontecendo simultaneamente.

No entanto, agora, algumas horas depois, estou descobrindo que está lendo no disco local, interrompendo a leitura enquanto grava no NAS e, quando não há mais dados para gravar no NAS, ele retoma a leitura do disco novamente. A rede está ociosa enquanto o disco está sendo lido e o disco está ocioso enquanto a rede está em uso.

Escusado será dizer que ler 200MB e depois escrever 200MB leva muito mais tempo do que ler e escrever esses 200MB ao mesmo tempo.

Como posso configurar o kernel de forma a manter o comportamento anterior de ler e escrever ao mesmo tempo, em vez de alternar entre ler e escrever, executando apenas uma operação por vez?

Algumas observações: quando o disco local lê a 100 + MB / s, tudo parece acontecer paralelamente, mas depois que o disco fica mais lento (parece que agora está com apenas 20 MB / s por algum motivo), é quando ocorre a leitura / gravação. mudança parece acontecer.

Também posso executar syncmanualmente a cada poucos segundos para que as gravações ocorram em paralelo com as leituras (embora obviamente a velocidades reduzidas), colocando syncum whileloop para que seja executado a cada cinco segundos não parece a solução certa ...

O kernel parece armazenar em cache cerca de 1 GB de dados e depois gravá-los na rede o mais rápido possível - o que é bom - só não entendo por que o disco lento precisa parar de ser lido enquanto os dados são enviados pelo rede.

Malvineous
fonte
1
A maioria das ferramentas unix não é absolutamente otimizada para largura de banda nesse sentido, nem rsync, nem mesmo um cp simples. Eles são aplicativos de thread único usando E / S de bloqueio.
peterh - Restabelece Monica
1
Em algum lugar, cerca de 100 MB / s também é o que você pode esperar dos modernos discos rígidos rotacionais comuns de 7200 rpm em cargas de trabalho puramente sequenciais. Ele diminui assim que você começa a procurar, como atualizar metadados ou se o sistema de arquivos está fragmentado, porque você se torna vinculado ao IOPS.
um CVn
você pode instalar o rsync no NAS?
Jasen

Respostas:

27

Após mais algumas investigações, parece que esse problema está menos relacionado ao kernel e mais sobre como o rsyncCIFS interage.

Pelo que sei, o que está acontecendo é que, quando rsyncfecha o arquivo de destino, o CIFS (e provavelmente qualquer sistema de arquivos de rede) garante que o arquivo seja completamente liberado e gravado no disco remoto antes que o closesyscall retorne. Isso é para garantir a qualquer aplicativo que, uma vez que a operação de fechamento seja concluída com êxito, o arquivo tenha sido completamente salvo e não haja risco de erros adicionais que possam causar perda de dados.

Se isso não fosse feito, seria possível que um aplicativo fechasse um arquivo, saia pensando que a operação de salvamento foi bem-sucedida e, posteriormente (talvez devido a um problema de rede) os dados não pudessem ser gravados, afinal, até então é tarde demais para o aplicativo fazer algo a respeito, como perguntar ao usuário se ele deseja salvar o arquivo em outro lugar.

Esse requisito significa que toda vez que a rsynccópia de um arquivo é concluída, todo o buffer de disco deve esvaziar a rede antes que rsyncseja permitido continuar lendo o próximo arquivo.

Uma solução alternativa é montar o compartilhamento CIFS com a opção cache=noneque desativa esse recurso e faz com que todas as E / S sejam direcionadas diretamente ao servidor. Isso elimina o problema e permite que leituras e gravações sejam executadas em paralelo, no entanto, uma desvantagem dessa solução é que o desempenho é um pouco menor. No meu caso, a velocidade de transferência da rede cai de 110 MB / s para 80 MB / s.

Isso pode significar que, se você estiver copiando arquivos grandes, o desempenho poderá ser melhor com o comportamento alternativo de leitura / gravação. Com muitos arquivos menores, desabilitar o cache resultará em menos descargas de cache cada vez que um arquivo for fechado, para que o desempenho possa aumentar lá.

Parece rsyncprecisar de uma opção para fechar seus identificadores de arquivo em outro segmento, para que ele possa começar a ler o próximo arquivo enquanto o último ainda estiver sendo liberado.

EDIT: Confirmei que cache=nonedefinitivamente ajuda a transferir muitos arquivos pequenos (traz de 10 MB / s até 80 MB / s), mas ao transferir arquivos grandes (1 GB ou mais) cache=nonereduz a transferência de 110 MB / s para os mesmos 80 MB / s. Isso sugere que a transferência lenta de muitos arquivos pequenos tem menos a ver com a procura do disco de origem e mais com tantas liberações de cache de todos os arquivos pequenos.

Malvineous
fonte
2
Que é um problema muito interessante, e obrigado por postar a explicação. rsyncnão ler o arquivo em um segmento diferente (na verdade, processo diferente), porque ele é projetado para que uma cópia rsyncestá em execução em cada lado da rede, embora no seu caso ambas as cópias estão do mesmo lado (e o sistema de arquivos está escondendo o fato de que existe uma rede). Eu acho que não ajuda, porque o processo do leitor enche muito rapidamente o cano enquanto o processo do gravador está bloqueando um close(). rsyncteria melhor desempenho se você estivesse usando rsynco fio, não o CIFS.
Celada
1
Eu imaginaria que outra solução é que você não pode rodar rsyncno NAS seria usar rsyncatravés da rede (como rsync -a files localhost:/dest/path), introduzindo artificialmente um enorme buffer (como, pelo menos, múltiplos megabytes, pelo menos) nas conexões de rede. Não sei como seria o melhor truque para fazer isso.
Celada
@ Celada: Obrigado! Sim, eu imagino que rodar rsyncna própria caixa NAS também resolva o problema. Um pouco mais complexo (permissões estranhas do NAS, necessidade de eliminar links simbólicos etc.), mas se eu tivesse um pouco mais de dados para copiar, valeria o investimento de tempo para fazer isso.
Malvineous
2
Possivelmente não relacionado ao seu caso: tive um problema semelhante há alguns anos atrás ao escrever a saída de dump(8)um NAS montado sobre NFS. Na época, eu diagnosticava o problema como maximizar a CPU no NAS, devido ao efeito combinado do servidor NFS e um firewall em execução no NAS (a caixa não estava enraizada e o firewall não podia ser desativado completamente de a interface da web). O problema desapareceu quando substituímos o NAS por um PC antigo. FWIW.
Satō Katsura
@SatoKatsura: Definitivamente, uma possibilidade para dispositivos NAS mais antigos, embora nesse caso eu imagine que você veria uma transferência geral mais lenta do que uma transferência como essa? Meu NAS é um Atom de núcleo duplo (~ 2GHz) que fica com cerca de 30% de uso da CPU ao maximizar uma NIC de gigabit sem quadros jumbo; portanto, tudo bem.
Malvineous