如何修复棘手的 Sidekiq 内存问题

主要观点:使用 Sidekiq 运行 Ruby 应用的后台任务久了会遇到内存问题,虽有很多内容专注于帮助查找和修复内存问题,但有时后台任务确实需要大量内存。本文主要探讨减轻内存消耗大的后台任务的危害,包括用 APM 工具查找内存问题、常见的内存优化方法(如扇出大任务)、根据内存需求将任务拆分到不同队列以及自动缩放专用 Sidekiq 队列等。
关键信息:

  • APM 工具可监测应用和 Sidekiq 进程的内存问题,如 Scout、New Relic 和 AppSignal 可提供内存使用见解。
  • 常见的内存优化方法是“扇出”大任务,将其拆分成可更快执行甚至并行的小任务,如将发送提醒的任务拆分成RemindersJobNotifyUserJob
  • 可根据内存需求将内存消耗大的任务放入单独的 Sidekiq 队列,如ImportJob,并为其分配单独的进程,还可设置单线程运行,甚至将其分配到不同机器,垂直扩展机器内存。
  • 分配内存消耗大的 Sidekiq 队列到单独进程后可进行水平缩放,如使用 Judoscale 根据队列时间自动缩放 Sidekiq 工作进程,以更好地处理峰值工作负载而不浪费资源。
    重要细节:
  • RemindersJob通过wherepluck方法获取需要通知的Event记录的 ID,然后使用NotifyUserJob.perform_bulk方法将通知任务入队。
  • 可通过修改类定义将ImportJob放入memory_hungry队列,如class ImportJob include Sidekiq::Job sidekiq_options queue: 'memory_hungry' end
  • 可通过bundle exec sidekiq -q default -q memory_hungry启动包含两个队列的 Sidekiq 进程,还可在Procfile中设置不同队列的工作进程,如worker_memory_hungry: RAILS_MAX_THREADS=1 bundle exec sidekiq -q memory_hungry
  • Judoscale 可根据队列时间自动缩放 Sidekiq 工作进程,处理内存消耗大的任务时可先拆分任务,再根据内存需求拆分到队列,灵活调整配置和添加资源。
阅读 12
0 条评论