💵

AlmaLinux 9 のサーバが時々長時間応答しなくなる原因が (たぶん) dnf makecache だった

2024/11/20に公開

先にまとめ

AlmaLinux 9 ではデフォルトで 1-2h 毎に dnf makecache が実行される。この処理はメモリを 1GB 以上使う可能性があり、メモリが足りている場合は数秒で終了するが、不足している場合はスワップアウトが発生し、著しくサーバのパフォーマンスを低下させる場合がある。

これを回避するには systemctl stop dnf-makecache.timer && systemctl disable dnf-makecache.timer で定期実行を停止し、必要に応じて microdnfdnf5 の採用を検討する。

経緯

EC2 で運用している AlmaLinux 9 のサーバが数週間に 1 回程度 HTTP や SSH に応答しなくなり、再起動が必要だったり、1 時間程度かかって復旧するという現象に悩まされていた。

状況はこんな感じ↓

  • zabbix によりメモリや CPU の監視をしていたが、応答しない期間はデータが取れず、その前後でもリソースの変化がほとんどない。
  • ログもその期間はほとんど出力されていない。cron の実行を遅延したログくらい。
  • この現象の調査のために、1 分ごとに CPU / メモリ / IO / ネットワークの使用量の多いプロセスを記録するスクリプトを作成して実行していたが、これも応答がない期間はログが取れず (cron で実行をスケジュールしていたが実行が遅延された)、前後でも多くのリソースを使っているプロセスがなかった。

と、とにかくログがないので調査に難航していたが、何度かこれを繰り返しているうちに応答がなくなる前の /var/log/messages に dnf のログがよくある事に気付いた。

# 時間・IP アドレスは適当に加工、コメントを追加
Nov 14 11:13:33 ip-x-x-x-x dnf[4066440]: AlmaLinux 9 - AppStream                         5.9 kB/s | 4.2 kB     00:00
Nov 14 11:13:34 ip-x-x-x-x dnf[4066440]: AlmaLinux 9 - BaseOS                            6.4 kB/s | 3.8 kB     00:00
Nov 14 11:13:34 ip-x-x-x-x dnf[4066440]: AlmaLinux 9 - Extras                            6.1 kB/s | 3.8 kB     00:00
Nov 14 11:13:35 ip-x-x-x-x dnf[4066440]: Extra Packages for Enterprise Linux 9 - x86_64   25 kB/s | 9.3 kB     00:00
Nov 14 11:13:37 ip-x-x-x-x dnf[4066440]: Extra Packages for Enterprise Linux 9 - x86_64   12 MB/s |  23 MB     00:01
# この時点から応答なし
# 再起動
Nov 14 12:13:25 ip-x-x-x-x kernel: The list of certified hardware and cloud instances for Red Hat Enterprise Linux 9 can be viewed at the Red Hat Ecosystem Catalog, https://catalog.redhat.com.

同様のログは平時に何度も出力されていたので、無関係だと思っていたが、調べてみることにした。

/var/log.dnf.log をみると dnf makecache --timer というコマンドで実行されているようだ。

2024-11-14T11:13:32+0900 DDEBUG Command: dnf makecache --timer

cron の設定を探しても該当するものが無かったが、systemd を使ったサービス dnf-makecache.timer で実行しているようだった。設定ファイルは下記の通りで、OS 起動後 10min 後に初回の実行、その後 1h 経ったら最大 60min のディレイを入れて実行を繰り返すようだ。

$ systemctl cat dnf-makecache.timer
# /usr/lib/systemd/system/dnf-makecache.timer
[Unit]
Description=dnf makecache --timer
ConditionKernelCommandLine=!rd.live.image
# See comment in dnf-makecache.service
ConditionPathExists=!/run/ostree-booted
Wants=network-online.target

[Timer]
OnBootSec=10min
OnUnitInactiveSec=1h
RandomizedDelaySec=60m
Unit=dnf-makecache.service

[Install]
WantedBy=timers.target

dnf makecache は dnf のパッケージのメタデータを更新するコマンド。そんなに負荷の高い処理には思えなかったが実際に実行してみることにした。

dnf clean all && dnf makecache でキャッシュをクリアして実行。実行時間は 18s 程度だったが、 vmstat 1 で監視していたところ、スワップアウトが発生していた。実行前 Available memory (free + cache) が 900MB ほどあるので 1GB 以上使っていそう。

$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0  73728 690324      0 232544    0    0     0   357  146  188  0  0 100  0  0
 1  0  73728 690072      0 232564    0    0    52    44  688  453 11  2 83  0  3
 1  0  73728 660588      0 243472   48    0    97  8496 1911  778 23  4 66  0  7
 2  0  73728 641624      0 243492    0    0     0     8 1192  238 40  2 50  0  8
 0  0  73728 657500      0 251160    0    0     4     0  778  182 23  1 72  0  4
 0  0  73728 646664      0 256200    0    0     4  2380 1403  484 28  2 69  1  2
 0  0  73728 646664      0 256392    0    0    77    48  666  373 11  0 88  0  1
 1  0  73728 610652      0 279744    0    0    25 23468 5407 1010 33  6 57  2  4
 1  0  73728 571400      0 287624    0    0     0     0 1127  139 47  2 50  0  2
 1  0  73728 518468      0 287680    0    0     0     0 1124  133 46  1 50  0  2
 1  0  73728 498056      0 287680    0    0     0     0 1145  123 48  1 50  0  2
 1  0  73728 528544      0 298516    0    0     0     8 1100  125 48  2 50  0  0
 1  0  73728 512268      0 305396    0    0     0     0 1109  118 47  3 50  0  0
 2  0  73728 186256      0 305464    0    0     0     0 1171  139 36  6 50  0  9
 2  0 138240 728832      0 189260   52 64572  3540 104860 9101 1047 30 22 34  1 13
 1  0 138240 656840      0 243356    0    0 34156     0 1496  231 35  2 50  2 13
 2  0 138240 690664      0 253480   12    0  4908  5872 1534  623 30  3 49  8 10
 0  0 138240 788720      0 254408  120    0  1060     0  226  175  1  0 97  1  0
 0  0 138240 788216      0 255668    0    0  1440     0  280  293  0  0 99  0  1

おそらくほかのサービスがメモリを多く使っているときに dnf makecache が実行され、大量のスワップアウトが発生、著しくパフォーマンスが低下して応答しなくなったと推察した。

メモリがある程度足りていれば 1 分以内に完了するため、zabbix 等のメトリクスに現れにくかったようだ。

対処

"dnf makecache out of memory" で検索するといろいろ情報がヒットする。

No, 1 GB of RAM is not enough for package management of a Fedora based system
How to run DNF without going OOM on GCP e2-micro

下記は Fedora のフォーラムでの Packaging Team の方の 2022 年の投稿。対処として microdnf という dnf の軽量版を使うことを提案している。

The current design of the DNF package manager can cause it to use quite large amounts of memory (into the hundreds of megabytes) for most operations.
DNF operations use large amount of RAM and may fail in low-memory environments

microdnf はその後のアップデートで dnf5 という名前になり、Fedora 41 からはこれがデフォルトで採用されているようだ (参考1参考2)。

残念ながら 2024/11/20 現在、AlmaLinux 9 のリポジトリには dnf5 がない。microdnf の使用は検討中。
ひとまず dnf-makecache.timer の実行を停止することにした。

systemctl stop dnf-makecache.timer
systemctl disable dnf-makecache.timer

ちなみに RHEL のガイドには下記の記述がある。

dnf-makecache.timer は、パッケージメターデータを自動的に更新する必要がない場合に限り無効にします。
2.2. 無効にしても安全なサービスを選択するためのガイド | Red Hat Product Documentation

Discussion