メモリ使用量の削減
GitLab Railsアプリケーションコードはメモリリークに悩まされています。ウェブリクエストの場合、この問題は監視スレッドを使うことで対処可能です。このスレッドは、ワーカーが与えられた常駐セットサイズ(RSS) のしきい値を一定時間超えると自動的に再起動します。GitLabがバックグラウンドジョブを処理するために使うSidekiqプロセスにも同じアプローチを使います。
GitLabは、LinuxパッケージまたはDockerインストールに対してのみ、デフォルトで利用可能なRSSの上限を監視します。その理由は、GitLabはメモリによるシャットダウン後にSidekiqを再起動するためにrunitに依存しており、セルフコンパイルやHelmチャートのインストールではrunitや同等のツールを使用しないためです。
デフォルトの設定では、Sidekiqは15分に1回以上の頻度で再起動することはなく、再起動は着信バックグラウンドジョブに約1分の遅延を引き起こします。
バックグラウンドジョブの中には、長時間稼働する外部プロセスに依存しているものがあります。Sidekiqの再起動時にこれらのプロセスを確実に終了させるため、各Sidekiqプロセスはプロセスグループリーダーとして実行する必要があります(たとえば、chpst -P
)。Linuxパッケージのインストールまたはrunit
がインストールされたbin/background_jobs
スクリプトを使用すると、この処理が行われます。
制限の設定
Sidekiqメモリ制限は、環境変数を使って制御されます。
-
SIDEKIQ_MEMORY_KILLER_MAX_RSS
(KB): は、許容RSSのSidekiqプロセスソフトリミットを定義します。SidekiqプロセスのRSS(キロバイトで表示)SIDEKIQ_MEMORY_KILLER_MAX_RSS
が、SIDEKIQ_MEMORY_KILLER_GRACE_TIME
をSIDEKIQ_MEMORY_KILLER_MAX_RSS
超える場合SIDEKIQ_MEMORY_KILLER_MAX_RSS
、グレースフル・リスタートがトリガーされます。SIDEKIQ_MEMORY_KILLER_MAX_RSS
設定されていないか、その値が0に設定されている場合、ソフトリミットは監視されません。SIDEKIQ_MEMORY_KILLER_MAX_RSS
デフォルトは2000000
。 -
SIDEKIQ_MEMORY_KILLER_GRACE_TIME
は、Sidekiqプロセスが許容RSSソフトリミットを超えて実行することを許可する猶予時間を秒単位で定義します。Sidekiqプロセスが許容RSS(ソフトリミット)をSIDEKIQ_MEMORY_KILLER_GRACE_TIME
下回った場合、再起動は中断されます。デフォルト値は900秒(15分)です。 -
SIDEKIQ_MEMORY_KILLER_HARD_LIMIT_RSS
(KB): 許容RSSのSidekiqプロセスハードリミットを定義します。SidekiqプロセスのRSS(キロバイトで表示)SIDEKIQ_MEMORY_KILLER_HARD_LIMIT_RSS
が、この値をSIDEKIQ_MEMORY_KILLER_HARD_LIMIT_RSS
超えるとSIDEKIQ_MEMORY_KILLER_HARD_LIMIT_RSS
、Sidekiqのグレースフル・リスタートが即座に実行されます。この値が設定されていないか、0に設定されている場合、ハードリミットは監視されません。 -
SIDEKIQ_MEMORY_KILLER_CHECK_INTERVAL
: プロセスRSSをチェックする頻度を定義します。デフォルトは3秒です。 -
SIDEKIQ_MEMORY_KILLER_SHUTDOWN_WAIT
すべてのSidekiqジョブが終了するまでの最大時間を設定します。この間、新しいジョブは受け付けられません。デフォルトは30秒です。プロセスの再起動がSidekiqによって実行されない場合、Sidekiqプロセスは、Sidekiqシャットダウンタイムアウト(デフォルトは25秒)+2秒後に強制終了されます。その間にジョブが終了しない場合、Sidekiqプロセスに
SIGTERM
シグナルが送信され、現在実行中のすべてのジョブが中断されます。 -
GITLAB_MEMORY_WATCHDOG_ENABLED
デフォルトで有効。GITLAB_MEMORY_WATCHDOG_ENABLED
ウォッチドッグの実行を無効にするには、falseにGITLAB_MEMORY_WATCHDOG_ENABLED
設定GITLAB_MEMORY_WATCHDOG_ENABLED
します。
ワーカーの再起動を監視
GitLab はメモリ使用量が多いためにワーカーが再起動されると、ログイベントを発行します。
以下は/var/log/gitlab/gitlab-rails/sidekiq_client.log
におけるログイベントの例です:
{
"severity": "WARN",
"time": "2023-02-04T09:45:16.173Z",
"correlation_id": null,
"pid": 2725,
"worker_id": "sidekiq_1",
"memwd_handler_class": "Gitlab::Memory::Watchdog::SidekiqHandler",
"memwd_sleep_time_s": 3,
"memwd_rss_bytes": 1079683247,
"memwd_max_rss_bytes": 629145600,
"memwd_max_strikes": 5,
"memwd_cur_strikes": 6,
"message": "rss memory limit exceeded",
"running_jobs": [
{
jid: "83efb701c59547ee42ff7068",
worker_class: "Ci::DeleteObjectsWorker"
},
{
jid: "c3a74503dc2637f8f9445dd3",
worker_class: "Ci::ArchiveTraceWorker"
}
]
}
どこに:
-
memwd_rss_bytes
は実際に消費されたメモリ量です。 -
memwd_max_rss_bytes
はper_worker_max_memory_mb
を通して設定された RSS の上限です。 -
running jobs
は、プロセスがRSS制限を超過し、グレースフル・リスタートを開始した時点で実行されていたジョブを一覧表示します。