Linuxのスワップディスク領域の設定と swappiness

1. スワップ領域の作り方
現状を確認する
sudo swapon --show
free -hswapon --show に何も表示されなければ、スワップは設定されていません。free -h の Swap: 行で合計と使用量を確認できます。
スワップファイルを作成する(2GB の例)
# 1. 領域を確保する
sudo fallocate -l 2G /swapfile
# 2. root 以外が読めないようにする(必須)
sudo chmod 600 /swapfile
# 3. スワップ領域としてフォーマットする
sudo mkswap /swapfile
# 4. 有効化する
sudo swapon /swapfile
# 5. 確認する
sudo swapon --showext4 であれば fallocate で問題ありません。ファイルシステムによって fallocate で作ったファイルを swapon が受け付けない場合は、dd で中身をゼロで埋めて作成します。
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progressbtrfs ではコピーオンライトの無効化など別の手順が必要になるため、ここでは扱いません。
再起動後も有効にする
/etc/fstab に次の1行を追加します。
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab追記する前に /etc/fstab のバックアップを取っておくと安全です。書き間違えると起動に影響することがあります。
スワップパーティションを使う場合
ファイルではなく専用パーティションを使う場合は、mkswap /dev/sdXN でフォーマットします。fstab にはデバイス名ではなく UUID を書くのが一般的です(UUID は blkid で確認できます)。最近は、サイズを後から変えやすいスワップファイルを選ぶ例が多いです。
サイズを変更する・削除する
sudo swapoff /swapfile # 無効化(中身は RAM に戻される)
sudo rm /swapfile # 削除する場合
# サイズを変える場合は、作成手順をやり直す削除する場合は、/etc/fstab に書いた行も消してください。swapoff を実行するときは、スワップ使用量より空きメモリ(available)が十分あることを確認してから行います。
サイズの目安
決まった正解はなく、用途によって変わります。
- RAM が小さい VPS(1〜2GB 程度)では、RAM と同程度を確保しておくと OOM の保険になります
- RAM が十分あるサーバーでは、数 GB 程度でも足りることが多いです
- ハイバネーション(休止状態)を使う場合は、RAM 以上のサイズが必要です
2. swappiness とは
vm.swappiness は、メモリを回収するときに次のどちらを優先して手放すかを決める重みです。
- ファイルキャッシュ:ファイルの内容をメモリに置いたもの。捨てても、ディスクから読み直せる
- 匿名メモリ:プロセスのヒープやスタックなど。手放すにはスワップへ書き出すしかない
値が高いほど匿名メモリをスワップへ出しやすくなり、低いほどキャッシュを先に捨てるようになります。
よくある誤解
「空きメモリが○%になったらスワップを始める閾値」という説明を見かけますが、これは誤りです。swappiness は回収が始まった後の配分を決める値で、スワップを始めるタイミングを決める値ではありません。
3. 60 と 10 の違い
カーネル 5.8 以降では、設定できる範囲は 0〜200 です。おおまかには「匿名メモリ : キャッシュ = swappiness : (200 − swappiness)」の比率で回収します。実際のカーネルは直近の I/O コストでこの比率を補正するので、あくまで目安です。
| 値 | 比率の目安 | 挙動 |
|---|---|---|
| 60(デフォルト) | 60 : 140 | キャッシュを多めに捨てつつ、使われていないプロセスのメモリもスワップへ出す |
| 10 | 10 : 190 | ほぼキャッシュだけを捨てる。スワップは本当に足りないときだけ使う |
| 100 | 100 : 100 | 両方を同じ重みで扱う |
| 0 | ― | 極力スワップしない(無効化ではない)。メモリが逼迫すると OOM Killer が動きやすくなる |
60 はキャッシュを残しやすいので、ファイル読み込みの多い処理に向いています。ただし、しばらく使われなかったプロセスが動き出すと、スワップから読み戻す遅延が出ることがあります。10 はプロセスのメモリを RAM に残しやすい一方、キャッシュが減るためディスク I/O が増える可能性があります。
4. 「空きがあるのにスワップを使っている」は異常か
多くの場合、異常ではありません。
- 一度スワップに出たページは、再びアクセスされるまでスワップに残り続けます。過去にメモリが逼迫したときに出されたページが残っているだけ、というケースがほとんどです
- 使われていないページを先にスワップへ出してキャッシュ用の RAM を確保するのは、60 では想定どおりの動作です
問題になるのは、スワップの出し入れが継続的に起きている状態(スラッシング)のときです。
5. 数値を決めるための確認手順
# スワップの出し入れを確認する(si/so がほぼ 0 なら問題なし)
vmstat 1 10
# 実際に使えるメモリは free 列ではなく available 列で見る
free -h
# どのプロセスがスワップに出ているかを確認する
for f in /proc/[0-9]*/status; do awk '/^Name|^VmSwap/{printf "%s ",$2} END{print ""}' $f; done 2>/dev/null | sort -k2 -n -r | head
# メモリ不足による待ち時間を確認する(PSI)
cat /proc/pressure/memoryスワップに出ているのが、あまり使われないデーモンであれば気にする必要はありません。MySQL や PHP-FPM など応答速度に直結するプロセスが出ているなら、swappiness を下げることを検討します。
用途別の目安
| 用途 | 目安 |
|---|---|
| DB サーバー、レイテンシ重視の API | 1〜10 |
| 一般的な Web サーバー | 30〜60 |
| 小メモリの VPS で応答速度を優先したい | 10〜20 |
| バッチ処理中心、デスクトップ | 60 のまま |
6. 設定を変更する
# 一時的に変更する(再起動で元に戻る)
sudo sysctl vm.swappiness=10
# 恒久的に変更する
echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --systemswappiness を下げても、すでにスワップにあるページは自動では RAM に戻りません。戻したい場合は、available に余裕があることを確認してから sudo swapoff -a && sudo swapon -a を実行します。