課題:なぜ1GB〜2GB RAMのVPSは頻繁にダウンするのか?
1GB〜2GB RAMの低スペックVPSでWordPressやTelegramボット、いくつかのDockerコンテナを動かしていると、トラブルが頻繁に発生しがちです。通常通り動作していたはずのサーバーで突然SSHが切断され、Nginxは502 Bad Gatewayを返し、MySQLプロセスは何の前触れもなく消失してしまいます。
この主な原因は、LinuxカーネルのOOM(Out Of Memory)Killerにあります。物理RAMが枯渇すると、OOM KillerはOS全体の停止を防ぐために介入し、最も多くのメモリを消費しているプロセス(通常はMySQLやPostgreSQLなどのデータベース)を自動的に強制終了(kill)します。
多くのクラウド/VPS事業者(DigitalOcean、Hetzner、Linodeなど)は、共有ストレージクラスタへのI/O負荷を軽減するために、初期状態でSwapパーティションを作成していません。その結果、急激なトラフィック増や負荷上昇が発生した際にバッファ領域がなく、即座にサーバーがダウンしてしまいます。毎月数ドルの追加コストを払ってVPSプランをアップグレードする前に、インメモリ圧縮技術であるzRAMとディスク上のSwapファイルを組み合わせた2層メモリモデルを導入してみましょう。
技術的背景:ディスクSwapとzRAMの比較
これら2つのメカニズムの違いを正しく理解することで、単なるコマンドのコピペではなく、適切なパラメータチューニングが可能になります。
1. 従来のSwap(ディスクSwap)
ディスクSwapは、SSDやNVMe上に作成されたファイルまたはパーティションです。RAMが不足すると、カーネルは非アクティブなメモリページ(inactive pages)をディスクに退避させ、実行中のアプリケーション用の空き領域を確保します。
- メリット: 容量の柔軟性が高く低コスト。ピーク時のサーバークラッシュを防ぐフェイルセーフとして機能します。
- デメリット: 一般的なNVMe SSDの帯域幅(約1,500〜3,500 MB/s)であっても、物理RAMの帯域幅(通常20,000 MB/s以上)に比べると大幅に低速です。RAM枯渇が常態化するとスラッシング(swap thrashing)が発生し、
iowaitが70%〜90%に跳ね上がり、CPUがボトルネックになってWebリクエストがタイムアウトします。
2. zRAM(リアルタイム圧縮メモリ)
zRAMは、物理RAM上に仮想ブロックデバイスを作成する機能です。ここに送られたデータは、ZSTDやLZ4などの高速アルゴリズムによってリアルタイムに圧縮されます。
例えば、VPSで1GBの一時データを保持する必要がある場合、SSDに書き出す代わりに、カーネルがzRAM経由で約350MB〜400MB(圧縮率約2.5:1)に圧縮してRAM内に保持します。わずか2%〜5%程度のCPUリソースを消費するだけで、実質的に利用可能なメモリ容量を約2倍に増やすことができます。
- メリット: 物理RAMと同等の極めて高速なアクセス速度。SSDへの書き込み回数を大幅に削減し、ドライブの寿命を延ばします。
- デメリット: 物理RAMの一部を消費し続けるほか、データの圧縮・展開時に一定のCPU処理能力を必要とします。
優先度(Priority)による階層化モデル
Linuxカーネルは、priフラグを通じて各Swapデバイスに優先順位を設定する機能を備えています。
- 第1層(Priority 100 – zRAM): システムは即応性を維持するため、アイドル状態のデータをまず圧縮領域であるzRAMに優先して送ります。
- 第2層(Priority -2 – ディスクSwap): 物理RAMとzRAMの両方が満杯になった場合にのみ、OOM Killerの発動を防ぐ最後の防波堤としてSSD上のSwapファイルへデータを退避させます。
Ubuntu Serverでのセットアップ手順
以下の手順は、sudo権限を持つアカウントを使用し、Ubuntu Server(20.04、22.04、24.04 LTS対応)上で実行します。
ステップ1: 現在のメモリ状態の確認
まず、システムの現在のメモリ構成を確認します。
free -h
swapon --show
Swapの行が0Bと表示され、swapon --showの出力が空の場合、サーバーにはSwapメモリが一切設定されていません。
ステップ2: SSD上にバックアップ用Swapファイルを作成
1GB〜2GB RAMのサーバーでは、緊急退避用として2GBのSwapファイルを作成するのが適切です。
ファイルの割り当てとパーミッションの設定を行います:
# fallocateを使用して2GBのファイルを迅速に作成
sudo fallocate -l 2G /swapfile
# rootのみが読み書きできるように権限を制限
sudo chmod 600 /swapfile
# Swap領域としてフォーマット
sudo mkswap /swapfile
# システムで即座に有効化
sudo swapon /swapfile
サーバー再起動時にも自動でマウントされるよう、/etc/fstabに設定を追記します:
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
ステップ3: zRAMのインストールと構成
Ubuntuの公式リポジトリからzram-toolsパッケージをインストールします:
sudo apt update
sudo apt install -y zram-tools
設定ファイルを編集します:
sudo nano /etc/default/zramswap
設定内容を以下のように編集します(行頭に#がある場合は削除してコメントアウトを解除してください):
# 圧縮アルゴリズム: 現代のCPUにおいて圧縮率と速度のバランスが最適なzstdを指定
ALGO=zstd
# zRAMのサイズ制限: 物理RAMの50%に設定
PERCENT=50
# ディスクSwapよりも高い優先度を設定
PRIORITY=100
ファイルを保存(Ctrl + O → Enter → Ctrl + X)し、zRAMサービスを再起動します:
sudo systemctl restart zramswap
ステップ4: sysctlによるカーネルパラメータの最適化
Linuxのデフォルト動作では、RAMが限界近くまで圧迫されてからSwapを開始します。しかしzRAMを導入している環境では、カーネルが早い段階から積極的に未使用データを圧縮するように設定し、重い処理用により多くの空きRAMを確保するのが理想的です。
専用のsysctl設定ファイルを新規作成します:
sudo nano /etc/sysctl.d/99-memory-tuning.conf
以下の設定内容を記述します:
# 未使用メモリページを早期かつ積極的にzRAMへ圧縮退避
vm.swappiness=100
# dentry/inodeキャッシュの解放圧力を下げ、ファイルキャッシュをRAM内に長く保持
vm.vfs_cache_pressure=50
# I/Oの滞留を防ぐため、ダーティデータを早めにディスクへフラッシュ
vm.dirty_background_ratio=5
vm.dirty_ratio=10
システムを再起動することなく、新しい設定値を即座に反映します:
sudo sysctl --system
ステップ5: 動作結果の検証
現在アクティブなSwapデバイスの一覧を確認します:
swapon --show
1GB RAMのVPSにおける実際の出力例は以下のようになります:
NAME TYPE SIZE USED PRIO
/dev/zram0 partition 485M 0B 100
/swapfile file 2G 0B -2
PRIOカラムから階層化アーキテクチャが正常に動作していることが確認できます。/dev/zram0の優先度は100であり、/swapfileの-2よりも遥かに高くなっています。これにより、LinuxはすべてのデータをまずzRAMに書き込み、この485MBのzRAM領域が満杯になったときにのみディスクSwapを使用します。
数時間運用した後、圧縮効率を次のコマンドで確認できます:
zramctl
詳細なメトリクスが表示されます:
NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram0 zstd 485M 180M 65M 72M 1 [SWAP]
上記の例では、180MBの元データ(DATA)が圧縮後にわずか65MBの実際の物理RAM(COMPR)に収まっており、約2.8倍の圧縮率を達成しています。
まとめ
わずか数分の設定作業で、速度を担保するzRAMとメモリ枯渇を防ぐSwapファイルという、堅牢な2層バッファ機構を構築できました。これは低スペックなLinuxサーバーを運用する上で不可欠な最適化手法であり、システムの安定稼働を実現し、メモリ不足によるサービス停止を根本から解消します。
