Как обрабатывать новые файлы для обработки в работе cron - PullRequest
3 голосов
/ 07 января 2010

Как я могу проверить файлы, которые я уже обработал в скрипте, чтобы я не обработал их снова? и / или Что не так с тем, как я это делаю сейчас?

Здравствуйте, Я использую tshark с опцией кольцевого буфера для выгрузки в файлы через 5 МБ или 1 час. Я написал скрипт Python для чтения этих файлов в формате XML и выгрузки в базу данных, это прекрасно работает.

Моя проблема в том, что это действительно интенсивный процесс, один из этих 5 МБ может превратиться в файл размером 200 МБ при преобразовании в XML, поэтому я не хочу выполнять какую-либо ненужную обработку.

Скрипт запускается каждые 10 минут и обрабатывает ~ 5 файлов за цикл, так как при сканировании папки, в которой создаются файлы, для любых новых записей, я сбрасываю хэш файла в базу данных и при следующем запуске проверяю хэш, и если его нет в базе данных, я сканирую файл. Проблема в том, что это не работает каждый раз, в конечном итоге он обрабатывает файлы, которые он уже сделал . Когда я проверяю хеш файла, который он пытается обработать, он не отображается нигде в базе данных, поэтому и пытаюсь обрабатывать его снова и снова.

Я печатаю имя файла + хэш в выводе скрипта:

using file /var/ss01/SS01_00086_20100107100828.cap with hash: 982d664b574b84d6a8a5093889454e59
using file /var/ss02/SS02_00053_20100106125828.cap with hash: 8caceb6af7328c4aed2ea349062b74e9
using file /var/ss02/SS02_00075_20100106184519.cap with hash: 1b664b2e900d56ca9750d27ed1ec28fc
using file /var/ss02/SS02_00098_20100107104437.cap with hash: e0d7f5b004016febe707e9823f339fce 
using file /var/ss02/SS02_00095_20100105132356.cap with hash: 41a3938150ec8e2d48ae9498c79a8d0c 
using file /var/ss02/SS02_00097_20100107103332.cap with hash: 4e08b6926c87f5967484add22a76f220
using file /var/ss02/SS02_00090_20100105122531.cap with hash: 470b378ee5a2f4a14ca28330c2009f56
using file /var/ss03/SS03_00089_20100107104530.cap with hash: 468a01753a97a6a5dfa60418064574cc 
using file /var/ss03/SS03_00086_20100105122537.cap with hash: 1fb8641f10f733384de01e94926e0853
using file /var/ss03/SS03_00090_20100107105832.cap with hash: d6209e65348029c3d211d1715301b9f8 
using file /var/ss03/SS03_00088_20100107103248.cap with hash: 56a26b4e84b853e1f2128c831628c65e 
using file /var/ss03/SS03_00072_20100105093543.cap with hash: dca18deb04b7c08e206a3b6f62262465 
using file /var/ss03/SS03_00050_20100106140218.cap with hash: 36761e3f67017c626563601eaf68a133 
using file /var/ss04/SS04_00010_20100105105912.cap with hash: 5188dc70616fa2971d57d4bfe029ec46 
using file /var/ss04/SS04_00071_20100107094806.cap with hash: ab72eaddd9f368e01f9a57471ccead1a 
using file /var/ss04/SS04_00072_20100107100234.cap with hash: 79dea347b04a05753cb4ff3576883494 
using file /var/ss04/SS04_00070_20100107093350.cap with hash: 535920197129176c4d7a9891c71e0243 
using file /var/ss04/SS04_00067_20100107084826.cap with hash: 64a88ecc1253e67d49e3cb68febb2e25 
using file /var/ss04/SS04_00042_20100106144048.cap with hash: bb9bfa773f3bf94fd3af2514395d8d9e 
using file /var/ss04/SS04_00007_20100105101951.cap with hash: d949e673f6138af2d388884f4a6b0f08

Единственные файлы, которые он должен делать, - это один на папку, поэтому только 4 файла. Это вызывает ненужную обработку, и мне приходится иметь дело с перекрывающимися заданиями cron + другие службы были затронуты.

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

Вот код (я не кодер, а системный администратор, так что будьте добры: P) строки 30-32 обрабатывают сравнения хешей. Заранее спасибо.

Ответы [ 5 ]

5 голосов
/ 08 января 2010

Хороший способ обработки / обработки файлов, созданных в случайное время, - это использование incron вместо cron.(Примечание: поскольку incron использует системные вызовы inotify ядра Linux, это решение работает только с Linux.)

В то время как cron выполняет задание на основе даты и времени, incron запускаетзадание на основе изменений в контролируемом каталоге.Например, вы можете настроить incron для запуска задания каждый раз, когда создается или изменяется новый файл.

В Ubuntu пакет называется incron.Я не уверен насчет RedHat, но я считаю, что это правильный пакет: http://rpmfind.net//linux/RPM/dag/redhat/el5/i386/incron-0.5.9-1.el5.rf.i386.html.

После установки пакета incron прочитайте

man 5 incrontab 

для получения информации о настройкеКонфигурационный файл incrontab.Ваш incron_config файл может выглядеть примерно так:

/var/ss01/ IN_CLOSE_WRITE /path/to/processing/script.py $#
/var/ss02/ IN_CLOSE_WRITE /path/to/processing/script.py $#
/var/ss03/ IN_CLOSE_WRITE /path/to/processing/script.py $#
/var/ss04/ IN_CLOSE_WRITE /path/to/processing/script.py $#

Затем, чтобы зарегистрировать этот конфиг с помощью демона incrond, вы должны запустить

incrontab /path/to/incron_config

Это все, что нужно сделать.Теперь, когда файл создается в / var / ss01, / var / ss02, / var / ss03 или / var / ss04, запускается команда

/path/to/processing/script.py $#

с заменой $ # на имявновь созданный файл.

Это избавит от необходимости хранить / сравнивать хэши, и файлы будут обрабатываться только один раз - сразу после их создания.

Просто убедитесь, что ваш скрипт обработки не выполняетнапишите в верхний уровень контролируемых каталогов.Если это так, то incrond заметит созданный новый файл и снова запустит script.py, отправив вас в бесконечный цикл.

incrond отслеживает отдельные каталоги и не рекурсивно отслеживает подкаталоги.Таким образом, вы можете указать tshark записать в / var / ss01 / tobeprocessed, использовать incron для мониторинга / var / ss01 / tobeprocessed и сделать так, чтобы ваш script.py записывал в / var / ss01, например.Существует также интерфейс Python для inotify, называемый pyinotify .В отличие от incron, pyinotify может рекурсивно отслеживать подкаталоги.Однако в вашем случае я не думаю, что функция рекурсивного мониторинга полезна или необходима.

2 голосов
/ 07 января 2010

Я недостаточно знаю, что находится в этих файлах, поэтому это может не сработать для вас, но если у вас есть только один предполагаемый потребитель, я бы рекомендовал использовать каталоги и перемещать файлы, чтобы отразить их состояние. В частности, вы могли бы иметь структуру dir, такую ​​как

/waiting
/progress
/done

и используйте относительную атомарность mv, чтобы изменить «состояние» каждого файла. (Полагаю, что mv действительно атомарно, зависит от вашей файловой системы.)

Когда ваша задача обработки хочет работать с файлом, она перемещает его с waiting на progress (и обеспечивает успешное перемещение). Таким образом, никакое другое задание не может поднять его, так как оно больше не ждет. Когда файл завершен, он перемещается из progress в done, где задача очистки может удалить или архивировать старые файлы, которые больше не нужны.

0 голосов
/ 07 января 2010

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

Я предлагаю вам переместиться вверх от базы данных к базе данных, которая будет действовать как блокировка для последующих cronjobs и иметь «успех» или «завершение» в самом конце. Последняя часть важна, поскольку то, что показано как обработка, но не имеет завершенного состояния (в сочетании с понятием времени), может быть программно завершено как ошибка. (То есть, cronjob пытался обработать его, но никогда не завершал его, и обработка журнала показа в течение 1 недели!)

Подводя итог

  1. Переместить журнал в базу данных, чтобы он действовал как блокировка
  2. Добавить состояние «успешно» или «завершено», которое дало бы понятие состояния с ошибкой

PS: Не поймите это неправильно, но код немного сложен для понимания. Я не уверен, что я вообще так делаю.

0 голосов
/ 07 января 2010

Почему бы просто не переместить обработанный файл в другой каталог?

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

0 голосов
/ 07 января 2010

Я вижу несколько вопросов.

Если у вас есть перекрывающиеся задания cron, вам нужен механизм блокировки для контроля доступа. Разрешить только один процесс за раз, чтобы устранить проблему перекрытия. Вы можете настроить скрипт оболочки для этого. Создайте «блокировку», создав каталог (атомарный mkdir), обработайте данные, затем удалите каталог блокировки. Если сценарий оболочки обнаруживает, что каталог уже существует, когда он пытается его создать, то вы знаете, что другая копия уже запущена, и он может просто выйти.

Если вы не можете изменить таблицы (таблицы) cron, просто переименуйте исполняемый файл и назовите свой скрипт оболочки так же, как старый исполняемый файл.

Не гарантируется, что хэши будут уникальными идентификаторами файлов, скорее всего, они есть, но это не абсолютно гарантировано.

...