2 votes

zip trop gentil (Mac OS X)

J'utilise zip pour faire une sauvegarde régulière d'un répertoire local sur une machine distante. Ils ne croient pas aux choses comme rsync ici, donc c'est le mieux que je puisse faire ( ?). Voici le script que j'utilise

echo $(date)>>~/backuplog.txt;
if [[ -e /Volumes/backup/ ]];
then 
    cd /Volumes/Non-RAID_Storage/;
    for file in projects/*; 
        do nice -n 10 zip -vru9 /Volumes/backup/nonRaidStorage.backup.zip "$file" 2>&1 | grep -v "zip info: local extra (21 bytes)">>~/backuplog.txt;
    done;
else 
    echo "backup volume not mounted">>~/backuplog.txt;
fi

Tout cela fonctionne bien, sauf que zip n'utilise jamais beaucoup de CPU et semble donc prendre plus de temps qu'il ne devrait. Il ne semble jamais dépasser 5%. J'ai essayé de le rendre agréable -20 mais cela n'a fait aucune différence. Est-ce la vitesse du réseau ou du disque qui gêne le processus ou est-ce que je fais quelque chose de mal ?

7voto

David Spillett Points 23094

Vous constaterez probablement que zip passe la plupart de son temps à attendre les E/S (lecture des fichiers et écriture des versions compressées), c'est pourquoi il n'utilise pas autant de CPU que prévu. En donnant au processus une priorité supplémentaire via nice n'a aucun effet sur ce point car la tâche ne peut pas utiliser plus de temps CPU si elle n'est pas alimentée en données à un rythme qui l'exigerait.

Sous Linux, vous pouvez voir cette situation comme un pourcentage élevé de temps d'attente d'E/S dans la sortie de top et des utilitaires similaires, il peut en être de même pour OSX.

Les raisons du temps d'attente de l'OI peuvent être les suivantes :

  1. le traitement de nombreux petits fichiers (beaucoup de mouvements de tête pour lire les fichiers et les structures de répertoire correspondantes)
  2. fragmentation des fichiers
  3. entrer en concurrence avec d'autres activités sur les lecteurs concernés (utilisateurs copiant/déplaçant/accédant à des fichiers, analyses AV programmées, ...) pendant que la sauvegarde a lieu.
  4. lire les fichiers sur un réseau (un CPU moderne peut compresser des données bien plus rapidement qu'une liaison à 100Mbit/s ne peut le faire, et la latence du réseau exacerbera l'effet des nombreux petits fichiers) ou pousser les données compressées sur le réseau (à moins que vos données ne soient exceptionnellement compressibles, la même condition "zip est plus rapide que votre réseau sur les CPU modernes" s'applique car il lira à partir de vos disques locaux et traitera le fichier plus rapidement qu'il ne peut ensuite envoyer le résultat sur le réseau)
  5. la contention du réseau (si le serveur auquel vous parlez a une liaison de 100Mbit et que d'autres l'utilisent, cela peut être un problème, moins si la liaison est plus rapide bien sûr)
  6. des disques lents ou des interfaces lentes (si l'un des disques concernés est connecté en USB2, il aura tendance à ne pas transférer plus de 25Mbyte/sec, parfois plus lentement en fonction de l'adaptateur USB utilisé et de la contention du bus USB avec d'autres périphériques rapides, alors qu'un disque interne moderne poussera le double, si ce n'est plus, pour les transferts en masse).

Si vous voulez utiliser les cycles CPU "libres" et que vous ne pouvez pas le faire en réduisant les délais d'E/S, vous pouvez essayer d'utiliser 7zip à la place - il utilise beaucoup plus de temps CPU par bloc de données mais réalise une meilleure compression que zip dans de nombreux cas, réduisant ainsi la taille de vos sauvegardes. Que ce soit plus rapide (parce que 7zip envoie moins de données sur le réseau) ou plus lent (parce que la complexité de calcul supplémentaire signifie que votre CPU peut devenir le goulot d'étranglement et non les disques/systèmes de fichiers/réseau) dépend des spécifications exactes de votre machine.

Editar:

Une autre chose, certains outils rapportent l'utilisation des processus par cœur et d'autres par CPU (et certains dans les deux cas selon les paramètres), et zip est généralement un processus threadé. Donc, si vous avez un processeur à quatre cœurs, il n'est pas improbable que ces 5% soient "5% du processeur", ou environ 20% d'un cœur (bien qu'il puisse rebondir entre les cœurs, s'il est à un seul fil, il ne fonctionnera pas sur plus d'un à un moment donné).

1voto

Frode Lillerud Points 1655

"nice -n 10" rend le programme en question encore plus "sympa" en utilisant une priorité inférieure. Peut-être vouliez-vous dire "nice -n -10" ou "nice --10" qui rend le programme moins "gentil" et utilise donc plus de CPU.

1voto

stib Points 3975

Voici mon script tel qu'il est, si cela intéresse quelqu'un. Évidemment, il y a quelques chemins codés en dur ici, donc vous ne pouvez pas simplement l'exécuter tel quel. Il garde un journal de ses opérations et utilise grognement pour vous signaler toute erreur. Si vous n'avez pas growl / ne voulez pas l'installer, commentez / supprimez simplement les lignes contenant growlnotify.

L'une des autres modifications que j'ai apportées a été de copier l'archive zip distante sur un lecteur local avant d'ajouter les fichiers. Ce qui se passait, c'est que zip copiait l'archive dans le fichier temporaire local, effectuait les modifications et replaçait ensuite le fichier temporaire sur le lecteur distant, pour chaque fichier/dossier du répertoire de premier niveau. Maintenant, il ne fait qu'une seule fois le travail réseau lourd. Je me dis que je devrais plutôt regarder du côté de tar pour ce genre de choses

localBaseDirectory=/Volumes/Non-RAID_Storage/;
backedUpDirectory=projects;
backupVolume=/Volumes/video-prod/Backup;
backupFile=$backupVolume/Non-RAID_Storage_backup.zip;
zipTempfile=/Volumes/B_media
localBackupTempFile=/Volumes/A_Media/backuptemp.zip;
log=~/backuplog.txt;
temp=/var/tmp/backupError.txt;
##############################################
/usr/local/bin/growlnotify -m "backing up $backedUpDirectory on $localBaseDirectory" 2>&1 >/Dev/Null  #need this redirect because growl chucks errors when run by cron;

echo $(date) > $log
if [[ -e $backupVolume ]];
then 
   if [[ -e $backupFile ]];
        then cp $backupFile $localBackupTempFile;
        mv $backupFile "$backupFile-old";
        echo "copied old backup to $backupFile-old">>$log;
    fi;
    cd $localBaseDirectory 2>$temp;
    if [[ -s $temp ]];
        #notify if there was an error cding to this directory. -s is true if the file exists and is not zero sized
        then cat $temp | /usr/local/bin/growlnotify -s;
        cat $temp >> $log;
    fi;
    for file in $backedUpDirectory/*;
    do
        /usr/local/bin/growlnotify -m "backing up $file" 2>&1 >/Dev/Null;
        #zip using verbose, recursive, update (ie don't overwrite files unless they're older), highest level compression
        #zip creates a lot of garbage errors when being verbose eo send errors to a temp file, and stdout to the log file
         nice -n 10 zip -vru9 -b $zipTempfile $localBackupTempFile "$file" 2>$temp |grep "adding:">>$log;
         #add just the important errors to the log
         cat $temp 2>/dev/null|grep "error:">>$log;
    done;
    echo "done adding to local zip file - moving to $backupFile">>$log;
    #move the local version to the remote backup file
    mv $localBackupTempFile $backupFile 2>>$log;
    echo "$(date) - backed up Non-RAID_storage">>$log
    /usr/local/bin/growlnotify -m "backed up $backedUpDirectory on $localBaseDirectory" 2>&1 >/Dev/Null;
else 
    /usr/local/bin/growlnotify -s -m "Backup volume not mounted" 2>&1 >/Dev/Null;
    echo "backup volume not mounted" >> $log;
fi;

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X