問題の紹介:なぜサーバーパフォーマンスを最適化する必要があるのか?
Linuxサーバーを使い始めたばかりであれば、システムをスムーズかつ迅速に稼働させることがいかに重要であるかをすぐに理解するでしょう。特に、ユーザーやデータの量が増え始めるにつれて、その重要性は増します。サーバーの動作が遅いと、ユーザーエクスペリエンスが低下するだけでなく、顧客の喪失、サービスの中断、さらには金銭的損害といった深刻な問題を引き起こします。そのため、パフォーマンスの最適化は単なるスキルではありません。それは各システム管理者の責任でもあります。
ITに不慣れで、「サーバーパフォーマンス」という概念が複雑に思えますか?心配いりません!この記事は、各側面を理解し、すぐに適用できる詳細な実践手順を提供します。
中核概念:パフォーマンスとは何か、そしてボトルネック
最適化に着手する前に、Linuxサーバーのコンテキストにおける「パフォーマンス」が実際に何を意味するのかを理解する必要があります。サーバーのパフォーマンスは多くの要因で評価されますが、最も基本的なものは次のとおりです。
- Throughput(スループット):特定の期間に処理できるリクエストまたはデータの量(例:1秒あたりのトランザクション数)。
- Latency(レイテンシー):リクエストに応答するために必要な時間(例:Webページの読み込み時間)。
- Resource Utilization(リソース使用率):CPU、RAM、ディスクI/O、ネットワークなどのハードウェアリソースの使用レベル。
サーバーのパフォーマンスが低下する場合、それは通常、1つ以上のリソースが過負荷になり、いわゆる「ボトルネック」が発生しているためです。私たちの任務は、これらのボトルネックを見つけて修正することです。たとえば、RAMが大量に空いているにもかかわらずCPUが常に100%稼働している場合、CPUがボトルネックです。
実践的な詳細:Linuxサーバーパフォーマンス最適化の手順
1. 監視と分析:敵を知り己を知る
システムを最適化するための最初で最も重要なステップは、それを監視することです。測定できないものを改善することはできません。Linuxにはリソースを監視するための強力なツールが多数提供されています。
リソースの概要監視
topやhtop(topよりも人気があり機能豊富なツール)などのコマンドは、CPU、RAM、スワップ、および実行中のプロセスに関する概要を提供します。
htop
RAMとスワップの使用状況のみを表示するには:
free -h
ディスク容量を確認するには:
df -h
ディスクI/Oの監視
iostatは、ディスクのI/Oパフォーマンスを効率的にチェックするのに役立ちます:
iostat -x 1 10
このコマンドは、1秒ごとに詳細なI/Oレポートを10回繰り返して表示します。%util(デバイスの使用率)、r/s、w/s(1秒あたりの読み取り/書き込み数)、rkB/s、wkB/s(1秒あたりの読み取り/書き込みデータ量)などの重要な列に注目してください。特に、await列(I/O操作の平均待機時間)は非常に重要です。
iotopも、CPU/RAMのtopと同様に、どのプロセスが最も多くのI/Oを引き起こしているかを確認するのに非常に役立ちます:
iotop
ネットワークの監視
ss(netstatの現代的な代替)は、アクティブなネットワーク接続を表示するのに役立ちます:
ss -tulpn
このコマンドは、リスニング状態のTCP、UDPソケット、確立された接続のソケット、およびプロセス名を表示します。
ログの確認(システムログ)
ログファイルを決して無視しないでください!ログは、サーバーで何が起こっているかを理解するのに役立つ情報の宝庫です。私が駆け出しのシステム管理者だった頃、ログを注意深く読まなかったために、遅いサーバーをデバッグするのに丸一日を費やしたことがあります。結局のところ、障害が発生したサービスが継続的に再起動を試み、CPUとディスクI/Oリソースを消費していたのです。もっと早くログを確認していれば、多くの時間を節約できたでしょう!
確認すべき重要なログ:
/var/log/syslogまたは/var/log/messages(システム共通ログ)- 特定のアプリケーションのログ(Apache、Nginx、データベース、あなたのアプリケーションなど…)
- systemdを使用するシステムでは
journalctlを使用します:
journalctl -xe
このコマンドは、最新のログを表示し、エラーや警告を迅速に検出するのに役立ちます。
2. CPUの最適化
topまたはhtopでCPUが常に高いレベルにあることが示された場合、いくつかの最適化方法があります:
- CPUを大量に消費するプロセスを特定:
top/htopを使用して%CPU列でソートし、最もCPUを消費しているプロセスを見つけます。その後、そのプロセスが正しく動作しているか、またはエラーが発生しているかを調査する必要があります。 - プロセスの優先度を調整:それほど重要ではないが実行する必要があるプロセスがある場合、
niceとreniceを使用してそれらの優先度を下げることができます。これにより、それらのプロセスがより重要なプロセスにCPUを譲るようになります。
# 優先度を下げてコマンドを実行する(例:my_commandはCPUリソースをより少なく受け取る)
nice -n 10 my_command
# 実行中のプロセスの優先度を変更する(PIDはプロセスのID)
renice +10 -p <PID>
niceの値が高いほど(例:+19)、優先度は低くなります。逆に、値が低いほど(例:-20)、優先度は高くなります。
3. RAMとスワップの最適化
RAMはサーバーの速度にとって非常に重要なリソースです。RAMが不足すると、システムはスワップ(仮想RAMとして使用されるディスクの一部)を使用しなければなりません。これは実際のRAMよりも数百倍遅いです。
スワッピングの制御
swappinessは、システムがスワップを使用する頻度を制御するカーネルパラメータです。Ubuntuのデフォルト値は通常60で、これはRAMの40%が空になるとカーネルがスワップを使い始めることを意味します。本番環境では、サーバーがデータをRAMに保持することを優先させたいと考えるのが一般的です。早すぎるスワップアウトを制限することは非常に重要です。
# 現在のswappiness値を確認
sysctl vm.swappiness
# swappiness値を低く設定する(例:10)と、スワップの使用が減少する
sudo sysctl vm.swappiness=10
# この変更を永続化するには、/etc/sysctl.confに追加する
sudo echo "vm.swappiness=10" >> /etc/sysctl.conf
適切なswappinessの値は、アプリケーションによって異なります。高いパフォーマンスを必要とし、ほとんどスワップを使用しないアプリケーションの場合、10または1が理想的な値です。逆に、サーバーのRAMが少なく、メモリ不足によるシステムフリーズ(OOM killer)を避けたい場合は、デフォルト値を維持するか、わずかに増やすことができます。
ファイルシステムキャッシュの削減
Linuxカーネルは通常、ページキャッシュ、inodeキャッシュ、dentryキャッシュなどのファイルシステムキャッシュにRAMの一部を使用し、読み書き速度を向上させます。これは非常に良いことですが、時としてこれらのキャッシュが大量のRAMを占有し、本当に必要なアプリケーションのためのメモリ不足を引き起こす可能性があります。vm.vfs_cache_pressureパラメータは、カーネルがこれらのキャッシュをどの程度回収するかを制御します。デフォルト値は100です。
# 現在の値をチェック
sysctl vm.vfs_cache_pressure
# この値を減らす(例:50)と、カーネルがキャッシュを回収する頻度が減り、RAMに長く保持される
sudo sysctl vm.vfs_cache_pressure=50
# 永続的な変更のため
sudo echo "vm.vfs_cache_pressure=50" >> /etc/sysctl.conf
vm.vfs_cache_pressureの調整は慎重に行う必要があります。値を低くしすぎると、ファイルシステムの速度が低下する可能性があります。これは高度な最適化であり、通常、アプリケーションを十分に理解し、他の代替案を検討した場合にのみ実行されます。
4. ディスクI/Oの最適化
ディスクI/O(入力/出力)は、特にデータベースアプリケーションや大規模ファイル処理において、最も一般的なボトルネックの1つです。
マウントオプション
ファイルシステムをマウントする際、パフォーマンスを向上させるためのオプションを追加できます:
noatime:デフォルトでは、Linuxはファイルが読み取られるたびにアクセス時刻(atime)を更新します。これはかなりの量の不要なディスクI/O書き込み操作を引き起こします。noatimeオプションは、この更新を無効にし、ディスクの負荷を軽減します。
noatimeを追加するには、/etc/fstabファイルを編集します。最適化したいパーティションのマウント行を見つけ、オプションのリストにnoatimeを追加します。
例:
UUID=... / ext4 defaults 0 1
次のように:
UUID=... / ext4 defaults,noatime 0 1
編集後、パーティションを再マウント(またはサーバーを再起動)する必要があります:
sudo mount -o remount /
/etc/fstabの編集には注意してください。わずかな間違いでもシステムが起動できなくなる可能性があります。
I/Oスケジューラ
I/Oスケジューラは、物理ディスクに送信される読み取り/書き込み要求の順序を決定します。一般的なスケジューラは、noop、deadline、cfqです。
noop:最もシンプルなスケジューラで、通常、SSDや仮想化環境に適しています。ここでは、I/Oの調整はハードウェア層またはハイパーバイザーで既に処理されています。deadline:読み取り要求を優先し、それらに期限を設定して、どの要求も長く待ちすぎないようにします。通常、データベースアプリケーションに適しています。cfq(Completely Fair Queuing):プロセス間でI/O帯域幅を公平に分配しようとします。通常、デスクトップや従来のHDDを使用する多目的サーバーに適しています。
現代のSSDでは、noopまたはdeadlineが通常、より良いパフォーマンスを提供します。
# sdaディスクの現在のスケジューラを確認
cat /sys/block/sda/queue/scheduler
# スケジューラをnoopに設定
sudo echo noop > /sys/block/sda/queue/scheduler
この変更を永続化するには、GRUB設定ファイルを編集するか、udevルールを使用する必要があります。
5. ネットワークの最適化
いくつかの高度なネットワーク設定は他の記事で言及されていますが、LinuxカーネルのTCP/IP層に基本的な最適化をいくつか適用して、全体的なネットワークパフォーマンスを向上させることは可能です。
TCP/IPチューニング
/etc/sysctl.confファイルを編集して、次のカーネルパラメータを追加または変更します:
# TIME_WAIT状態に保持できる最大接続数を増やす
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_tw_buckets = 500000
# 未承諾の着信接続のキューを増やす
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# ネットワークバッファの制限を増やす(受信バッファと送信バッファ)
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 4194304
# Fast Openを許可する(TCP接続確立の遅延を減らす)
net.ipv4.tcp_fastopen = 3
編集後、変更を適用します:
sudo sysctl -p
これらのパラメータは、サーバーが送受信接続をより良く処理し、特に高負荷時にソケットリソース不足によるネットワーク輻輳の可能性を減らすのに役立ちます。
ファイルディスクリプタの制限を増やす (ulimit)
各ネットワーク接続や開かれたファイルは、ファイルディスクリプタを使用します。Webサーバーやデータベースなどのアプリケーションは、数千、場合によっては数万のファイルディスクリプタを同時に開く必要がある場合があります。この制限が低すぎると、アプリケーションはエラーに遭遇し、効率的に動作できなくなります。
シェルプロセスの現在の制限を確認するには:
ulimit -n
この制限をシステム全体で増やすには、/etc/security/limits.confファイルを編集する必要があります:
# ファイルの最後にこれらの2行を追加して、ソフトおよびハード制限を設定します
* soft nofile 65535
* hard nofile 65535
そして、PAMモジュールが/etc/pam.d/common-sessionまたは/etc/pam.d/loginでアクティブ化されていることを確認します(通常、デフォルトでアクティブ化されています):
session required pam_limits.so
変更後、変更を有効にするには、ログアウトして再度ログインするか、サーバーを再起動する必要があります。
結論
Linuxサーバーのパフォーマンス最適化は、監視、分析、調整を必要とする継続的なプロセスです。各アプリケーションと環境には独自の要件があるため、すべてのケースに当てはまる一般的な処方箋はありません。重要なのは、サーバーがどのように動作しているか、どのリソースがボトルネックになっているかを明確に理解し、それに応じて適切な最適化措置を適用することです。
最適化は初期設定で終わるものではないことを忘れないでください。システムを常に監視し、ログを読み、作業負荷の変化に応じて調整する準備が必要です。この記事で得た知識とツールがあれば、サーバーをより速く、より強力にする旅を始めるのに十分な装備が整っていると信じています。

