执行意外的 sidekiq 作业

Unexpected sidekiq jobs get executed

我正在使用 sidekiq cron 来 运行 一些工作。我有一个 parent 工作,它只有 运行 一次,而那个 parent 工作启动了 700 万个 child 工作。然而,在我的 sidekiq 仪表板中,它显示有超过 4200 万个工作排队。我检查了那些排队的工作,它们是我的 child 工作。我想弄清楚为什么排队的工作比预期的多。我检查了 sidekiq 中的日志,我注意到的一件事是 "Cron Jobs - add job with name: new_topic_post_job" 在日志中多次出现。 new_topic_post 是 schedule.yml 中 parent 作业的名称。以下几行也多次出现

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 是 parent 工作 class 的名称。想知道这是否意味着我的 parent 工作 运行 多次而不是只有 1 次?如果有,原因是什么?我很确定 cron 作业中的时间是正确的,我将它设置为“0 17 * * 4”,这意味着它每周只有 运行s 一次。此外,我将 parent 作业的重试设置为 false,child 作业的重试设置为 3。所以即使所有 child 个工作岗位都失败了,我们应该仍然只有 2100 万个工作岗位。以下是我在 schedule.yml

中的 cron 作业设置
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

很可能是您的父 sidekiq 作业导致 sidekiq 进程崩溃,然后导致 worker 重新启动。在重新启动时,sidekiq 可能会尝试恢复中断的作业并再次开始处理它(从头开始)。这里有一些细节: https://github.com/mperham/sidekiq/wiki/Reliability#recovering-jobs

这可能会在父作业最终完成之前发生多次,因此会创建非常多的子作业。您可以通过检查 sidekiq 进程的进程 ID 轻松地验证这一点,同时此作业正在 运行 并且它很可能会在一段时间后继续更改:

ps aux | grep sidekiq

可能是你有一些monit配置来重启sidekiq以防内存使用过多high.Or可能是这个查询导致进程崩溃:

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

尝试减少 batch_size。 100 万感觉这个数字太高了。但我最好的猜测是 sidekiq 进程在处理长 运行ning 父进程时死亡。