避免服务器过载的慢重烘脚本

我不得不等到整个重烤完成就上线了。上线后,我无法运行重烤,因为它会杀死服务器。我可以在默认队列上运行重烤,因为它会延迟所有其他进程,如通知。

所以我使用了这个脚本将所有重烤任务排入超低优先级的 sidekiq 队列。如果有人需要,在此分享。

# slow_rebake_resumer_ultralow.rb
# 从特定点恢复和排队重烤作业,并将它们直接发送到 :ultra_low 优先级队列。
# 在容器内执行,使用 -

# --- 配置 ---
BATCH_SIZE = 500
SLEEP_DURATION = 5
# --- 从上次更新的起点 ---
last_processed_id = 1952526 
# --------------------

start_time = Time.now
total_posts = Post.count

puts "正在恢复并排队重烤作业,共 #{total_posts} 个帖子到 :ultra_low 队列..."
puts "从帖子 ID #{last_processed_id} 之后开始。"
puts "---"

loop do
  # 高效地查找要处理的下一批帖子
  posts_to_enqueue = Post.where("id 

  # 如果没有更多帖子,则退出循环
  break if posts_to_enqueue.empty?

  posts_to_enqueue.each do |post|
    begin
      # 定义所有选项在一个哈希中,包括目标队列
      options = {
        post_id: post.id,
        cook: true,
        bypass_bump: true,
        queue: :ultra_low
      }

      # 使用正确、经过验证的语法排队作业
      Jobs.enqueue(:process_post, options)

    rescue =
      puts "!!! 为帖子 ID #{post.id} 排队作业时出错:#{e.message}"
    end
  end

  # 更新我们的位置到当前批次的最后一个帖子 ID
  last_processed_id = posts_to_enqueue.last.id
  
  # 获取更准确的计数以进行进度报告
  enqueued_count = Post.where("id 

  # --- 进度报告 ---
  percentage = (enqueued_count.to_f / total_posts * 100).round(2)
  elapsed_minutes = ((Time.now - start_time) / 60).round(2)

  puts "已排队到帖子 ID #{last_processed_id}。总共排队:约 #{enqueued_count} / #{total_posts} (#{percentage}%)"
  puts "已用时间(本次会话):#{elapsed_minutes} 分钟。"
  puts "作业正在发送到 :ultra_low 队列。"

  # 在批次之间暂停以保持低负载
  if enqueued_count 
    puts "休眠 #{SLEEP_DURATION} 秒..."
    sleep(SLEEP_DURATION)
    puts "---"
  end
end

puts "\n所有剩余的重烤作业已成功排队到 :ultra_low 队列!"

3 个赞

我很确定,一直有一个进程在运行,做着几乎相同的事情,并且它在恢复脚本中有提到,但也许你在生产服务器上运行了迁移,并且没有看到它。

是的,有。我没有运行标准的迁移脚本导入。等用户们抱怨完 Discourse 的无限滚动和糟糕混乱的用户体验后,我会发布更多相关信息。:upside_down_face:

但总的来说,有时也可能需要进行完全的重新烘焙,例如更改域名、进行一些查找和替换等。

抱歉打扰了,我的 Discourse 也遇到了类似的情况。

有什么提示可以告诉我如何运行这个脚本吗?

应该在哪里创建脚本,以及如何调用它?

提前感谢!

在共享目录下的 tmp 目录中创建一个名为 slow_rebake_resumer_ultralow.rb 的文件,并将所有代码粘贴到其中。

然后,在容器内使用 rails runner slow_rebake_resumer_ultralow.rb 执行该文件。

yousite.com/sidekiq 下观察进度。

1 个赞