Демон для обработки очереди

fixxxer

К.О.
Партнер клуба
@grigori, нахрена? обычный cli скрипт, запускается N инстансов любым способом (systemd, supervisor, смешная третья опция), каждый читает очередь.

В том же Laravel так и сделано: https://laravel.com/docs/5.6/queues
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
запускается N инстансов любым способом (systemd, supervisor, смешная третья опция), каждый читает очередь.
В том же Laravel так и сделано: https://laravel.com/docs/5.6/queues
там нет ничего про балансировку задачи между инстансами
я вижу поллинг редиса или базы раз в block_for сек, и лимитом количества воркеров, которые могут одновременно поймать одну и ту же задачу
не понимаю, в чем может быть смысл дублировать обработку одной задачи

если я не пропустил ничего - это ущербно, по сравнению с fpm, не понимаю зачем это создано
 
Последнее редактирование:

AnrDaemon

Продвинутый новичок
Да ради Б-га, пусть твой актор дёргает динамический FPM… Это детали реализации.
 

fixxxer

К.О.
Партнер клуба
могут одновременно поймать одну и ту же задачу
Не могут.
про балансировку задачи между инстансами
Кто первый освободился и схватил задачу из FIFO очереди - тот ее и обрабатывает.
Чем это с точки зрения балансировки отличается от того, как fpm работает с очередью fcgi-соединений?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@AnrDaemon, он должен не просто дергать - он должен держать соединение открытым, пока задача в работе, что приводит к оркестрированию
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Не могут.

Кто первый освободился и схватил задачу из FIFO очереди - тот ее и обрабатывает.
Чем это с точки зрения балансировки отличается от того, как fpm работает с очередью fcgi-соединений?
там не написано, а почему не могут? кто помешает двум процессам поймать одну задачу?

you may specify the maximum number of workers that may simultaneously process a given job. This can be helpful when a queued job is modifying a resource that should only be modified by one job at a time. For example, using the funnel method, you may limit jobs of a given type to only be processed by one worker at a time:
Redis::funnel('key')->limit(1)->then(function () {
 

Adelf

Administrator
Команда форума
да даже ларавель с queue_driver=database из таблички через статус задачи вполне себе решает эту задачу. думаю, у других решено это тоже.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@Adelf, процессы, которые в табличке выставляют статус без инкремента числа процессов, которые ее взяли, с последующим перечитыванием и рандомным sleep при коллизии, отлично входят в race condition,
а с этим алгоритмом - хреново держат realtime-события

а кто те другие, о которых ты пишешь, и что решено?
 

fixxxer

К.О.
Партнер клуба
а почему не могут?
Потому что это так или иначе решено в каждом драйвере.

you may specify the maximum number of workers that may simultaneously process a given job. This can be helpful when a queued job is modifying a resource that should only be modified by one job at a time. For example, using the funnel method, you may limit jobs of a given type to only be processed by one worker at a time:
Там не очень понятно написано. Job тут имеется ввиду class, а не instance. Имя очереди, а не ее элемент.
 

grigori

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

fixxxer

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

Слова особого прочтения не требуют - если читать сначала, там объясняется, что такое Job в терминах laravel. Хотя потом он сам использует это слово неоднозначно, есть такое ;)

Да и я ж не настаиваю на конкретной реализации, просто привел пример, с чем работаю. Есть всякие symfony queue bundles, php-enqueue итд, сотни их.
 
Последнее редактирование:

grigori

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

вопрос у меня возник потому, что решение проблем с race condition без мьютексов мне представляется двумя способами:
а) lock + sleep - непредсказуемый latency
б) менеджер процессов со списком процессов в памяти - spof+state
 

fixxxer

К.О.
Партнер клуба
Я не понимаю, о чем ты. :)

Все сводится к вариациям на тему select for update или атомарным операциям типа RPOPLPUSH.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Я не понимаю, о чем ты. :)

Все сводится к вариациям на тему select for update или атомарным операциям типа RPOPLPUSH.
* минимальное значение innodb_lock_wait_timeout - 1, при select for update в mysql это приводит к 1 секунде сна всех процессов, кроме первого.
Иногда - нормально, но для разбора событий вроде "реклама на странице была в зоне видимости 200 миллисекунд" - нет.
Надо учитывать врожденные пороки развития.
* А в постгресе есть NOWAIT и LISTEN - можно сделать полноценную реализацию с уведомлениями и мьютексами. Но какой поток сообщений оно выдержит - я не знаю.
* очередь в редисе тоже интересная, надо пробовать, я с ней еще не работал
 

AnrDaemon

Продвинутый новичок
@AnrDaemon, он должен не просто дергать - он должен держать соединение открытым, пока задача в работе, что приводит к оркестрированию
Извини, но ты сейчас пытаешься теоретизировать в попытках найти свою собственную Большую Синюю Кнопку.
Всё это решается, тем или иным способом, в зависимости от предъявленых требований.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
мне нравится заклинание "тем или иным способом", которое стало последние пару дней очень популярным :)

требования у меня простые - обрабатывать три типа потока событий
* типа "показ объявления", когда нужна скорость в ущерб полноте данных,
* поток событьй типа "покупка", когда важна полнота данных в ущерб скорости, и
* поток событий типа "обработка фотографий": ресайз в real time, запись в хранилище в фоне, - тут нужна оптимизация баланса доступности сервиса и цены используемых серверов

соответственно, я рассматриваю варианты решений для каждого типа очереди

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

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

запись в лог nginx, и обсчет демоном в фоне - тоже костыль, не хочу
 
Последнее редактирование:

AnrDaemon

Продвинутый новичок
@grigori, остановись, пока тебя кто-нибудь не начал обучать постановке задач по методу кутёнка.
Твоё практическое теоретизирование до сих пор не зашло дальше "я книгу не читал/фильм не смотрел, но считаю своим долгом…"
Никто не знает, какие у тебя конкретные задачи, больше того - никто знать не хочет. Тебе описали инструмент и приблизительно обрисовали его возможности. Дальше уже твоя работа, как заинтересованного специалиста - собрать концептуальную схему и посмотреть, подходит ли инструмент под твои задачи.
 
  • Like
Реакции: WMix

AnrDaemon

Продвинутый новичок
например, была запись просмотров - при запросе ресурса делался insert, пришли роботы, записей стало много, база-то на insert справлялась, а подсчет статистики - уже нет,
пришлось отключить, а юзеры, которые деньги платят, теперь требуют ее вернуть
RRD рассматривали?
 

fixxxer

К.О.
Партнер клуба
мне нравится заклинание "тем или иным способом", которое стало последние пару дней очень популярным :)
Ты мне предлагаешь озвучить все разнообразие способов для каждого из десяти с лишним драйверов? Сорри, для половины мне лень, а для другой половины сам не в курсе, так как ни разу не пользовался.
 
Сверху