Стабильность batch операций

grigori

( ͡° ͜ʖ ͡°)
Команда форума
к сожалению, никто не привел причины почему запуск по крону им не подходит.
я встречал один случай: длительность работы может быть большой, а начать выполнение надо условно мгновенно,
но чаще всего это решается через завершение скрипта по сигналу после запуска по крону нового вместо завершения при отсутствии задания
 

cDLEON

Онанист РНРСlub
Запуск по крону имеет кучу недостатков. Контролировать количество запущенных копий не возможно. Следить за выполнением - ещё тот гемор. "Прибивать по сигналу" - тоже ещё тот гемор. Особенно, если запущено несколько инстансов. Всё это, конечно, реализуемо и там. Но усилия не соизмеримы. Крон хорошо подходит для быстрых(по времени выполнения) или редких задач.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Крон создан для регулярного исполнения алгоритма в одним процессе.
Если количество процессов в нормальном режиме больше 1 - крон вообще ни при чем, и про map-reduce на кроне никто не говорит.

Для одного-двух фоновых процессов существуют простые механизмы межпроцессного взаимодействия.

Часто допустимо, чтобы 2 процесса работали одновременно короткое время. Усилия по прибиванию старого процесса при пакетной обработке сводятся к алгоритму из 3 строк:
* процесс при запуске пишет в pid-файл свой pid, берет пакет задач и начинает обработку,
* старый процесс в рабочем цикле видит чужой id и завершает работу

Примеры, где это работает: проверка и рассылка почты, расчеты данных, ресайз фоток.

Если надо исключить одновременное исполнение - можно добавить ожидание в скрипте когда старый завершится, а старый при завершении отправляет posix_kill SIGUSR новому pid-у.
Если процесс может зависнуть, заблокировав общий ресурс, новый может отправить старому SIGTERM, но это уже граничные ситуации, надо разбираться, ставить таймауты, и проблема совсем не в кроне.
 
Последнее редактирование:

stalxed

Новичок
grigori, на языках, которые в отличие от PHP не созданы, "чтобы умирать", схема выше гуд.
Но как представишь Doctrine, сразу представляешь утечки памяти...
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
у меня обработчики на php по такой схеме работают долго, ограничений не наблюдаю

доктрина не для демонов, это авторы признают, но, если ты не Свидетель Доменной Модели на Рефлексии - варианты есть, тот же sql ручками, и ничего не течет

перезапуск процесса раз в 15 минут или час как-раз решает проблему небольших утечек
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Надо сказать, что проблема утечек памяти куда болезненнее с экстеншнами, чем с пхп-кодом, потому что с ними особо поделать ничего нельзя, да и дебажить не так просто. А текут многие экстеншны, за минусом наверное, самых основных.
 

stalxed

Новичок
доктрина не для демонов, это авторы признают, но, если ты не Свидетель Доменной Модели на Рефлексии - варианты есть, тот же sql ручками, и ничего не течет
Я вот думаю рискнуть и использовать схему очереди:
  • 1 задание: добавить в очередь n требуемых записей на некую обработку
  • 2 задание: каким-нибудь демоном вызывать в несколько потоков php cli, это пускай админы делают, но вроде не проблема ожидать завершение работы, только тогда вызывать снова, т.е. можно контролировать таким способом количество потоков. И уже в этих потоках выполнять n заданий. 1 запуск не дольше 1 минуты. Можно вообще 1 запуск - 1 задание.
В теории вроде должно быть нормально... И пофиг доктрина, не доктрина, 1 запуск не будет отличаться, в плане ресурсов, от 1 запуска через веб(т.е. количество работы сделать сравнимым с обычным запросом).
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
а кто будет ставить первое задание?
ты ж не забывай, что народ тут поржать любит, посоветуют еще написать скрипт, который напишет скрипт

представляю ответ админа, к которому приходит разработчик и просит сделать демона, который в несколько потоков вызывает php cli :D

тебе алгоритм Дима расписал больше недели назад, ты еще не решил задачу?
 
Последнее редактирование:

stalxed

Новичок
grigori, пока всё сделал через это http://jmsyst.com/bundles/JMSJobQueueBundle
Для тестовой эксплуатации хватит.

Но позже да, нужно будет обеспечить более большие объёмы данных.

< а кто будет ставить первое задание?
другое задание

< посоветуют еще написать скрипт, который напишет скрипт
Вообще-то в этом ничего плохого нет. Я бы даже сказал, что это хорошо.
Например конфиги для data grid сейчас у меня так генерятся:
  1. Мой генератор, из пары шаблонов - генерирует кучу конфигов дата гридов(мне впадлу было писать однородную хрень... генератор быстрее написать).
  2. Конфиги дата гридов собираются в сервис DI контейнера симфони(как аргумент конструктора).
  3. Модуль oro platform из конфига собирает datagridы.
И что плохого в сервере очередей?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
а кто будет ставить другое задание? :)

ты, главное, начальству не говори что они платят тебе за неделю развлечений когда эта задача выполняется за несколько часов безо всяких параллельных вычислений и серверов очередей

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

если таки надо распараллелить вычисления между php-скриптами, самый простой, надежный и удобный способ - отдельный служебный пулл fpm, который запускается ab или курлом, алгоритм разбора пакетов заданий Дима разжевал
все остальное - просто развлекуха
 
Последнее редактирование:

stalxed

Новичок
grigori, у очереди главный плюс - отслеживание завершения задания, т.е. скрипт сдох, из очереди не убралось сообщение, так как не подтвердил завершение.
Т.е. весь геморрой с отслеживанием завершения - просто перекладывается на плечи сервера очередей.
Схема DiMA - нужно писать больше кода - отслеживать, делить, контролировать...
А так:
  • контроль выполнения перекладываю на сервер очередей;
  • настройку сервера очередей на админов;
  • связь с сервером очередь на авторов каково-нибудь бандла, например https://github.com/videlalvaro/RabbitMqBundle
Самому остаётся чуток, жаль что авторы бандла не сделали ещё удобное превращение заданий в команды symfony, вообще бы рай...
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
SELECT * FROM tasks WHERE task_status='new' OR started < now() - interval 15 min
ох, много кода
  • контроль выполнения перекладываю на сервер очередей;
не перекладываешь, а прячешь - обработки сбоев нет, дебаг в цикле стороннего сервера очередей проблематичен. бывает, нужно отдебажить состояние гонки
  • настройку сервера очередей на админов;
админы у вас получают меньше тебя? начальству только не говори об этой "экономии" :)
а админам не говори о том, что зоопарк с серверами очередей, на самом деле, не обязателен
  • связь с сервером очередь на авторов каково-нибудь бандла
винить в проблемах авторов бандлов -- это прекрасно!
а я-то как дурак сегфолты в php и фреймворках багрепорчу
 
Последнее редактирование:

stalxed

Новичок
grigori, ваша тактика: только php, никаких ORM, никакой кодо-генерации, никаких сторонних библиотек, никаких серверов очередей...
ПОЧЕМУ?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
моя тактика простая как Бритва Оккама: хорошо то, что выгодно.

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

Если можно за одно время написать решение на Симфони, nginx и mysql, которые уже есть, или на Симфони и RabbitMQ, который надо поставить, я выберу первое.
Если для обработки выделяется отдельный сервер, который будет обрабатывать десятки миллионов записей в сутки для разных очередей - я выберу второй.
В твоих задачах нет миллионов операций в сутки, у тебя просто пересчет скидок для клиентов, и ты не ebay. Тебе хватит простой пакетной обработки без сервера очередей и параллельных вычислений.

еще, возможно, причина в том, что я уже не раз дебажил race condition на параллельных вычислениях, а ты, вероятно, еще нет
 
Последнее редактирование:

stalxed

Новичок
grigori, да, данных меньше, чем предоставляемых мощностей.
Т.е. мощности превышают задачу в несколько раз грубо говоря...
И если понадобится ещё сервер - не проблема.

Главный критерий стабильность, в идеале необходимо, чтобы вообще проект не требовал вмешательства, на полной автономии.

Я не могу понять это:
Я рассказываю о решении более надежном
чем решение у DiMA более стабильно?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
нет spof и узких мест, все открыто, прозрачно, легко дебажится и failover-ится
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
например, читаю я http://www.rabbitmq.com/reliability.html
If we need to ensure that our broker survives hardware failure, we can use RabbitMQ's clustering.
ты умеешь делать кластер RabbitMQ? ты знаешь как восстанавливать его хранилище, если сервак упадет, допустим, в kernel panic?
я - нет, а вот репликацию mysql - умею, и твои админы - тоже
 

fixxxer

К.О.
Партнер клуба
Вместо запуска по крону в современных дистрибутивах, где init-система имеет функции супервизора (upstart, systemd), может быть удобно запускать ей. Пусть себе скрипт делает работу и дохнет - само же и перезапустится моментально, и c pid-файлами само разберется. Несколько инстансов современные инит-системы тоже умеют.

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

Если события возникают достаточно редко, активный поллинг сам по себе получается слишком нагрузочным, и хочется запускать обработчик только по факту получения события - можно взять gearman, например. Он хотя бы достаточно простой. Что касается возможной потери данных - так можно отправлять не данные, а уведомления, потерять одно уведомление совсем не страшно, если оно в виде "чувак, там для тебя что-то есть". Но тут уже надо аккуратнее - не устроить себе race condition.
 
Последнее редактирование:
Сверху