Řešení 1:
Vytvořte bash skript takto:
#!/bin/bash
rm -- "$*"
sleep 0.5
Uložte jej pod názvem deleter.sh
například. Spusťte chmod u+x deleter.sh
aby byl spustitelný.
Tento skript odstraní všechny soubory, které mu byly předány jako argumenty, a poté přejde 0,5 sekundy do režimu spánku.
Poté můžete spustit
find cache.bak -print0 | xargs -0 -n 5 deleter.sh
Tento příkaz načte seznam všech souborů v cache.bak a předá pět názvů souborů najednou do mazacího skriptu.
Můžete tedy upravit, kolik souborů se odstraní najednou a jak dlouhá je prodleva mezi jednotlivými operacemi odstranění.
Řešení 2:
Měli byste zvážit uložení mezipaměti na samostatný souborový systém, který můžete připojit/odpojit, jak někdo uvedl v komentářích. Dokud to neuděláte, můžete používat tuto jednu vložku /usr/bin/find /path/to/files/ -type f -print0 -exec sleep 0.2 \; -exec echo \; -delete
za předpokladu, že se váš vyhledávací binární soubor nachází v /usr/bin a chcete vidět průběh na obrazovce. Upravte podle toho spánek, abyste svůj HDD příliš nezatěžovali.
Řešení 3:
Možná budete chtít zkusit ionice na skriptu spotřebovávajícím výstup příkazu find. Něco jako následující:
ionice -c3 $(
for file in find cache.bak -type f; do
rm $file
done
for dir in find cache.bak -depthe -type d -empty; do
rmdir $dir
done
)
V závislosti na souborovém systému může každé odstranění souboru vést k přepsání celého adresáře. U velkých adresářů to může být docela hit. Jsou vyžadovány další aktualizace tabulky inodů a možná i seznam volného místa.
Pokud má systém souborů žurnál, změny se zapisují do žurnálu; aplikovaný; a odstraněny z deníku. To zvyšuje požadavky na vstup/výstup pro činnost s intenzivním zápisem.
Možná budete chtít použít souborový systém bez žurnálu pro mezipaměť.
Místo ionice můžete použít příkaz spánku k omezení akcí. To bude fungovat, i když ionice ne, ale smazání všech souborů bude trvat dlouho.
Řešení 4:
Dostal jsem zde mnoho užitečných odpovědí/komentářů, které bych rád uzavřel a také ukázal své řešení.
-
Ano, nejlepší způsob prevence taková věc, která se děje, je ponechat adresář cache na samostatném souborovém systému. Nuking / rychlé formátování souborového systému vždy trvá nanejvýš několik sekund (možná minut), bez ohledu na to, kolik souborů / adresářů se v něm nacházelo.
-
ionice
/nice
řešení nic neudělalo, protože proces mazání ve skutečnosti nezpůsobil téměř žádné I/O. Domnívám se, že I/O způsobilo to, že se fronty/vyrovnávací paměti na úrovni jádra / souborového systému zaplnily, když byly soubory smazány příliš rychle procesem mazání. -
Způsob, jakým jsem to vyřešil, je podobný řešení Tero Kilkanena, ale nevyžadoval volání skriptu shellu. Použil jsem rsync vestavěný v
--bwlimit
přepněte pro omezení rychlosti mazání.
Úplný příkaz byl:
mkdir empty_dir
rsync -v -a --delete --bwlimit=1 empty_dir/ cache.bak/
Nyní bwlimit určuje šířku pásma v kilobajtech, což se v tomto případě vztahuje na název souboru nebo cestu k souborům. Nastavením na 1 kB/s se smazalo asi 100 000 souborů za hodinu, neboli 27 souborů za sekundu. Soubory měly relativní cesty jako cache.bak/e/c1/db98339573acc5c76bdac4a601f9ec1e
, který má 47 znaků, takže by to dalo 1000/47 ~=21 souborů za sekundu, takže něco podobného jako můj odhad 100 000 souborů za hodinu.
Nyní proč --bwlimit=1
? Zkoušel jsem různé hodnoty:
- 10000, 1000, 100 -> systém se zpomaluje jako předtím
- 10 -> systém nějakou dobu funguje docela dobře, ale jednou za minutu dochází k částečnému zpomalení. Doba odezvy HTTP stále <1 s.
- 1 -> žádné zpomalení systému. Nespěchám a tímto způsobem lze smazat 2 miliony souborů za <1 den, takže volím to.
Líbí se mi jednoduchost vestavěné metody rsync, ale toto řešení závisí na relativní délce cesty. Není to velký problém, protože většina lidí najde správnou hodnotu metodou pokusů a omylů.