Направляющие, выполняющие несколько delayed_job - блокируют таблицы

Эй. Я использую delayed_job для фоновой обработки. У меня есть 8 серверов ЦП, MySQL, и я запускаю 7 процессов delayed_job

RAILS_ENV=production script/delayed_job -n 7 start 

Q1: я задаюсь вопросом, это возможный, что 2 или больше процесса delayed_job начинают обрабатывать тот же процесс (та же рекордная строка в базе данных delayed_jobs). Я проверил код delayed_job плагина, но не могу найти директиву блокировки способом, это должно быть (никакая таблица блокировки или ВЫБОР... FOR UPDATE).

Я думаю, что каждый процесс должен заблокировать таблицу базы данных прежде, чем выполнить ОБНОВЛЕНИЕ на lock_by столбце. Они блокируют запись просто путем обновления locked_by поля (ОБНОВИТЕ locked_by НАБОРА delayed_jobs...). Это действительно достаточно? Никакая блокировка не необходима? Почему? Я знаю, что ОБНОВЛЕНИЕ имеет более высокий приоритет, чем ВЫБОР, но я думаю, что это не имеет эффекта в этом случае.

Мое понимание multy-потоковой ситуации:

Process1: Get waiting job X. [OK]
Process2: Get waiting jobs X. [OK]
Process1: Update locked_by field. [OK]
Process2: Update locked_by field. [OK]
Process1: Get waiting job X. [Already processed]
Process2: Get waiting jobs X. [Already processed]

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

Q2: действительно ли 7 delayed_jobs являются большим количеством для 8CPU сервер? Почему да/не.

Спасибо 10x!

10
задан xpepermint 25 April 2010 в 08:58
поделиться

1 ответ

Я думаю, что ответ на ваш вопрос находится в строке 168 "lib / delayed_job / job.rb":

self.class.update_all(["locked_at = ?, locked_by = ?", now, worker], ["id = ? and (locked_at is null or locked_at < ?)", id, (now - max_run_time.to_i)])

Здесь обновление строки выполняется только в том случае, если никакой другой исполнитель уже не заблокировал задание, и это проверяется, если таблица обновляется. Блокировка таблицы или подобное (что, кстати, значительно снизит производительность вашего приложения) не требуется, поскольку ваша СУБД гарантирует, что выполнение одного запроса изолировано от эффектов других запросов. В вашем примере Process2 не может получить блокировку для задания X, поскольку он обновляет таблицу заданий тогда и только тогда, когда она не была заблокирована ранее.

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

11
ответ дан 4 December 2019 в 01:00
поделиться
Другие вопросы по тегам:

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