Exclua mais de 10 milhões de arquivos do ZFS, efetivamente


30

Eu escrevi um programa de buggy que acidentalmente criou cerca de 30 milhões de arquivos em / tmp. (O bug foi introduzido há algumas semanas e estava criando alguns subdiretórios por segundo.) Eu poderia renomear / tmp para / tmp2 e agora preciso excluir os arquivos. O sistema é o FreeBSD 10, o sistema de arquivos raiz é o zfs.

Enquanto isso, uma das unidades no espelho deu errado e eu a substituí. A unidade possui dois discos SSD de 120 GB.

Aqui está a pergunta: substituir o disco rígido e alterar novamente a matriz inteira levou menos de uma hora. Excluir arquivos / tmp2 é outra história. Eu escrevi outro programa para remover os arquivos e ele pode excluir apenas 30-70 subdiretórios por segundo. Levará de 2 a 4 dias para excluir todos os arquivos.

Como é possível que a reestruturação de toda a matriz leve uma hora, mas a exclusão do disco leva 4 dias? Por que tenho um desempenho tão ruim? 70 deleções / segundo parece ter um desempenho muito, muito ruim.

Eu poderia excluir o inode para / tmp2 manualmente, mas isso não liberará espaço, certo?

Isso pode ser um problema com o zfs ou com os discos rígidos ou o quê?


11
Como não sou especialista em zfs, não posso falar sobre o ajuste de desempenho ou o que você pode fazer para melhorá-lo (isso também exigiria muitas informações e provavelmente seria melhor ser feito diretamente por um especialista). No entanto, posso dizer que a nova resolução acontece no nível do bloco, enquanto as exclusões ocorrem no nível do sistema de arquivos. O sistema de arquivos terá maior sobrecarga ao excluir um bilhão de buffers de inode como esse.
Spooler

Poste seu df -he zpool liste zfs list.
ewwhite

5
Escreveu outro programa: rm -rf /tmp2não vai fazer o trabalho?
Thorbjørn Ravn Andersen

2
Você não pode apenas reiniciar? /tmpdeve ser um tmpfssistema de arquivos e é armazenado na memória.
Blender

Respostas:


31

As exclusões no ZFS são caras. Ainda mais se você tiver a desduplicação ativada no sistema de arquivos (já que a desreferencia de arquivos deduplicados é cara). Instantâneos também podem complicar as coisas.

É melhor excluir o /tmpdiretório em vez dos dados contidos nele.

Se /tmpfor um sistema de arquivos ZFS, exclua-o e crie novamente.


11
@ nagylzs Nesse caso, sugiro torná-lo um sistema de arquivos ZFS separado. Em seguida, você pode mover o atual / tmp para fora do caminho, mover um novo / tmp para o lugar e excluir os arquivos conforme a necessidade do sistema. Resultado: tempo de inatividade mínimo mais uma leve degradação no desempenho (mitigável ionice, supondo que o FreeBSD o possua) enquanto a exclusão está em execução.
um CVn

9
Eu estava errado. Era um sistema de arquivos separado. Aqui está o que funcionou: reboot para o modo de usuário único, em seguida, fazer "zfs excluir zroot / tmp; zfs criar zroot / tmp; chmod 41777 / tmp"
nagylzs

6
Foram 5 minutos de inatividade total. Fantástico! :-)
nagylzs 5/09/16

11
Bem, isso também fala da preocupação que eu tinha, que excluir lutas nunca libera espaço por causa de instantâneos. Mas o tmp será configurado para não fazer instantâneos periódicos automáticos, certo ?
JDługosz 5/09

11
Na verdade, era o seguinte: zfs create -o compressão = on -o exec = on -o setuid = off zroot / tmp; chmod 1777 / zroot / tmp; zfs setpoint da montagem = / tmp zroot / tmp; Não sei ao certo como desativar os instantâneos automáticos. Existe "zfs set com.sun: auto-snapshot = false", mas isso funciona apenas com o Solaris, eu acho.
Nagylzs 6/09/16

27

Como é possível que a reestruturação de toda a matriz leve uma hora, mas a exclusão do disco leva 4 dias?

Considere um prédio de escritórios.

A remoção de todos os computadores, móveis e acessórios de todos os escritórios em todos os andares leva muito tempo, mas deixa os escritórios imediatamente utilizáveis ​​por outro cliente.

Demolir o prédio inteiro com RDX é um conjunto muito mais rápido, mas o próximo cliente é bastante provável para reclamar sobre como drafty o lugar é.


5
O ZFS não é um prédio de escritórios :) #
developerbmw

9
@developerbmw também não existe realmente um arquivo ou uma pasta, mas precisamos de conceitos metafóricos para entender o que está acontecendo.
JamesRyan

2
@JamesRyan Yep é realmente uma boa analogia ... Eu estava apenas sendo estúpido
developerbmw

5

Há várias coisas acontecendo aqui.

Primeiro, todas as tecnologias modernas de disco são otimizadas para transferências em massa. Se você precisar mover 100 MB de dados, eles o farão muito mais rápido se estiverem em um bloco contíguo em vez de espalhados por todo o lugar. Os SSDs ajudam muito aqui, mas mesmo eles preferem dados em blocos contíguos.

Segundo, a resilvering é bastante ideal no que diz respeito às operações de disco. Você lê uma grande quantidade de dados contíguos de um disco, realiza algumas operações rápidas da CPU e, em seguida, reescreve-as em outra grande parte contígua em outro disco. Se a energia falhar parcialmente, não é grande coisa - você simplesmente ignorará todos os dados com somas de verificação ruins e continuará normalmente.

Terceiro, a exclusão de um arquivo é realmente lenta . O ZFS é particularmente ruim, mas praticamente todos os sistemas de arquivos são lentos para excluir. Eles devem modificar um grande número de diferentes partes de dados no disco e cronometrar corretamente (ou seja, aguardar) para que o sistema de arquivos não seja danificado se houver falta de energia.

Como é possível que a reestruturação de toda a matriz leve uma hora, mas a exclusão do disco leva 4 dias?

A nova resolução é algo em que os discos são realmente rápidos e a exclusão é algo em que os discos são lentos. Por megabyte de disco, você só precisa fazer um pouco de resiliência. Você pode ter mil arquivos nesse espaço que precisam ser excluídos.

70 deleções / segundo parece um desempenho muito, muito ruim

Depende. Eu não ficaria surpreso com isso. Você não mencionou que tipo de SSD está usando. Os modernos SSDs da Intel e da Samsung são muito bons nesse tipo de operação (leitura-modificação-gravação) e terão melhor desempenho. SSDs mais baratos / mais antigos (por exemplo, Corsair) serão lentos. O número de operações de E / S por segundo (IOPS) é o fator determinante aqui.

O ZFS é particularmente lento para excluir coisas. Normalmente, ele executa exclusões em segundo plano para que você não veja o atraso. Se você está fazendo um grande número deles, não pode ocultar e deve atrasar você.


Apêndice: por que as exclusões são lentas?

  • A exclusão de um arquivo requer várias etapas. Os metadados do arquivo devem ser marcados como 'excluídos' e, eventualmente, devem ser recuperados para que o espaço possa ser reutilizado. O ZFS é um 'sistema de arquivos estruturado em log' que apresenta melhor desempenho se você criar apenas coisas e nunca excluí-las. A estrutura do log significa que, se você excluir algo, há uma lacuna no log e, portanto, outros dados deverão ser reorganizados (desfragmentados) para preencher a lacuna. Isso é invisível para o usuário, mas geralmente lento.
  • As alterações devem ser feitas de forma que, se a energia falhar parcialmente, o sistema de arquivos permanecerá consistente. Geralmente, isso significa esperar até que o disco confirme se os dados realmente estão na mídia; para um SSD, isso pode levar um longo tempo (centenas de milissegundos). O efeito líquido disso é que há muito mais contabilidade (ou seja, operações de E / S de disco).
  • Todas as mudanças são pequenas. Em vez de ler, escrever e apagar blocos de flash inteiros (ou cilindros para um disco magnético), você precisa modificar um pouco de um. Para fazer isso, o hardware deve ler um bloco ou cilindro inteiro, modificá-lo na memória e gravá-lo na mídia novamente. Isso leva muito tempo.

Não conheço o ZFS, mas alguns sistemas de arquivos permitem desvincular um diretório com o conteúdo, mas esses conteúdos são removidos posteriormente posteriormente durante a fase de coleta de lixo / desfragmentação / limpeza. O ZFS possui utilitários para fazer uma exclusão tão lenta, talvez? Na verdade, não acelerará a exclusão do OP, mas provavelmente o tornaria menos problemático se isso acontecer implicitamente durante a limpeza.
Vality 6/09/16

2

Como é possível que a reestruturação de toda a matriz leve uma hora, mas a exclusão do disco leva 4 dias?

Isso é possível porque as duas operações funcionam em diferentes camadas da pilha do sistema de arquivos. A resilvering pode ser executada em um nível baixo e, na verdade, não é necessário examinar arquivos individuais, copiando grandes pedaços de dados de cada vez.

Por que tenho um desempenho tão ruim? 70 deleções / segundo parece ter um desempenho muito, muito ruim.

Tem que fazer muita contabilidade ...

Eu poderia excluir o inode para / tmp2 manualmente, mas isso não liberará espaço, certo?

Eu não conheço o ZFS, mas se ele pudesse se recuperar automaticamente disso, provavelmente, no final, faria as mesmas operações que você já está fazendo, em segundo plano.

Isso pode ser um problema com o zfs ou com os discos rígidos ou o quê?

Diz zfs scrubalguma coisa?


2

Excluir muitos arquivos nunca é realmente uma operação rápida.

Para excluir um arquivo em qualquer sistema de arquivos, você precisa ler o índice do arquivo, remover (ou marcar como excluído) a entrada do arquivo no índice, remover quaisquer outros metadados associados ao arquivo e marcar o espaço alocado para o arquivo como não utilizado. Isso deve ser feito individualmente para que cada arquivo seja excluído, o que significa que excluir muitos arquivos requer muitas E / Ss pequenas. Fazer isso de uma maneira que garanta a integridade dos dados em caso de falta de energia aumenta ainda mais a sobrecarga.

Mesmo sem as peculiaridades introduzidas pelo ZFS, a exclusão de 30 milhões de arquivos normalmente significa mais de cem milhões de operações de E / S separadas. Isto vai levar um longo tempo, mesmo com um SSD rápido. Como outros já mencionaram, o design do ZFS agrava ainda mais esse problema.


2

Ian Howson dá uma boa resposta sobre por que é lento.

Se você excluir arquivos em paralelo, poderá ver um aumento na velocidade devido à exclusão, podendo usar os mesmos blocos e, assim, salvar a reescrita do mesmo bloco várias vezes.

Então tente:

find /tmp -print0 | parallel -j100 -0 -n100 rm

e veja se o desempenho é melhor do que as 70 exclusões por segundo.


0

Muito simples se você inverter o seu pensamento.

  1. Faça uma segunda unidade (você já parece ter isso)

  2. Copie tudo da unidade A para a unidade B com rsync, excluindo o diretório / tmp. Rsync será mais lento que uma cópia em bloco.

  3. Reinicialize, usando a unidade B como o novo volume de inicialização

  4. Reformate a unidade A.

Isso também desfragmentará sua unidade e fornecerá um diretório novo (tudo bem, desfragmentar não é tão importante com um SSD, mas linearizar seus arquivos nunca prejudica nada)


Antes de tudo, copie tudo, exceto / tmp? Então, incluindo / dev e / proc? Em segundo lugar, pareça um pouco arrogante para mim, especialmente em um servidor de produção.
Hennes

Suponho que ele seja inteligente o suficiente para excluir arquivos que não são arquivos, volumes montados e a pasta de memória virtual, a maioria dos quais não pode ser adivinhada aqui. Ou faça isso a partir de uma inicialização de manutenção, onde nada disso importa.
peter

Eu acho que você também pode zfs send/recv(copiar em nível de bloco) todos os outros sistemas de arquivos, exceto o sistema de arquivos raiz (onde / tmp está localizado neste caso) e copiar os dados restantes no sistema de arquivos raiz manualmente (excluindo / tmp, é claro).
User121391

2
Isso perderá os instantâneos e ignorará alguns dos recursos de confiabilidade. Perde o objetivo de usar zfs.
JDługosz 5/09

2
@ JDługosz pontos válidos, mas relevantes apenas se o usuário se importa. Mais ou menos como "meus backups estão corrompidos, como reparar?" -> "Você precisa de arquivos de backup?" -> "Não" -> "Reformatar".
peter

-1

Você tem 30 milhões de entradas em uma lista não classificada. Você digitaliza a lista para a entrada que deseja remover e a remove. Agora você tem apenas 29.999.999 entradas na sua lista não classificada. Se todos estiverem em / tmp, por que não apenas reiniciar?


Editado para refletir as informações nos comentários: Declaração de problema: A remoção da maioria, mas não de todos , dos mais de 30 milhões de arquivos criados incorretamente em / tmp está demorando muito.
Problema 1) A melhor maneira de remover um grande número de arquivos indesejados de / tmp.
Problema 2) Compreendendo por que é tão lento excluir arquivos.

Solução 1) - / tmp é redefinido para esvaziar na inicialização pela maioria das distribuições * nix. O FreeBSD, no entanto, não é um deles.
Etapa 1 - copie arquivos interessantes em outro lugar.
Etapa 2 - Como root

 $ grep -i tmp /etc/rc.conf  
 clear_tmp_enable="YES" # Clear /tmp at startup.  

Etapa 3 - reinicie.
Etapa 4 - altere clear_tmp_enable de volta para "Não".
Os arquivos indesejados agora desaparecem, pois o ZFS no FreeBSD possui o recurso "A destruição de um conjunto de dados é muito mais rápida do que excluir todos os arquivos que residem no conjunto de dados, pois não envolve a varredura de todos os arquivos e a atualização de todos os metadados correspondentes. " portanto, tudo o que precisa ser feito no momento da inicialização é redefinir os metadados do conjunto de dados / tmp. Isto é muito rápido.

Solução 2) Por que é tão lento? O ZFS é um maravilhoso sistema de arquivos que inclui recursos como acesso constante ao diretório de tempo. Isso funciona bem se você souber o que está fazendo, mas as evidências sugerem que o OP não é um especialista em ZFS. O OP não indicou como eles estavam tentando remover os arquivos, mas, suponho, eu diria que eles usaram uma variação em "find regex -exec rm {} \;". Isso funciona bem com números pequenos, mas não é escalável porque há três operações seriais em andamento 1) obtenha a lista de arquivos disponíveis (retorna 30 milhões de arquivos em ordem de hash), 2) use regex para selecionar o próximo arquivo a ser excluído, 3 ) diga ao sistema operacional para localizar e remover esse arquivo de uma lista de 30 milhões. Mesmo se o ZFS retornar uma lista da memória e se 'find' o armazena em cache, o regex ainda precisa identificar o próximo arquivo a ser processado da lista e depois solicitar ao sistema operacional que atualize seus metadados para refletir essa alteração e, em seguida, atualize a lista para que não seja processado novamente.


11
Eu acho que você não entendeu a pergunta. Eu precisava remover a maioria dos arquivos. Ou seja, mais de 30 milhões de arquivos.
Nagylzs 6/09/16

@nagylzs / tmp é limpo na reinicialização. Se você deseja excluir a maioria , apenas deseja manter alguns , ou seja, menos da metade, copie os que deseja manter e, em seguida, reinicie para se livrar do resto. O motivo de suas exclusões serem tão lentas é que o fato de ter um grande número de arquivos em um diretório resulta em uma grande lista não classificada que precisa ser processada para localizar o arquivo a ser operado, o que leva tempo. O único problema aqui é o PEBCAK.
Paul Smith

Os diretórios Zfs não são classificados ? Eu pensei que o zfs lidava especificamente com diretórios grandes também.
JDługosz 6/09/16

Bem, / tmp não é limpo, apenas arquivos relacionados ao X. Pelo menos no FreeBSD. Ele não pode ser limpo de qualquer maneira na inicialização, porque levaria dias para o script rc excluir normalmente.
Nagylzs 6/09/16

@JDlugosz - O ZFS é muito melhor do que a maioria, mas as listas de inodes (que são todos os diretórios) não são classificadas.
Paul Smith
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.