Linuxを高速化:tmpfsで「ホット」データをRAMに配置してI/Oを最適化する

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

NVMe SSDでも不十分なとき

ダッシュボードを確認すると、CPU負荷は低く、RAMも数十GB空いているのに、アプリケーションのレスポンスが遅いと感じることはありませんか?もし top コマンドで %wa (I/O Wait) が頻繁に10-15%を超えているなら、システムはストレージがボトルネックになっています。

実際、最高性能のNVMe SSDであっても、レイテンシ(遅延)は約10~100マイクロ秒です。対して、RAMのレイテンシはわずか数十~100ナノ秒程度です。つまり、RAMはストレージよりも100倍から1,000倍高速です。一時的なデータの書き込みが頻繁に発生するタスクにおいて、ストレージにその処理を強いるのは、リソースの莫大な浪費と言えます。

以前、私が毎秒数千セッションを処理するCentOS 7のサーバークラスターを管理していた際、ディスクI/Oが常に上限に達して頭を抱えていました。その時の解決策は非常にシンプルかつ効果的なものでした。それが tmpfs です。PHPセッションをディスクに書き込む代わりに、それらを直接RAMに展開したのです。

tmpfs:柔軟な仮想メモリ

tmpfsは、仮想メモリ(Virtual Memory)上に直接データを保存するファイルシステムです。最初から固定の容量を確保するわけではありません。例えば2GBでマウントしても、実際に100MBしか使用していなければ、システムが消費する物理RAMは100MBのみです。

よくtmpfsと ramfs が混同されますが、大きな違いがあります。ramfsは書き込みすぎると際限なく肥大化し、最終的にシステムをフリーズ(カーネルパニック)させます。一方、tmpfsはサイズ制限(size limit)を設定でき、物理RAMが不足した場合にはデータをSwap領域に逃がすことができます。これにより、本番環境での安全性が格段に高まります。

30秒でできるtmpfsの設定

Ubuntu、DebianからRHEL/CentOSまで、主要なディストリビューションのカーネルにはtmpfsが組み込まれています。追加のパッケージをインストールする必要はありません。

1. テスト用のクイックマウント

一時的なファイル処理のために1GBのスペースが必要な場合は、以下のコマンドを実行します。

sudo mkdir -p /mnt/ramdisk
sudo mount -t tmpfs -o size=1G tmpfs /mnt/ramdisk

df -h コマンドで結果を確認してください。非常に高速なアクセスが可能な新しいパーティションが表示されるはずです。

2. /etc/fstabによる永続的な設定

再起動後も自動的にマウントされるようにするには(NginxのキャッシュやPHPセッションに重要)、システム設定ファイルを編集します

sudo nano /etc/fstab

ファイルの末尾に以下の行を追加します。

tmpfs   /mnt/ramdisk   tmpfs   rw,nodev,nosuid,size=2G   0   0

セキュリティパラメータの解説:

  • nodev: パーティション上でのデバイスファイルの作成を禁止します。
  • nosuid: SUID権限を持つファイルの実行をブロックし、権限昇格のリスクを低減します。
  • size=2G: 最大容量の制限です。サーバーのRAM容量に合わせて size=50% のように割合で指定することも可能です。

sudo mount -a を実行すれば、再起動なしですぐに適用されます。

実践的な活用例:数字で見る効果

「なんとなく速そう」という理由だけでtmpfsを使うのではなく、以下のような「ホットスポット(負荷集中箇所)」に適用しましょう。

Webサーバー(Nginx/PHP)の高速化

デフォルトでは、PHPはセッションを /var/lib/php/sessions に保存します。1,000人のユーザーが同時アクセスすると、ストレージに対して毎秒数千回の細かな読み書きが発生します。このディレクトリをtmpfsに移行すると、Webサイトのレスポンス遅延(TTFB)が200msから50ms以下に短縮されることがあります。

# /etc/fstabに追加
tmpfs   /var/lib/php/sessions   tmpfs   rw,nodev,nosuid,size=512M   0   0

メディア処理時のSSD寿命保護

FFmpegで動画を変換したり、ImageMagickで画像をリサイズしたりする場合、中間の一時ファイルがSSDの寿命を激しく削ります。一時出力先をRAMに指定しましょう。

import subprocess

# tmpfsがマウントされているディレクトリ
temp_path = "/mnt/ramdisk/output.mp4"
subprocess.run(["ffmpeg", "-i", "input.mov", temp_path])

監視と「血の教訓」とも言える注意点

tmpfsは非常に快適ですが、油断すると痛い目を見ます。RAMパーティションがいっぱいになると、アプリケーションは「No space left on device」というエラーを吐き、即座にクラッシュします

以下のコマンドで定期的に容量を監視することをお勧めします:

watch -n 5 df -h /mnt/ramdisk

必ず覚えておくべき3つのルール:

  1. データは消失する: 停電や再起動が発生すると、tmpfs上のデータはすべて消えます。データベースの本体や重要なソースコードは絶対にここに置かないでください。
  2. OOM(メモリ不足)を避ける: 他のサービスが稼働しているサーバーでは、tmpfsにRAMの50%以上を割り当てないようにしましょう。RAMが枯渇すると、カーネルがOOM Killerを発動し、MySQLやNginxなどのプロセスを強制終了させます。
  3. 適切な権限設定: /tmp として使用する場合は、安全のためにスティッキービット(権限 1777)を設定してください: chmod 1777 /mnt/ramdisk

tmpfsの活用は、新しいハードウェアを購入することなくサーバーのパフォーマンスを向上させる、最も安価で効果的な方法です。システムの最適化が成功することを願っています!

Share: