O motivo da grande diferença de velocidade é que a transferência de um arquivo e um instantâneo não podem ser comparados. Um arquivo é E / S sequencial e um instantâneo é E / S aleatória, pois contém os blocos que foram alterados.
Eu testei uma conexão de 10Gbit entre dois hosts para poder ler um arquivo de 10GB do host1 e gravá-lo no host2 usando o netcat, onde a velocidade era de 410MB / s.
Quando envio / recebo novamente o ZFS com o netcat pela mesma conexão dedicada de 10 Gbit, só obtenho 70 MB / s. O instantâneo foi de 2,5 TB com 15 milhões de arquivos.
Pergunta
Qual poderia ser o motivo dessa desaceleração? É o gargalo que leva muito tempo para reverter um instantâneo com esses muitos arquivos ou o número de arquivos não tem uma influência da velocidade de reversão do ZFS?
Atualizar
O teste de transferência de arquivos de 10 GB onde eu obtive 410MB / s, suponho, simula um envio / recebimento de ZFS com reversão. Então, com essa suposição, estou muito surpreso por ver velocidades tão diferentes. Estou usando a velocidade para comparação entre os dois testes, então não preciso gerar um arquivo de 2,5 TB com dados aleatórios.
Então eu não entendo porque "ler arquivo do host1, transferir com netcat, gravar arquivo no host2" é muito mais rápido que "zfs enviar instantâneo do host1, transferir com netcat, receber / reverter no host2".
Talvez outra maneira de perguntar o mesmo seria?:
Se eu tiver dois instantâneos de 2,5 TB de tamanho igual, em que snapshot1 contém 1 arquivo e snapshot2 contém 15 milhões de arquivos. O tempo para zfs receive
para ambos será o mesmo? Ou será um mais rápido que o outro?
O número de arquivos e diretórios envolvidos em um fluxo zfs send / recv não deve ter impacto direto em sua velocidade de transferência. Indiretamente, pode acontecer, porque geralmente é verdade dizer que a propagação do conjunto de dados em seus discos será maior com mais diretórios / arquivos, dependendo da carga de trabalho que os gerou. Isso é importante, porque é muito mais fácil para um disco rígido fazer uma leitura seqüencial do que uma leitura aleatória - e se o fluxo em questão estiver em todos os seus discos, será muito mais uma carga de trabalho de leitura aleatória do que sequencial. >
Além disso, entendo que há metadados do ZFS envolvidos em arquivos em sistemas de arquivos ZFS (não em zvols); Não tenho números diretos, mas não ficaria surpreso por um único arquivo de 2,5 TB ter, em geral, significativamente menos blocos de metadados associados a ele do que 2,5 TB de 15 milhões de arquivos. Esses (potencialmente muitos) blocos de metadados extras adicionarão mais dados que devem ser lidos, aumentando a leitura do disco (e potencialmente buscando). Então, sim, é provável que indiretamente, um fluxo de envio consistindo de 15 milhões de arquivos seja mais lento do que um consistindo em um único arquivo do mesmo tamanho (especialmente se esse arquivo foi criado de uma só vez, como uma gravação sequencial, em uma piscina com muito espaço livre contíguo na época).
É muito comum que os fluxos de envio / recebimento do ZFS enviados sem buffer tenham um desempenho muito irregular - às vezes, eles parecem passar muito rapidamente e, em seguida, cairão para quase nada por períodos potencialmente longos. O comportamento foi descrito e até analisado até certo ponto em vários fóruns na internet, então não vou entrar nisso. A ideia geral é que, embora o ZFS possa e deva fazer algum trabalho para torná-lo um fluxo de trabalho mais eficiente internamente, uma "correção rápida" para muitos dos problemas é a introdução de um buffer no lado do envio e do recebimento. Para isso, a ferramenta mais comum é o 'mbuffer'.
Por canalizar seu zfs send através do mbuffer antes do netcat (e novamente através do mbuffer antes do zfs recv), você deve ver uma melhora acentuada se o problema subjacente for aquele que a adição de um buffer pode ajudar. Alasdair escreveu um artigo resumido sobre isso em seu blog - não tenho nada publicado sobre esse assunto no momento, então vou apontar para ele: link