Задать вопрос
evgen_dev
@evgen_dev
Веб-разработчик

Как хранить и обмениваться текущим смещением строк в файле при его построчном чтении несколькими процессами?

Приветствую.
Есть приложение на Laravel. Есть мастер-комманда, которая запускает в фоне N процессов (артисан команды) , которые обрабатывают файлы. Не вдаваясь в подробности, есть условный файл с 10000 строк.
Задача запустить 100 конкурирующих процессов, которые будут читать и обрабатывать файл построчно.
Сейчас сделано так, что на каждый процесс выделяется по 100 строк и он их обрабатывает, по завершению запускается новый процесс со 100 строками и т. д. Это решение не нравится тем, что если какой-то процесс работает медленно, остальные не могу ему "помочь", даже если они уже свободные.

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

P. S. Использование mysql не рассматриваю в принципе.

Благодарю.
  • Вопрос задан
  • 92 просмотра
Подписаться 1 Средний 10 комментариев
Пригласить эксперта
Ответы на вопрос 3
Я бы на твоём месте использовал атомарный инкремент редиса
$currentRow = $redis->incr('current_row');
Даже если все 100 потоков в одну миллисекунду выполнят этот код, то redis гарантированно отдаст каждому потоку своё уникальное значение без коллизий
Ответ написан
Комментировать
ipatiev
@ipatiev Куратор тега PHP
Потомок старинного рода Ипатьевых-Колотитьевых
Для не слишком принципиальных товарищей есть элементарное решение
update tasks set uuid = ? where done=0 limit 1;
// обрабатываем
update tasks set done=1 where  uuid = ?;


А принципиальные должны страдать :)
Ответ написан
@aleksejjjjj
Вы либо слишком переусложняете, либо я задачу вашу не понимаю.

1. Есть 100 воркеров. Они крутятся через supervisor, ожидают задач
2. Что угодно, хоть консольная команда, хоть в контроллере, хоть суперворкер - читаем файл по 10 строк и отправляем в очередь.
MyJob::dispatch($tenLinesFromFile);
Итого, файл разделился на 1000 кусков, освободившийся воркер обрабатывает следующую часть.
Накладные расходы? 10мс? При времени обработки в 15 мин кажется не там вы оптимизировать пытаетесь.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы