Faça o Linux gravar no sistema de arquivos de rede simultaneamente com as leituras de disco locais

16

Resumo

Como você pode configurar o Linux para ler a partir de um disco / sistema de arquivos local e gravar em um compartilhamento de rede ao mesmo tempo, em vez de ler enquanto não há dados na rede, enviando esses dados pela rede enquanto disco local está ocioso?

É muito mais rápido ler e escrever ao mesmo tempo, em vez de apenas executar 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 rsync para copiar basicamente /srv/data em /mnt/nas , que é uma montagem CIFS.

Começou bem, lendo a 100MB / seg e escrevendo para o NAS a 100MB / seg (limite de rede gigabit), com leitura e escrita acontecendo simultaneamente.

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

Escusado será dizer que, lendo 200MB, em seguida, escrever 200MB demora muito mais do que ler e escrever que 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ê em 100 + MB / s, tudo parece acontecer em paralelo, mas quando o disco desacelera (parece estar indo a apenas 20MB / s agora, por algum motivo), é aí que a comutação de leitura / gravação parece acontecer.

Também posso executar sync manualmente a cada poucos segundos para que as gravações ocorram em paralelo com as leituras (embora obviamente em velocidades reduzidas), colocando sync em um loop while 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 escrevê-los na rede o mais rápido possível - o que é bom - eu não entendo porque o disco lento precisa parar de ser lido enquanto os dados estão sendo enviados pela rede.

    
por Malvineous 18.12.2016 / 09:06

1 resposta

25

Depois de mais algumas investigações, parece que esse problema é menos relacionado ao kernel e mais sobre como o rsync e o CIFS interagem.

Até onde eu sei, o que está acontecendo é que quando rsync fecha o arquivo de destino, o CIFS (e provavelmente qualquer sistema de arquivos da rede) garante que o arquivo seja completamente liberado e gravado no disco remoto antes do close syscall retorna. Isso é para assegurar que qualquer aplicativo, uma vez concluída a operação de fechamento, tenha sido completamente salvo e não haja risco de mais erros que possam causar perda de dados.

Se isso não foi feito, seria possível que um aplicativo feche 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 puderam ser gravados, mas aí é tarde demais para o aplicativo fazer alguma coisa, como perguntar ao usuário se ele deseja salvar o arquivo em outro lugar.

Esse requisito significa que sempre que rsync terminar de copiar um arquivo, todo o buffer de disco deverá ser esvaziado pela rede antes que rsync tenha permissão para continuar lendo o próximo arquivo.

Uma solução alternativa é montar o compartilhamento CIFS com a opção cache=none , que desativa esse recurso e faz com que todas as E / S sejam direcionadas 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 110MB / seg para 80MB / seg.

Isso pode significar que, se você estiver copiando arquivos grandes, o desempenho pode ser melhor com o comportamento alternado de leitura / gravação. Com muitos arquivos menores, desabilitar o cache resultará em menos limpezas de cache sempre que um arquivo for fechado, portanto, o desempenho pode aumentar.

Parece que rsync precisa de uma opção para fechar suas alças de arquivo em outro thread, para que ele possa começar a ler o próximo arquivo enquanto o último ainda está sendo liberado.

EDITAR: Confirmei que cache=none definitivamente ajuda na transferência de muitos arquivos pequenos (de 10MB / s para 80MB / s), mas ao transferir arquivos grandes (1GB +) cache=none reduz a transferência de 110MB / seg para os mesmos 80MB / seg. Isso sugere que a transferência lenta de muitos arquivos pequenos é menor em relação à procura de disco de origem e mais sobre ter tantos esvaziamentos de cache de todos os arquivos pequenos.

    
por 18.12.2016 / 09:38