2

Я использую zip для регулярного резервного копирования локального каталога на удаленную машину. Они не верят в такие вещи, как rsync, поэтому это лучшее, что я могу сделать (?). Вот сценарий, который я использую

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

Все это прекрасно работает, за исключением того, что zip никогда не использует много ЦП, поэтому, похоже, это занимает больше времени, чем следовало бы. Кажется, он никогда не поднимается выше 5%. Я пытался сделать это хорошо -20, но это не имело никакого значения. Это просто скорость сети или диска, затрудняющая процесс, или я делаю что-то не так?

3 ответа3

7

Вы, вероятно, обнаружите, что zip тратит большую часть своего времени на ожидание ввода / вывода (чтение файлов и запись сжатых версий), поэтому он не использует столько ресурсов процессора, сколько вы ожидаете. Придание процессу дополнительного приоритета через nice не влияет на это, так как задача не может использовать больше процессорного времени, если ей не передаются данные со скоростью, которая потребовала бы этого.

Под Linux вы можете видеть эту ситуацию как высокий% времени как время ожидания ввода-вывода в выводе от top и аналогичных утилит, то же самое может быть верно для OSX.

Причины времени ожидания ввода-вывода могут включать:

  1. обработка множества маленьких файлов (много движений головы, чтение файлов и связанных структур каталогов)
  2. фрагментация файла
  3. конкурировать с другими действиями на соответствующих дисках (пользователи, копирующие / перемещающие / получающие доступ к файлам, запланированные AV-сканирования, ...), пока выполняется резервное копирование
  4. чтение файлов по сети (современный ЦП может архивировать данные гораздо быстрее, чем когда-либо может передать их канал со скоростью 100 Мбит / с, а задержка в сети усугубит эффект многих маленьких файлов) или передача сжатых данных по сети (если только ваши данные сжимаются необычно, применяется то же условие «zip быстрее, чем ваша сеть на современных процессорах», так как оно будет считывать данные с локальных дисков и обрабатывать данные быстрее, чем может затем отправить результат по сети)
  5. конкуренция в сети (если сервер, с которым вы разговариваете, имеет 100-мегабитную ссылку, а другие используют его, это может быть проблемой, в меньшей степени, если у него, конечно, более быстрая ссылка)
  6. медленные диски или медленные интерфейсы (если какой-либо из этих дисков подключен через USB2, он будет иметь тенденцию передавать не более 25 Мбайт / с, иногда медленнее, в зависимости от используемого USB-адаптера и конкуренции с шиной USB с другими быстрыми устройствами, где современный внутренний диск будет вдвое больше, если не больше для массовых переводов)

Если вы хотите использовать "резервные" циклы ЦП и не можете сделать это за счет сокращения задержек ввода-вывода, вы можете вместо этого попробовать использовать 7zip - это использует гораздо больше процессорного времени на блок данных, но обеспечивает лучшее сжатие, чем zip by Во многих случаях это тоже достаточно для уменьшения размера ваших резервных копий. Будет ли это быстрее (потому что 7zip приводит к отправке меньшего количества данных по сети) или медленнее (потому что дополнительная вычислительная сложность означает, что ваш ЦП может стать узким местом, а не дисками / файловыми системами / сетью), зависит от точной спецификации вашей машины.

Редактировать:

Еще одна вещь, некоторые инструменты сообщают, что процесс использует каждое ядро, а некоторые - процессор (а некоторые в любом случае в зависимости от настроек), а zip обычно является многопоточным процессом. Так что если у вас четырехъядерный процессор, то 5%, скорее всего, будут "5% от ЦП", или примерно 20% от одного ядра (хотя он может быть отскакивающим между ядрами, если он однопоточный, он не будет работать на более чем один в любой момент).

1

Вот мой сценарий в том виде, в каком он есть, если кому-то интересно. Очевидно, что здесь есть несколько жестко заданных путей, поэтому вы не можете просто запустить их в том виде, в каком они есть. Он ведет журнал своих операций и использует рычание, чтобы уведомлять вас о любых ошибках. Если у вас нет рычания / вы не хотите его устанавливать, просто закомментируйте / удалите все строки с пометкой growlnotify.

Одним из других изменений, которые я сделал, было копирование удаленного zip-архива на локальный диск перед добавлением файлов. Происходило то, что zip копировал архив в локальный временный файл, вносил изменения и затем перемещал временный файл обратно на удаленный диск для каждого файла / папки в каталоге верхнего уровня. Так что теперь он только один раз поднимает тяжелую сеть. Я вроде думаю, что я должен смотреть на смолу для такого рода вещей ..

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;
1

«nice -n 10» делает данную программу еще более "хорошей", используя более низкий приоритет. Возможно, вы имели в виду «nice -n -10» или «nice --10», что делает программу менее "приятной" и, таким образом, использует больше ресурсов процессора.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .