Gostaria de excluir um diretório de cache nginx, que limpei rapidamente:
mv cache cache.bak
mkdir cache
service nginx restart
Agora eu tenho uma cache.bak
pasta com 2 milhões de arquivos. Eu gostaria de excluí-lo, sem perturbar o servidor.
Um simples rm -rf cache.bak
destrói o servidor, mesmo a resposta HTTP mais simples leva 16 segundos enquanto o rm está em execução, então não posso fazer isso.
Eu tentei ionice -c3 rm -rf cache.bak
, mas não ajudou. O servidor possui um HDD, não um SSD, provavelmente em um SSD isso pode não ser um problema.
Acredito que a melhor solução seria algum tipo de limitação, como o gerenciador de cache integrado do nginx.
Como você resolveria isso? Existe alguma ferramenta que pode fazer exatamente isso?
ext4 no Ubuntu 16.04
Faça um script bash como este:
Salve-o com o nome,
deleter.sh
por exemplo. Executechmod u+x deleter.sh
para torná-lo executável.Este script exclui todos os arquivos passados para ele como argumentos e, em seguida, dorme 0,5 segundo.
Então, você pode correr
Esse comando recupera uma lista de todos os arquivos em cache.bak e passa os cinco nomes de arquivo por vez para o script de exclusão.
Assim, você pode ajustar quantos arquivos são excluídos por vez e quanto tempo demora entre cada operação de exclusão.
Você deve considerar salvar seu cache em um sistema de arquivos separado que possa montar/desmontar como alguém afirmou nos comentários. Até que o faça, você pode usar este forro
/usr/bin/find /path/to/files/ -type f -print0 -exec sleep 0.2 \; -exec echo \; -delete
assumindo que seu binário de busca está localizado em /usr/bin e você deseja ver o progresso na tela. Ajuste o sono de acordo, para não sobrecarregar seu HDD.Você pode tentar o ionice em um script que consome a saída de um comando find. Algo como o seguinte:
Dependendo do sistema de arquivos, cada exclusão de arquivo pode resultar na reescrita de todo o diretório. Para diretórios grandes, isso pode ser um grande sucesso. Existem atualizações adicionais necessárias para a tabela de inodes e, possivelmente, uma lista de espaço livre.
Se o sistema de arquivos tiver um diário, as alterações serão gravadas no diário; aplicado; e removido da revista. Isso aumenta os requisitos de E/S para atividades intensivas de gravação.
Você pode querer usar um sistema de arquivos sem um diário para o cache.
Em vez de ionice, você pode usar um comando sleep para limitar a taxa das ações. Isso funcionará mesmo que o ionice não funcione, mas levará muito tempo para excluir todos os seus arquivos.
Recebi muitas respostas / comentários úteis aqui, que gostaria de concluir e também mostrar minha solução.
Sim, a melhor maneira de evitar que isso aconteça é manter o diretório do cache em um sistema de arquivos separado. Nuking / formatação rápida de um sistema de arquivos sempre leva alguns segundos (talvez minutos) no máximo, não relacionado a quantos arquivos / diretórios estavam presentes nele.
As soluções
ionice
/nice
não fizeram nada, porque o processo de exclusão quase não causou E/S. O que causou a E/S foi que eu acredito que filas/buffers no nível do kernel/sistema de arquivos foram preenchidos quando os arquivos foram excluídos muito rapidamente pelo processo de exclusão.A maneira como resolvi é semelhante à solução de Tero Kilkanen, mas não exigia a chamada de um script de shell. Usei o
--bwlimit
switch interno do rsync para limitar a velocidade de exclusão.O comando completo foi:
Agora bwlimit especifica a largura de banda em kilobyes, que neste caso se aplica ao nome do arquivo ou caminho dos arquivos. Ao configurá-lo para 1 KBps, ele estava excluindo cerca de 100.000 arquivos por hora ou 27 arquivos por segundo. Os arquivos tinham caminhos relativos como
cache.bak/e/c1/db98339573acc5c76bdac4a601f9ec1e
, que tem 47 caracteres, então daria 1000/47 ~= 21 arquivos por segundo, algo semelhante ao meu palpite de 100.000 arquivos por hora.Agora porque
--bwlimit=1
? Eu tentei vários valores:Gosto da simplicidade do método integrado do rsync, mas essa solução depende do comprimento do caminho relativo. Não é um grande problema, pois a maioria das pessoas encontraria o valor certo por tentativa e erro.