ハイエンドハードウェアに潜む隠れたボトルネック
数年前、私はトラフィックの多い12台のWebノードクラスターをデプロイしました。スペック上は、デュアルEPYCプロセッサ、256GBのRAM、NVMeストレージという強力な構成でした。しかし、最初のトラフィック急増時に、p99レイテンシが500msまで跳ね上がりました。ログにアプリのエラーは出ておらず、システムが悲鳴を上げている状態でした。OSが、高コンカレンシーなWebトラフィックではなく、一般的な安定性を重視した「汎用的な」設定で動作していたため、リソースを使い切れずに窒息していたのです。
標準的なLinuxディストリビューションは、保守的なデフォルト設定で出荷されます。これらの設定は、Raspberry Piから128コアのサーバーまで、あらゆる環境で確実に起動することを保証しますが、ハードウェア의潜在能力を最大限に引き出すことは稀です。負荷の高いPostgreSQLインスタンスや、多忙なNginxプロキシでこれらのデフォルト設定のまま運用していると、本来発揮できるパフォーマンスの20〜30%を無駄にしていることになります。
なぜ手動チューニングは大規模環境で失敗するのか
古くからある解決策は、/etc/sysctl.confや/etc/security/limits.confをあちこち編集することです。時には、/sys/block/内のディスクスケジューラを直接操作することもあるでしょう。この方法は1台のサーバーなら機能しますが、50台規模のフリートでは運用の悪夢となります。メンテナンスされていないBashスクリプトが起動時に古いカーネルパラメータを適用したことで、原因不明のパフォーマンス問題が発生し、DevOpsチームが何日もデバッグに追われる姿を私は見てきました。
システムチューニングは「一度設定すれば終わり」というタスクではありません。データベースには高いディスクスループットとヒュージページが必要です。逆に、仮想化ホストは多数のゲスト間でCPUサイクルをバランスよく配分する必要があります。これらの値をハードコードしてしまうと、インフラが硬直化し、ハードウェアのアップグレードやワークロードの変化に適応できなくなります。
適切な最適化戦略の選択
解決策に入る前に、多くのチームがどのように最適化を処理しているかを見てみましょう。
- 静的スクリプト: 作成は簡単ですが危険です。ハードウェアの変化を検知しないため、SSD向けに最適化されたスクリプトが、古いIOスケジューラを適用することでNVMeドライブの性能を誤って低下させてしまう可能性があります。
- 構成管理ツール (Ansible/Terraform): 一貫性の維持には優れています。しかし、特定のユースケースごとに何百ものカーネル変数を手動で調査し、維持し続ける必要があります。
- Tuned: 動的な適応デーモンです。複雑な設定を「プロファイル」としてグループ化し、実際のシステム負荷に基づいてパラメータを動的に調整できます。
私がTunedを好むのは、パフォーマンスを「面倒な作業」ではなく「ポリシー」として扱えるからです。データベースのためにvm.swappinessを10にすべきだと暗記する代わりに、システムに「君はデータベースサーバーだ」と伝えるだけで済みます。あとはTunedがすべて処理してくれます。
Tunedの実装:実践ガイド
Tunedは、sysctl設定、電力状態、CPUガバナー、ディスクスケジューリングを単一の統合インターフェースで管理します。これは Linux最適化における「お手軽ボタン」です。
1. インストールとサービスのセットアップ
AlmaLinuxやRocky LinuxなどのRHELベースのシステムでは、通常Tunedはプリインストールされています。UbuntuやDebianユーザーの場合は、リポジトリから取得する必要があります。
# Ubuntu/Debianの場合
sudo apt update && sudo apt install tuned -y
# AlmaLinux/CentOS/Fedoraの場合
sudo dnf install tuned -y
# サービスを起動
sudo systemctl enable --now tuned
現在のステータスをtuned-adm activeで確認します。ほとんどのシステムはデフォルトでbalancedになっています。これはラップトップには適していますが、本番サーバーとしては平均的な設定です。
2. データベースワークロードの強化
MySQLやPostgreSQLなどのデータベースは、メモリの安定性とディスクI/Oが命です。OSが節電のためにCPUのクロックを下げたり、アイドル時にメモリをディスクにスワップしたりすると、パフォーマンスが低下します。
これらのマシンには、throughput-performanceプロファイルを使用します。これにより、CPUがハイパフォーマンスガバナーに固定され、積極的な省電力機能が無効になります。
# 利用可能なプロファイルを確認
tuned-adm list
# パフォーマンス設定を適用
sudo tuned-adm profile throughput-performance
このコマンド1つで、dirty_ratio(ディスクに書き出す前にメモリに保持できるデータ量)が調整され、データベースエンジンが必要な瞬間にすべてのCPUサイクルを確保できるようになります。
3. 高コンカレンシーWebサーバーのチューニング
Webサーバーは、数千もの短寿命なTCP接続を処理します。ここでは、マイクロレイテンシが敵となります。負荷の高いNginxロードバランサーでは、network-latencyプロファイルに切り替えることで、テイルレイテンシを大幅に削減できます。
sudo tuned-adm profile network-latency
このプロファイルは、Webアプリで予測不能な「しゃっくり(一時的な停止)」を引き起こす可能性がある透過的ヒュージページ(Transparent Huge Pages)を無効にし、ネットワークスタックがパケットをより速く処理できるように微調整します。私のテストでは、毎秒5,000リクエストを処理するノードで、p99レスポンスタイムが15%改善されました。
4. 仮想化ホスト vs ゲスト
KVMやQEMUを実行する場合、ホストとゲストでは求めるニーズが異なります。ホストは仮想ディスクイメージのI/Oを優先する必要があり、ゲストは冗長なクロックサイクルを避けるために、自分が仮想化環境で動作していることを認識する必要があります。
物理ホスト側:
sudo tuned-adm profile virtual-host
仮想マシン内部:
sudo tuned-adm profile virtual-guest
virtual-hostプロファイルはmax_map_countを増やし、ハイパーバイザーがゲスト用の大量のメモリをクラッシュさせることなく管理できるようにします。
カスタムプロファイルの作成
時にはハイブリッドなアプローチが必要になることもあります。Tunedでは、既存のプロファイルから設定を「継承」するカスタムプロファイルを作成できます。たとえば、throughput-performanceをベースにしつつ、特定のネットワーク制限を強制したい場合は、/etc/tuned/にディレクトリを作成します。
sudo mkdir /etc/tuned/app-specific
sudo nano /etc/tuned/app-specific/tuned.conf
設定ファイルにロジックを追加します:
[main]
summary=高コンカレンシーなNode.jsアプリ向けに最適化
include=throughput-performance
[sysctl]
net.core.somaxconn=8192
vm.swappiness=5
[sysfs]
/sys/kernel/mm/transparent_hugepage/enabled=never
他のプロファイルと同様に有効化します:sudo tuned-adm profile app-specific
検証:勘に頼らない
500以上のLinuxインスタンスを管理してきた経験から学んだのは、測定のない最適化はただの推測に過ぎないということです。変更は必ず検証してください。本番環境のクラッシュから復旧するのに10時間費やすよりも、テストに10分かけるほうが賢明です。
- ベースライン: 変更を加える前に、CPU/ディスクには
sysbench、HTTPトラフィックにはwrkを実行します。 - 適用:
tuned-admを使用してプロファイルを切り替えます。 - 監視:
htopやiostat -xz 1を使用して、負荷時のI/OウェイトやCPUスパイクを監視します。 - 確認: 実際のカーネル値を確認します。たとえば、
cat /proc/sys/vm/swappinessを実行して、変更が反映されているか確認します。
Tunedは、パフォーマンス最適化を「職人芸」から「再現可能なプロセス」へと変えてくれます。もし、いまだに複数のサーバーで手動でsysctlファイルをいじっているのなら、今すぐやめましょう。低レベルの単調な作業はTunedに任せ、より優れたアーキテクチャの構築に集中してください。

