Я следовал за образец кода создать параллельную очередь заданий GNU, как показано ниже
// create a job queue file
touch jobqueue
//start the job queue
tail -f jobqueue | parallel -u php worker.php
// in another shell, add the data
while read LINE; do echo $LINE >> jobqueue; done < input_data_file.txt
Этот подход работает и обрабатывает работу как простую очередь заданий. Но есть две проблемы
1- чтение данных из входного файла и последующая запись его в очередь заданий (другой файл) происходит медленно, поскольку требует дискового ввода-вывода.
2 — если по какой-то причине моя работа прерывается в середине, и я перезапускаю параллельную обработку, он будет повторно запускать все задания в файле очереди заданий
Я могу добавить скрипт в worker.php, чтобы фактически удалить строку из очереди заданий, когда работа выполнена, но я чувствую, что есть лучший способ для этого.
Возможно ли, что вместо использования
tail -f jobqueue
Я могу использовать именованный канал в качестве входных данных для параллельной, и моя текущая установка все еще может работать как простая очередь?
Я предполагаю, что таким образом мне не придется удалять строки из конвейера, которые будут выполнены, поскольку они будут автоматически удалены при чтении?
Постскриптум Я знаю и использовал RabbitMQ, ZeroMQ (и мне это нравится), nng, nanomsg и даже php pcntl_fork, а также pthreads. Так что вопрос не в том, что там для параллельной обработки. Больше о том, чтобы создать рабочую очередь с gnu параллельно.
while read LINE; do echo $LINE >> jobqueue; done < input_data_file.txt
Это можно сделать намного быстрее:
cat >> jobqueue < input_data_file.txt
Хотя fifo может работать, он будет блокироваться. Это означает, что вы не можете поставить много в очередь — что побеждает назначение очереди.
Я удивлен, если дисковый ввод-вывод является проблемой для чтения реальных заданий: GNU Parallel может выполнять 100-1000 заданий в секунду. Задание может занимать не более 128 КБ, поэтому самое большее на вашем диске должно быть 128 МБ / с. Если вы не выполняете 100 заданий в секунду, то дисковый ввод-вывод очереди никогда не будет проблемой.
Ты можешь использовать --resume --joblog mylog
чтобы пропустить уже запущенные задания, если вы перезапустите:
# Initialize queue
true >jobqueue
# (Re)start running the queue
tail -n+0 -f jobqueue | parallel --resume --joblog mylog
Других решений пока нет …