web-dev-qa-db-fra.com

Améliorez l'utilisation initiale du temps de performance `find`

Je travaille sur un projet pour trouver tous les fichiers d'installation .tar sur mon système à l'aide de la commande:

time find / -type f \( -name "*.tar" -o -name "*.tar.*" \) 2>/dev/null | wc

La première fois que ça fonctionne, je reçois:

real    1m10.767s

La deuxième fois que je cours, je reçois:

real    0m9.847s

Je voudrais toujours obtenir la deuxième performance de <10 secondes et renoncer à la performance initiale de 1 minute 10 secondes . Quel est le meilleur moyen d'éviter la pénalité d'une minute la première fois que find est utilisé?


Remarques

  • Votre find initiale peut être plus rapide car j'ai une installation Ubuntu 16.04 plus deux installations Windows 10 pour un total de 2 millions de fichiers.
  • OTOH votre initiale find peut être plus lente car j'ai Ubuntu 16.04 et l’une des installations de Windows 10 sur un SSD Samsung Pro 960 NVMe évalué à 3 000 Mbps alors que les disques durs sont évalués à 140 Mbps et les bons disques SSD à 400 Mbps.
  • Si vous souhaitez répliquer des tests sans disposer de fichiers .tar sur votre système, remplacez tar par bashrc dans la section: -name "*.tar" -o -name "*.tar.*".

TL; DR

Supprimer RAM caches qui accélèrent find accès au disque

Vous pouvez répéter les premier/deuxième tests de performance en appelant ce petit script avant le premier find:

#!/bin/bash
if [[ $(id -u) -ne 0 ]] ; then echo "Please run as root" ; exit 1 ; fi
sync; echo 1 > /proc/sys/vm/drop_caches
sync; echo 2 > /proc/sys/vm/drop_caches
sync; echo 3 > /proc/sys/vm/drop_caches

GIF indiquant la quantité de RAM disque utilisée pour la mise en cache

La commande find exécutée sur / consomme environ 500 Mo de mémoire cache, comme indiqué par le .gif ci-dessous au moment de leur suppression:

drop_caches.gif

^^^ --- Notez que la ligne de mémoire située immédiatement au-dessous de la fenêtre du terminal affiche une chute de 4,74 GiB à 4,24 GiB. En réalité, il tombe à 4.11 GiB après que l’enregistreur d’écran peek enregistre le fichier et se ferme. Sur mon système, find la mise en cache utilise environ 5% de RAM.

2
WinEunuuchs2Unix

Projet difficile

Dans les sections suivantes sont des choses qui devraient fonctionner mais ne fonctionnent pas. En fin de compte, la seule façon de réussir ce travail était d'utiliser ce script bash:

#!/bin/bash
# NAME: find-cache
# DESC: cache find command search files to RAM
# NOTE: Written for: https://askubuntu.com/questions/1027186/improve-initial-use-of-find-performance-time?noredirect=1#comment1669639_1027186

for i in {1..10}; do
    echo "========================" >> /tmp/find-cache.log
    printf "find-cache.log # $i: "  >> /tmp/find-cache.log
    date                            >> /tmp/find-cache.log
    echo "Free RAM at start:"       >> /tmp/find-cache.log
    free -h | head -n2              >> /tmp/find-cache.log
    printf "Count of all files: "   >> /tmp/find-cache.log
    SECONDS=0                       # Environment variable
    time find /* 2>/dev/null|wc -l  >> /tmp/find-cache.log
    duration=$SECONDS               # Set elapsed seconds
    echo "$(($duration / 60)) minutes and $(($duration % 60)) seconds for find." \
                                    >> /tmp/find-cache.log
    echo "Free RAM after find:"     >> /tmp/find-cache.log
    free -h | head -n2              >> /tmp/find-cache.log
    echo "Sleeping 15 seconds..."   >> /tmp/find-cache.log
    sleep 15
done

Copiez le texte ci-dessus dans un fichier de script nommé: find-cache. Mettez le nom du script dans Applications de démarrage . Utilisez les instructions de la section suivante, mais remplacez le nom de commande /usr/bin/find... par /<path-to-script>/find-cache.

N'oubliez pas de marquer le script comme exécutable en utilisant:

chmod a+x /<path-to-script>/find-cache

<path-to-script> devrait être dans votre environnement $ PATH tel que /usr/local/bin ou de préférence /home/<your-user-name>/bin. Pour revérifier, utilisez echo $PATH pour afficher la variable d'environnement.

Chaque fois que je me connecte, je lance généralement conky et firefox. Vous faites probablement d'autres choses. Pour ajuster les paramètres de votre système, vérifiez le fichier journal:

$ cat /tmp/find-cache.log
========================
find-cache.log # 1: Sun Apr 22 09:48:40 MDT 2018
Free RAM at start:
              total        used        free      shared  buff/cache   available
Mem:           7.4G        431M        5.9G        628M        1.1G        6.1G
Count of all files: 1906881
0 minutes and 59 seconds for find.
Free RAM after find:
              total        used        free      shared  buff/cache   available
Mem:           7.4G        1.1G        3.0G        599M        3.3G        5.3G
Sleeping 15 seconds...
========================
find-cache.log # 2: Sun Apr 22 09:49:54 MDT 2018
Free RAM at start:
              total        used        free      shared  buff/cache   available
Mem:           7.4G        1.2G        2.9G        599M        3.3G        5.3G
Count of all files: 1903097
0 minutes and 9 seconds for find.
Free RAM after find:
              total        used        free      shared  buff/cache   available
Mem:           7.4G        1.1G        3.0G        599M        3.3G        5.3G
Sleeping 15 seconds...

    (... SNIP ...)

Remarque: entre la 1ère et la 2ème itération libre RAM perd 3 Go mais firefox restaure 12 onglets en même temps. .

Quelle que soit la raison pour laquelle find est exécuté une seule fois dans un travail de démarrage, ou un cron reboot bash. Au travail, le noyau Linux pense: "Ils ne veulent probablement pas garder le cache de page, je vais donc le vider pour économiser de la RAM" . Cependant, lorsque la commande find est exécutée 10 fois, le noyau Linux pense dans ce script: "Qui aime vraiment ce contenu dans le cache de la page, je ferais mieux de ne pas le vider" .

Au moins c'est ma meilleure supposition. Quelle que soit la raison, cette approche fonctionne comme testée à plusieurs reprises.


Ce qui devrait fonctionner mais ne fonctionne pas

Vous trouverez ci-dessous deux tentatives pour que ce projet fonctionne. Je les ai laissés ici pour que les autres ne perdent pas de temps à les répéter. Si vous pensez pouvoir les réparer par tous les moyens, peaufinez-les, postez une réponse et je voterai avec allégation.

Utiliser les applications de démarrage

Appuyez et relâchez le Windows / Super touche (elle a l’icône: Winkey1 ou Winkey2 ou Winkey3) pour afficher dash.

Dans le champ de recherche, tapez startup et vous verrez apparaître l'icône Applications de démarrage . Cliquez sur l'icône. Lorsque la fenêtre s'ouvre, cliquez sur Add à droite. Remplissez les nouveaux champs du programme de démarrage comme suit:

  • Entrez le nom sous Cache Find to RAM.
  • Remplissez la commande en tant que sleep 30 && find /* 2>/dev/null | wc.
  • Ajoutez un commentaire tel que "Exécution initiale de la commande Find pour mettre le disque en cache en mémoire cache".
  • Cliquez sur le bouton Add en bas.

Maintenant, redémarrez et vérifiez les performances de la commande find.

Crédits: Icônes de clé Windows copiées à partir du super utilisateur post .


Cron au redémarrage

Vous pouvez utiliser cron pour appeler la commande find au moment du démarrage afin de mettre en cache le disque lent dans une mémoire vive rapide. Exécutez la commande crontab -e et ajoutez la ligne suivante en bas:

@reboot /usr/sleep 30 && /usr/bin/find /* 2>/dev/null | wc -l
  • @reboot indique à cron d'exécuter cette commande à chaque démarrage/redémarrage.
  • /usr/sleep 30 a la commande find attendre 30 secondes avant de s'exécuter afin que le démarrage s'exécute aussi vite que possible. Augmentez-le à 45 ou 60 en fonction de votre vitesse de démarrage, du temps nécessaire pour vous connecter et de vos applications de démarrage.
  • /usr/bin/find /* 2>/dev/null | wc-l appelle la commande find en recherchant tous les fichiers (/*). Tous les messages d'erreur sont masqués par 2>/dev/null. Le nombre de fichiers est compté avec | wc -l. Sur mon système, il en coûte environ 2 millions, à cause d'une installation Ubuntu et de deux installations Windows 10.
  • Après avoir ajouté la ligne utiliser Ctrl+O suivi par Enter pour sauvegarder le fichier.
  • Après avoir sauvegardé le fichier, utilisez Ctrl+X pour quitter l'éditeur nano utilisé par cron. Si vous avez choisi un autre éditeur que nano, utilisez les commandes appropriées pour enregistrer et quitter.

Comme toujours, l'acronyme YMMV (votre kilométrage peut varier) s'applique.

Après le redémarrage, j'ai fait ces tests pour le prouver ne fonctionne pas :

rick@alien:~$ time find / -type f \( -name "*.tar" -o -name "*.tar.*" \) 2>/dev/null | wc
     26      26    1278

real    1m10.022s
user    0m7.246s
sys     0m12.840s
───────────────────────────────────────────────────────────────────────────────────────────
rick@alien:~$ time find / -type f \( -name "*.tar" -o -name "*.tar.*" \) 2>/dev/null | wc
     26      26    1278

real    0m8.954s
user    0m2.476s
sys     0m3.709s
2
WinEunuuchs2Unix