Неожиданные задания sidekiq выполняются - PullRequest
0 голосов
/ 19 апреля 2019

Я использую sidekiq cron для запуска некоторых заданий.У меня есть родительская работа, которая выполняется только один раз, и эта родительская работа запускает 7 миллионов дочерних работ.Тем не менее, в моей приборной панели sidekiq говорится, что более 42 миллионов рабочих мест в очереди.Я проверил эти рабочие места, поставленные в очередь, они мои детские работы.Я пытаюсь выяснить, почему так много рабочих мест, чем ожидалось, поставлено в очередь.Я проверил журнал в sidekiq, заметил одну вещь: «Cron Jobs - добавить работу с именем: new_topic_post_job» много раз появляется в журнале.new_topic_post - это имя родительского задания в schedule.yml.Следующие строки также отображаются много раз

2019-04-18T17:01:22.558Z 12605 TID-osb3infd0 WARN: Processing recovered job from queue queue:low (queue:low_i-03933b94d1503fec0.nodemodo.com_4): "{\"retry\":false,\"queue\":\"low\",\"backtrace\":true,\"class\":\"WeeklyNewTopicPostCron\",\"args\":[],\"jid\":\"f37382211fcbd4b335ce6c85\",\"created_at\":1555606809.2025042,\"locale\":\"en\",\"enqueued_at\":1555606809.202564}"
2019-04-18T17:01:22.559Z 12605 TID-osb2wh8to WeeklyNewTopicPostCron JID-f37382211fcbd4b335ce6c85 INFO: start

WeeklyNewTopicPostCron - имя родительского класса задания.Интересно, означает ли это, что моя родительская работа выполняется несколько раз, а не только 1?Если так, то в чем причина?Я почти уверен, что время в работе cron подходит, я установил его на «0 17 * * 4», что означает, что оно запускается только раз в неделю.Также я установил для параметра false значение false для родительской работы и 3 для дочерних.Таким образом, даже все детские рабочие места терпят неудачу, у нас все еще должно быть только 21 миллион рабочих мест.Ниже приведены мои настройки задания cron в schedule.yml

new_topic_post_job:
  cron: "0 17 * * 4"
  class: "WeeklyNewTopicPostCron"
  queue: low

, а это WeeklyNewTopicPostCron:

class WeeklyNewTopicPostCron
  include Sidekiq::Worker

  sidekiq_options queue: :low, retry: false, backtrace: true

  def perform
    processed_user_ids = Set.new
    TopicFollower.select("id, user_id").find_in_batches(batch_size: 1000000) do |topic_followers|
      new_user_ids = []
      topic_followers.map(&:user_id).each { |user_id| new_user_ids << user_id if processed_user_ids.add?(user_id) }
      batch_size = 1000
      offset = 0
      loop do
        batched_user_ids_for_redis = new_user_ids[offset, batch_size]
        Sidekiq::Client.push_bulk('class' => NewTopicPostSender, 
                                  'args' => batched_user_ids_for_redis.map { |user_id| [user_id, 7] }) if batched_user_ids_for_redis.present?
        break if batched_user_ids_for_redis.size < batch_size
        offset += batch_size
      end
    end
  end
end

1 Ответ

1 голос
/ 19 апреля 2019

Скорее всего, ваша родительская работа sidekiq вызывает сбой процесса sidekiq, что приводит к перезапуску работника.При перезапуске sidekiq, вероятно, пытается восстановить прерванное задание и снова начинает его обрабатывать (с самого начала).Некоторые детали здесь: https://github.com/mperham/sidekiq/wiki/Reliability#recovering-jobs

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

ps aux | grep sidekiq

Возможно, чтоу вас есть некоторая monit конфигурация для перезапуска sidekiq в случае, если использование памяти слишком велико. Возможно, этот запрос вызывает сбой процесса:

TopicFollower.select("id, user_id").find_in_batches(batch_size: 1000000)

Попробуйте уменьшитьbatch_size.1 миллион кажется слишком большим числом.Но я думаю, что процесс sidekiq умирает при обработке долго выполняющегося родительского процесса.

...