Назад | Перейти на главную страницу

Самый лучший способ архивировать большой файл без побочных эффектов во время его изменения

Я ищу приложение, которое генерирует большой объем данных в файле журнала (около 5 ГБ в день) на сервере Red Hat. Этот процесс длится 24 часа в течение недели, поэтому в течение дня нет смысла, когда файл не изменяется, хотя информация, добавляемая в него за полночь, не особенно важна, поэтому ничего страшного, если я проиграю, скажем, несколько секунд данных за этот период.

Чтобы ежедневно делать «безопасные» архивы файла журнала, я создал сценарий, который рано утром выполняет следующие действия:

Вот сам скрипт на случай, если с ним возникнут явные проблемы:

DF=$(date +"%Y%m%d_%H%M%S")
TARGET="fixdata-logs-$DF"
cp -r ./fixdata/logs $TARGET

#Truncate the original log file
find ./fixdata/logs -name '*.log' -exec sh -c 'cat /dev/null >| {}' \;

#Zip the log files
tar -zcvf $TARGET.tar.gz $TARGET

#Delete the labelled copy
rm -rf $TARGET

#Archive files older tha 3 days
find . -type f -mtime +3 -name \*.gz -exec mv {} $ARCHIVE_DIR \;

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

Проблема в том, что в этот период приложение часто сообщает об ошибках, связанных с системными ресурсами. Например, монитор пульса своей очереди часто не выдает регулярных пульсов. Ясно, что этот процесс copy-> tar.gz-> move оказывает достаточное влияние на серверный ввод-вывод, что влияет на поведение приложения.

Как я могу уменьшить влияние этого скрипта? Время до завершения не важно - если решение занимает больше времени, но не вызывает ошибок приложения, то это «предпочтительнее, чем что-то быстрое. Есть ли другие подходы, которые мне следует рассмотреть?

Для полноты картины я рассмотрел следующее, но сомневаюсь:

Вы можете сделать это с помощью значительно уменьшение нагрузки ввода-вывода за счет отказа от копирования + усечения. Вместо этого переименуйте файл, а затем, если процесс держит дескриптор файла журнала открытым, сделайте все необходимое, чтобы заставить его повторно использовать свои дескрипторы журнала (обычно отправляя HUP канонический способ сделать это). Если у программы еще нет такой возможности, исправьте ее, чтобы она была.

Сделав это, у вас не будет накладных расходов на ввод-вывод копии на том же носителе (что является одновременным чтением + записью), а затем усечения (которое может или не может быть значительной нагрузкой, в зависимости от вашей файловой системы) , и затем чтение в tar / compress и загрузка записи для создания архива.

После того, как вы переименовали файлы журнала, вы можете использовать tar / compress / что угодно на досуге. Чтобы еще больше снизить нагрузку на ввод-вывод, рассмотрите возможность выполнения стороны записи tar / compress непосредственно в архивное хранилище - хотя ваше архивное хранилище может не быть типичным устройством с произвольным доступом, оно все равно будет принимать прямой поток данные, которые сжимаются на лету (даже S3 может это сделать с помощью подходящего инструмента CLI).

Другая вещь, которую следует учитывать, ортогональная вышеупомянутому, - это использование ionice. Запустив программу как ionice -c 3 <command>, вы понижаете приоритет ввода-вывода процесса до "только бездействующий" - то есть, если есть что-нибудь иначе в системе, которая хочет выполнять ввод-вывод, ваша программа будет остановлена. Это отличная идея, но она может укусить вас сзади, если у вас тяжелая система ввода-вывода (ваша программа может занять ааааагес для завершения, потому что он редко получает время ввода-вывода). В случаях, когда вы уже выполняете слишком много ненужных операций ввода-вывода, установка приоритета «только для простоя» усугубит проблему.

Я также сильно подозреваю, что планирование только простоя не вполне делайте то, что написано на жестяной банке; Я наблюдал небольшое снижение производительности других (запланированных «с максимальной эффективностью») процессов, когда выполняются программы «только в режиме ожидания», по сравнению с тем, когда процесс «только в режиме ожидания» не выполняется. Я подозреваю, что это происходит из-за того, что, когда программа запрашивает ввод-вывод, в то время как "только бездействующий" процесс находится в середине выполнения операции ввода-вывода, есть задержка до тех пор, пока этот ввод-вывод не будет выполнен до "максимального усилия" process 'Операция ввода-вывода может начаться. Иными словами, это все равно намного лучше, чем если бы процесс «только простоя» работал с приоритетом «максимальные усилия», но это не то чудесное исправление - все, что может показаться на первый взгляд.

Взгляните на утилиту logrotate linux, которая доступна в rhel, она имеет сжатие, copytruncate и различные другие параметры, а также имеет дело с файлами журналов, которые используются приложениями, как и вы. Вы также можете попробовать использовать диск ssd и скопировать данные на тот, который должен быть самым быстрым, и хотя он по-прежнему будет использовать процессор, io на медленный диск будет исключен, если вы не используете usb.