Linuxスワップ管理:高負荷サーバーのためのSwapfile、swappiness、zSwapの最適化

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

64GBのRAMを搭載したサーバーにスワップが必要な理由

64GBものRAMがあるからといってスワップを無効にするのは、裏目に出ることが多い典型的な「最適化」の失敗例です。スワップは単にメモリが不足したときのための予備タンクではありません。Linuxカーネルのメモリ管理における中核的なコンポーネントです。これにより、3日間アクセスされていないバックグラウンドデーモンのようなアイドル状態のデータを、高速なRAMからディスクへと移動させることができます。これにより、アクティブなプロセスや重要なファイルシステムキャッシュのための空き容量が確保されます。

このセーフティネットがない状態は、Out of Memory (OOM) Killerとロシアンルーレットをしているようなものです。RAMの使用率が99%に達すると、カーネルはシステム全体のハングアップを防ぐためにプロセスを強制終了し始めます。通常、その対象となるのはMySQL、Java、Nginxといった最もリソースを消費しているプロセスです。データベースがクラッシュして503エラーが発生するよりは、一時的に100ミリ秒のレイテンシスパイクが発生する方がマシでしょう。SwapfileやzSwapのような最新の戦略を使えば、速度を犠牲にすることなくこのセーフティネットを維持できます。

柔軟なSwapfileのセットアップ

専用のディスクパーティションのことは忘れましょう。稼働中の本番サーバーでパーティションのサイズを変更するのはリスクが伴います。現在ではSwapfileが業界標準となっています。パーティションと同等のパフォーマンスを提供しながら、テキストファイルと同じくらい簡単にサイズ変更や削除ができるからです。

Swapfileの作成

まずはスペースの割り当てから始めます。サーバーのRAMが4GB未満の場合は、スワップサイズをRAMと同じにします。より大きなシステムでは、通常2GBから4GBの固定バッファで十分です。標準的なUbuntuノードで4GBのSwapfileを設定する方法は次の通りです:

# fallocateを使用して即座に割り当て
sudo fallocate -l 4G /swapfile

# 古いXFSファイルシステムでfallocateが失敗する場合はddを使用:
# sudo dd if=/dev/zero of=/swapfile bs=1M count=4096

パーミッションの設定を忘れないでください。メモリから直接取得された機密データが含まれることが多いため、rootユーザーのみがこのファイルを読み取れるようにする必要があります。

sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

スワップの永続化

手動での有効化は再起動後には保持されません。変更を永続的にするには、ファイルシステムテーブル(/etc/fstab)を更新する必要があります。入力ミスがあるとサーバーが起動しなくなる可能性があるため、必ず事前にこのファイルをバックアップしてください。

# 安全のためにバックアップを作成
sudo cp /etc/fstab /etc/fstab.bak

# エントリを追記
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

微調整:swappinessとキャッシュプレッシャー

標準的な Linuxディストリビューションは、デスクトップ向けのデフォルト設定で出荷されています。カーネルパラメータのvm.swappinessは、システムがどの程度積極的にデータをディスクに移動させるかを制御します。デフォルトは通常60ですが、これはほとんどのサーバーにとって積極的すぎます。

vm.swappinessの調整

値の範囲は0から100です。データベース負荷の高いワークロードの場合、これを10または1に設定します。これにより、カーネルに対して「どうしても必要な場合のみディスクを使用せよ」と指示します。これにより、アプリケーションの実行よりもデータのやり取りに時間を費やしてしまう「スラッシング(thrashing)」状態を防ぐことができます。

# 現在の設定を確認
cat /proc/sys/vm/swappiness

# テスト用に一時的な修正を適用
sudo sysctl vm.swappiness=10

VFSキャッシュプレッシャー

ファイルシステムの速度は、しばしばvm.vfs_cache_pressureに依存します。これは、カーネルがディレクトリやinodeデータをどのくらいの期間メモリに保持するかを決定します。私の本番ノードでは、これを100から50に下げています。これによりファイルのメタデータがより長くキャッシュされ、ディレクトリの走査やファイルの検索が高速化されます。

これらの変更を永続的にするには、/etc/sysctl.confに追加します:

vm.swappiness=10
vm.vfs_cache_pressure=50

zSwapによるさらなる高速化

zSwapはパフォーマンス向上のための隠れた名機能です。スワップのための圧縮ライトバックキャッシュとして機能します。メモリページを直接低速なSSDに送る代わりに、zSwapはそれを(多くの場合3:1の比率で)圧縮し、RAM内の小さなプールに保持します。

ディスクI/Oは究極のボトルネックです。カーネルパラメータの調整と同様、zstd圧縮のためにわずかなCPUサイクルを使用することで、ディスクへの書き込みによる大幅なレイテンシを回避できます。4GBのVPSインスタンスでトラフィックが急増した際、ディスク待機時間が15%短縮されたのを確認しました。最も古いページは、圧縮プールがいっぱいになったときにのみ、実際のSwapfileに送られます。

カーネルのサポートを確認します:

grep -i zswap /boot/config-$(uname -r)

起動時に有効にするには、GRUBの設定を編集します。zstd圧縮を使用し、プールを合計RAMの25%に制限することをお勧めします。

# /etc/default/grubを編集
# GRUB_CMDLINE_LINUX_DEFAULTを更新して以下を含める:
# zswap.enabled=1 zswap.compressor=zstd zswap.max_pool_percent=25

sudo update-grub

確認とリアルタイムモニタリング

設定は確認しなければ意味がありません。swapon --showを使用してステータスを素早くチェックしましょう。どのファイルがアクティブで、現在の使用状況はどうなっているかが正確にわかります。

swapon --show
# 名前      タイプ サイズ 使用中 優先度
# /swapfile file  4G   1.2G -2

システムがスラッシングを起こしている疑いがある場合は、vmstat 2を実行します。si(スワップイン)とso(スワップアウト)の列に注目してください。これらの数値が数秒以上にわたって継続的に高い場合は、RAMの増設が必要か、ワークロードに対してswappinessがまだ高すぎる可能性があります。

圧縮によって実際にどれだけのメモリが節約されているかを確認するには、カーネルのデバッグ統計をチェックします:

sudo grep -r . /sys/kernel/debug/zswap/

スワップの最適化はバランスが重要です。適切なサイズのSwapfile、調整されたカーネルパラメータ、そしてzSwap圧縮を組み合わせることで、極限の負荷状況下でもサーバーの安定性を維持できます。これは、1メガバイトが重要となる場面でサービスをオンラインに保つための、非常に効果的な最適化です。

Share: