我在 Sidekiq 上遇到了一个问题。
通过 Sidekiq Web UI 监控时,它处理任务的速度非常快。但偶尔似乎会被淹没,导致运行速度极慢,降至正常速度的 1-5% 左右,除非我清空 Redis,否则无法恢复,尽管服务器资源使用情况正常且很低。
看起来一旦队列达到某个大小,它就会卡住并急剧变慢,导致队列进一步增长。不过这只是我的猜测,也许队列变大是因为它因其他原因变慢了。
这个动图描述了我看到的情况:
服务器资源非常充足,当前 CPU 使用率非常低,不到 10%。内存和 SSD 空间也充足。关于服务器配置,它有 16 个 CPU 核心(32 个线程)。我尝试运行 8 到 14 个 unicorn_sidekiq 进程,也试过 20 个,但这导致了大量 5xx 错误。
我之前通过以下方式加快了 Sidekiq Web UI“忙碌”标签页中显示的那些慢速任务的处理速度:
(在 /etc/sysctl.conf 文件中添加 ‘vm.overcommit_memory = 1’ 并重启服务器),同时将 unicorn_sidekiq 进程数从 12 减少到 8。
但问题仍然存在,运行依然缓慢。昨天我在 Redis 日志中看到了以下信息(唯一的另一个警告是关于未将 overcommit_memory 设置为 1,我已在上面修改):
# WARNING: /proc/sys/net/core/somaxconn 被设置为较低的值 128
^ 有人解决过这个警告吗?
总之,如果任何人知道可能的原因或解决方案,请告诉我,非常感谢。
我希望彻底解决此问题,避免再次发生,而不是依赖清空队列这种临时措施。
以下是我在 Sidekiq 仪表板上看到的内容截图:
以及一些“忙碌”标签页下任务的截图:
另外,有人知道从 Sidekiq Web UI 中删除低优先级队列是否安全吗?
更新:我已成功删除低优先级队列,但任务处理速度保持不变。
您是否有关于任务耗时情况的指标?看起来您的 PostAlert 任务存在严重的争用问题,但其他任务则很快完成。
根据我在 Sidekiq Web UI 中的观察,您说得对,其他任务似乎都很快完成,除了:
Jobs::PostAlert:0 到 3 分钟,大部分集中在 0 到 1 分钟之间。
Jobs::ProcessPost:0 到 21 秒。
我使用 Amazon SES 进行发送,并已配置邮件接收器以支持 VERP 接收。
SES 显示的发送限制为每秒 25 封邮件。这是否太慢了?我或许可以申请提高该限制。
既然您提到了这一点,我注意到该问题出现的当天,恰好是发送量远超平常的摘要邮件集中发送的日子(由于过去的配置问题,大量摘要邮件被集中到同一天发送)。
不确定有多少用户会收到邮件。管理员仪表板中显示的近 30 天活跃用户数为 60.8k,这或许是一个参考指标?以下是 SES 的发送统计信息(24 小时限制为 10 万+):
更新:SES 每秒发送速率限制已从 25 提升至 50。现在每小时可发送 18 万封邮件(尽管每日允许发送总量略高于 10 万封)。不过,Sidekiq 作业处理速度似乎并未提升。
Falco
(Falco)
10
几年前,我们曾遇到过一个问题:用户拥有10,000条未读通知,导致通知查询变慢,进而使 PostAlert 任务执行缓慢。
我们已添加保护机制,防止此类情况再次频繁发生,但在您的环境中可能会表现出不同的性能特征。
是否有用户设置了关注类别,却完全不在意通知数量?
您能否检查数据库中每位用户未读通知的最大数量?
所以我再次清空了低优先级队列,并让它搁置了几天(自上次更新以来没有任何更改)——它没有立即加速,积压的队列任务迅速增加,但随着时间的推移似乎自行恢复了。现在任务处理速度飞快。
使用 20 秒的轮询间隔,过去几分钟内每秒处理的任务量在 55 到 140 之间。按天来看也很健康,没有队列积压。非常感谢 @Falco @supermathie @Stephen 的帮助,我真的很感激!
关于你们的问题,我不太确定如何检查这些。如果仍然有帮助,我很乐意进行检查(需要一些指导)并提供相关信息。可能相关的一点是,我一直将“每位用户每天最大邮件数”设置保持为 3。
我可能说得太早了。Sidekiq 任务目前以每秒约 1 到 3 个的速度运行,队列积压为 881 万。

david
(David Taylor)
13
您上次更新是什么时候?几天前,我为 PostAlert 作业添加了一些性能改进:
我们的一些超大型站点在拥有大量用户“关注首帖”的分类中遇到了性能问题。此提交已在我们托管环境中解决了该问题,因此它也有可能对您的站点有所帮助。
太好了!我现在正在更新,上次更新大约是在 10 天前(测试已通过)。我会持续监控,看看是否有改善,然后向您反馈。谢谢!
更新:很遗憾,更新后速度没有立即改善。过段时间再看看是否会好转。
更新:运行仍然缓慢,队列正在积压。通过 ‘top’ 看到大量 postmaster 进程。总 CPU 使用率约为 85%(32 核),其中绝大部分来自 postmaster。这很有趣,因为今天早些时候 CPU 使用率仅为 20-35%(当时 Sidekiq 运行也依然缓慢)。相关讨论:Primary Postgres database process (postmaster) eating all CPU - #5 by pfaffman
这些 Redis 警告是否与问题有关?它们在应用重建期间显示:
# 警告:无法强制实施 TCP backlog 设置为 511,因为 /proc/sys/net/core/somaxconn 被设置为更低的值 128。
# 警告:您的内核已启用透明大页(THP)支持。这会导致 Redis 出现延迟和内存使用问题。要修复此问题,请以 root 身份运行命令 'echo never > /sys/kernel/mm/transparent_hugepage/enabled',并将其添加到 /etc/rc.local 中,以便在重启后保留该设置。禁用 THP 后必须重启 Redis。
有人解决过 Docker 安装中的这些错误吗?
我已经将 vm.overcommit_memory = 1 添加到 /etc/sysctl.conf 中,以修复内存过度分配警告。
所以我通过以 root 身份运行 echo never > /sys/kernel/mm/transparent_hugepage/enabled 解决了 Transparent Huge Pages (THP) 警告。我还没有将其添加到 rc.local 以实现持久化,目前仅用于测试。我执行了 Discourse 重建,性能大致相同——可能略有提升。
不过,我不太确定如何修复这个警告:
# 警告:无法强制执行 TCP backlog 设置 511,因为 /proc/sys/net/core/somaxconn 被设置为较低的 128。
看到有些人说,即使系统值设置得更高(例如通过类似本指南的方式:https://www.techandme.se/performance-tips-for-redis-cache-server/),Docker 仍会使用 128 这个值。
我觉得将一些 UNICORN_SIDEKIQS 专门分配给低优先级队列可能是个好主意。
看起来像 PostAlert 这样的“默认”优先级任务执行得相当慢,一旦这些慢速的默认优先级任务积压起来,低优先级队列(其中的任务本可以以显著更快的速度完成)就会急剧膨胀,因为几乎没有任何任务被完成。我怀疑这种膨胀会导致所有任务的总体队列处理速度变慢。我认为这或许也能解释每秒作业数量的大幅波动。
有人知道是否可以在 app.yml 文件(或其他方式)中将 UNICORN_SIDEKIQS 分配给特定的优先级任务吗?
Falco
(Falco)
20
在数据库成为瓶颈的情况下增加 Sidekiq 只会让情况变得更糟。
正如我上面所说,你需要调试 PostgreSQL 性能不佳的问题。