减少内存使用

极狐 GitLab 的 Sidekiq 内存杀手自动管理消耗过多内存的后台作业进程。这个功能监控工作进程,并在 Linux 内存杀手介入之前重新启动它们,从而允许后台作业在优雅关闭之前运行完成。通过记录这些事件,我们可以更容易地识别导致高内存使用的作业。

我们如何监控 Sidekiq 内存#

极狐 GitLab 仅在 Linux 软件包或 Docker 安装中默认监控可用的 RSS 限制。原因是极狐 GitLab 依赖 runit 在内存引发的关闭后重新启动 Sidekiq,而自编译和 Helm chart 安装不使用 runit 或等效工具。

使用默认设置,Sidekiq 的重启频率不超过每 15 分钟一次,重启会导致传入的后台作业大约一分钟的延迟。

一些后台作业依赖于长时间运行的外部进程。为了确保在 Sidekiq 重启时这些进程被清理干净,每个 Sidekiq 进程应该作为进程群组领导者运行(例如,使用 chpst -P)。如果使用 Linux 软件包安装或安装了 runitbin/background_jobs 脚本,这将自动处理。

配置限制#

Sidekiq 内存限制通过环境变量进行控制。

  1. SIDEKIQ_MEMORY_KILLER_MAX_RSS (KB): 定义 Sidekiq 进程允许的 RSS 软限制。如果 Sidekiq 进程的 RSS(以千字节表示)超过 SIDEKIQ_MEMORY_KILLER_MAX_RSS 超过 SIDEKIQ_MEMORY_KILLER_GRACE_TIME,将触发优雅重启。如果 SIDEKIQ_MEMORY_KILLER_MAX_RSS 未设置或其值设为 0,则不监控软限制。SIDEKIQ_MEMORY_KILLER_MAX_RSS 默认为 2000000

  2. SIDEKIQ_MEMORY_KILLER_GRACE_TIME: 定义允许 Sidekiq 进程在超过允许的 RSS 软限制的宽限时间(以秒为单位)。如果 Sidekiq 进程在 SIDEKIQ_MEMORY_KILLER_GRACE_TIME 内低于允许的 RSS(软限制),则重启将中止。默认值为 900 秒(15 分钟)。

  3. SIDEKIQ_MEMORY_KILLER_HARD_LIMIT_RSS (KB): 定义 Sidekiq 进程允许的 RSS 硬限制。如果 Sidekiq 进程的 RSS(以千字节表示)超过 SIDEKIQ_MEMORY_KILLER_HARD_LIMIT_RSS,将立即触发 Sidekiq 的优雅重启。如果该值未设置或设为 0,则不监控硬限制。

  4. SIDEKIQ_MEMORY_KILLER_CHECK_INTERVAL: 定义检查进程 RSS 的频率。默认为 3 秒。

  5. SIDEKIQ_MEMORY_KILLER_SHUTDOWN_WAIT: 定义允许 Sidekiq 作业完成的最大时间。在此期间不接受新作业。默认为 30 秒。

如果 Sidekiq 未执行进程重启,则在Sidekiq 关闭超时(默认为 25 秒)+2 秒后,Sidekiq 进程将被强制终止。如果作业在此期间未完成,所有当前运行的作业将通过向 Sidekiq 进程发送 SIGTERM 信号被中断。

  1. GITLAB_MEMORY_WATCHDOG_ENABLED: 默认启用。将 GITLAB_MEMORY_WATCHDOG_ENABLED 设置为 false,以禁用 Watchdog 的运行。

监控工作重启#

极狐 GitLab 会发出日志事件,如果工作因高内存使用而重新启动。

以下是 /var/log/gitlab/gitlab-rails/sidekiq_client.log 中这些日志事件的示例之一:

json
1{ 2 "severity": "WARN", 3 "time": "2023-02-04T09:45:16.173Z", 4 "correlation_id": null, 5 "pid": 2725, 6 "worker_id": "sidekiq_1", 7 "memwd_handler_class": "Gitlab::Memory::Watchdog::SidekiqHandler", 8 "memwd_sleep_time_s": 3, 9 "memwd_rss_bytes": 1079683247, 10 "memwd_max_rss_bytes": 629145600, 11 "memwd_max_strikes": 5, 12 "memwd_cur_strikes": 6, 13 "message": "rss memory limit exceeded", 14 "running_jobs": [ 15 { 16 jid: "83efb701c59547ee42ff7068", 17 worker_class: "Ci::DeleteObjectsWorker" 18 }, 19 { 20 jid: "c3a74503dc2637f8f9445dd3", 21 worker_class: "Ci::ArchiveTraceWorker" 22 } 23 ] 24}

其中:

  1. memwd_rss_bytes 是实际消耗的内存量。
  2. memwd_max_rss_bytes 是通过 per_worker_max_memory_mb 设置的 RSS 限制。
  3. running jobs 列出了进程在超过 RSS 限制并开始优雅重启时正在运行的作业。