Comment rendre `rm` plus rapide sur ext3 / linux?

32

J'ai le système de fichiers ext3 monté avec les options par défaut. Sur cela, j'ai des fichiers de ~ 100Go.

La suppression de l'un de ces fichiers prend du temps (8 minutes) et génère beaucoup de trafic io, ce qui augmente la charge du serveur.

Existe-t-il un moyen de rendre la société moins perturbante?


la source
4
En gros, aucune méthode d’ici n’a fonctionné, nous avons donc développé la nôtre. Le décrit ici: depesz.com/index.php/2010/04/04/how-to-remove-backups

Réponses:

14

La réponse la plus intéressante était à l’origine enterrée dans un commentaire sur la question. Voici une réponse de première classe pour la rendre plus visible:

En gros, aucune méthode d’ici n’a fonctionné, nous avons donc développé la nôtre. Le décrit ici: http://www.depesz.com/index.php/2010/04/04/how-to-remove-backups/ - depesz 6 avr. 10 à 15:15

Ce lien est une analyse incroyablement approfondie de l’exploration et de la découverte d’une solution viable.

Notez aussi:

L'article dit:

Comme vous pouvez le constater, j’ai utilisé les -c2 -n7options de ionice, qui semblent saines.

ce qui est vrai, mais l'utilisateur TafT indique que si vous ne voulez aucune perturbation, alors -c3«inactif» serait un meilleur choix que -c2«meilleur effort». Il a l'habitude -c3de construire en arrière-plan et a trouvé que cela fonctionnait bien sans provoquer l'attente de la construction pour toujours. Si vous utilisez réellement 100% io, -c3la suppression ne sera jamais terminée, mais il ne s'attend pas à ce que ce soit ce que vous avez basé sur le test effectué.

Matt McClure
la source
18

Mettez à niveau vers ext4 ou un autre système de fichiers moderne utilisant des extensions. Puisque ext3 utilise le schéma de blocs indirects plutôt que les extensions, la suppression de gros fichiers nécessite inévitablement beaucoup de travail.

Janneb
la source
6

Vous pouvez essayer Ionice . Cela ne le fera pas plus vite, mais cela pourrait le rendre moins perturbant.

En pause jusqu'à nouvel ordre.
la source
4

En termes d’efficacité, l’utilisation d’un fichier par fichier n’est pas optimale, car elle nécessite un fork et un exec pour chaque fichier.

En supposant que vous ayez un fichier list.txt contenant les fichiers que vous voulez supprimer, cela serait plus efficace, mais ça va quand même être lent:

xargs -i rm {} < list.txt

Une autre approche consisterait à: nice -20 xargs -i rm {} < list.txt
(cela prendra moins de temps mais affectera grandement votre système :)

ou

Je ne sais pas à quelle vitesse cela serait, mais:

mv <file-name> /dev/null 

ou

Créez un point de montage spécial avec un système de fichiers rapide (en utilisant un périphérique de boucle?), Utilisez-le pour stocker et supprimer vos fichiers énormes.
(Peut-être déplacer les fichiers là-bas avant de les supprimer, c'est peut-être plus rapide ou peut-être simplement le démonter quand vous voulez que les fichiers disparaissent)

ou

cat /dev/null > /file/to/be/deleted (donc il est de taille zéro maintenant) et si vous voulez le faire disparaître juste rm -rf <file> maintenant

ou même mieux

laisse tomber le chat et fais juste # > /file/to/be/emptied


la source
Eh bien, je supprime 1 fichier, donc il n'y a pas de surcharge.
1

J'ai eu du mal à supprimer le répertoire à un rythme raisonnable, il s'avère que le processus consistait à verrouiller le disque et à créer une pile de processus essayant d'accéder au disque. ionice ne fonctionnait pas, il continuait simplement à utiliser 99% de l'E / S du disque et bloquait tous les autres processus.

Voici le code Python qui a fonctionné pour moi. Il supprime 500 fichiers à la fois, puis prend une pause de 2 secondes pour laisser les autres processus faire leur travail, puis continue. Fonctionne très bien.

import os, os.path
import time

for root, dirs, files in os.walk('/dir/to/delete/files'):
    file_num = 0
    for f in files:
        fullpath = os.path.join(root, f)
        os.remove(fullpath)
        if file_num%500 == 1:
            time.sleep(2)
            print "Deleted %i files" % file_num
        file_num = file_num + 1
Nick Woodhams
la source
1
Essayez-le sur les fichiers 100G + du système de fichiers ext3. Le problème est dans la taille du fichier unique, pas le nombre de fichiers.
Dans votre cas, il semble que cela ne fonctionnerait pas. Mais j'ai eu une tonne de petits fichiers. Merci pour les commentaires.
Nick Woodhams
1

Mes deux centimes.

J'ai déjà eu ce problème. "Dans les scripts séquentiels qui doivent être exécutés rapidement, le processus supprime beaucoup de fichiers" .. Ainsi, le "rm" rendra la vitesse de ce script proche du temps IO wait / exec.

Donc, pour accélérer les choses, j’ai ajouté un autre processus (script bash) lancé par cron .. comme un ramasse-miettes, il supprime tous les fichiers d’un répertoire particulier.

Ensuite, j'ai mis à jour le script d'origine en remplaçant le "rm" par un mv par un "garbage folder" (renommez le fichier en ajoutant un compteur à la fin de son nom pour éviter les collisions).

Cela fonctionne pour moi, le script s'exécute au moins 3 fois plus vite. mais cela ne fonctionne bien que si le dossier de mémoire et le fichier d'origine se trouvent sous le même point de montage (même périphérique) afin d'éviter la copie de fichier. (mv sur le même appareil consomme moins d’IO que de rm)

J'espère que ça aide ..

Emmanuel Devaux
la source
0

Notez également que la réponse de Dennis Williamson, qui suggère ionice comme solution de contournement du chargement, ne fonctionnera que si votre périphérique de blocage utilise le planificateur CFQ io.

la famzah
la source
0

Vous pouvez essayer de créer un système de fichiers en boucle sur lequel stocker vos sauvegardes.

# dd if=/dev/zero of=/path/to/virtualfs bs=100M count=1024 # 100 MB * 1024 = 100 GB
# mke2fs /path/to/virtualfs
# mount -t ext2 /path/to/virtualfs /mnt/backups -o loop

Ensuite, lorsque vous souhaitez effacer les sauvegardes:

# umount /mnt/backups
# mke2fs /path/to/virtualfs
# mount -t ext2 /path/to/virtualfs /mnt/backups -o loop

Presto! L'ensemble du système de fichiers virtuel est effacé en quelques instants.

amphétamachine
la source
ne résout pas le problème, car cela ne fonctionnerait que si je voulais supprimer toutes les sauvegardes sur un système de fichiers donné.
0

Vous pouvez utiliser le multitheading avec xargs

find . -type f | xargs -P 30 rm -rf 

où 30 est le nombre de threads que vous souhaitez créer. Si vous utilisez zéro, le système crée le nombre maximal de threads disponibles pour l'utilisateur qui exécute la tâche.

Juan Carlos
la source
1
finda une -deleteoption qui est une bien meilleure alternative.
Ariel
0

mv <nom de fichier> / dev / null

/ dev / null est un fichier et non un répertoire. Vous ne pouvez pas déplacer un fichier, dans un fichier, ou vous risquez de l'écraser.

Créez un point de montage spécial avec un système de fichiers rapide (en utilisant un périphérique de boucle?), Utilisez-le pour stocker et supprimer vos fichiers énormes. (Peut-être déplacer les fichiers là-bas avant de les supprimer, c'est peut-être plus rapide ou peut-être simplement le démonter quand vous voulez que les fichiers disparaissent)

Je ne pense pas que ce soit pratique. Il utiliserait inutilement plus d'E / S que ne l'aurait souhaité le PO.

Felipe Alvarez
la source
-1

/ dev / null est un fichier et non un répertoire. Vous ne pouvez pas déplacer un fichier, dans un fichier, ou vous risquez de l'écraser.

En fait , il est un appareil et toutes les données écrites il obtient donc mis au rebut mv <file> /dev/nullest logique

Depuis Wikipedia, l'encyclopédie libre
Dans les systèmes d'exploitation de type Unix, / dev / null ou le périphérique null est un fichier spécial qui supprime toutes les données qui y sont écrites (mais signale que l'opération d'écriture a réussi) et ne fournit aucune donnée à un processus lit à partir de celui-ci (donnant immédiatement EOF). [1]


la source
1
C'est faux et INCROYABLEMENT dangereux. / dev / null est un périphérique, qui est un objet spécial de type fichier. Si vous êtes root, "mv / some / file / dev / null" SUPPRIMERA le périphérique spécial / dev / null et y déplacera votre fichier! Ainsi, la prochaine fois que quelqu'un essaiera d'utiliser / dev / null, il utilisera un fichier réel au lieu du périphérique, ce qui provoquera un désastre. (Lorsque Wikipédia dit "élimine toutes les données écrites", cela signifie que "cat / some / file> / dev / null" lira / some / file et supprimera les données que vous avez lues, mais cela n'affectera pas la fichier d'origine).
user9876