高ディスクI/Oレイテンシのトラブルシューティング: ステップバイステップLinuxガイド

iostat、iotop、pidstat、vmstat、ログ、実用的なワークロードチェックを使用してLinuxディスクI/Oレイテンシを診断します。

高ディスクI/Oレイテンシのトラブルシューティング: ステップバイステップLinuxガイド

高ディスクI/Oレイテンシには非常に特徴的な感覚があります。SSHはまだ接続され、CPUは最大使用率ではありませんが、ファイルに触れるすべてのコマンドが一瞬ハングします。セッションを書き込む際にWebアプリが一時停止します。通常はすぐに返されるデータベースクエリがストレージを待ち始めます。マシンは生きているように見えますが、泥の中を歩いているように感じます。

重要なのは推測を避けることです。「ディスクが遅い」というのは、飽和したブロックデバイス、スワップスラッシング、故障中のドライブ、ノイズの多いバックアップジョブ、過負荷のネットワークボリューム、またはインデックスが欠落しているためにランダム読み取りを行っているデータベースを意味する可能性があります。同じ症状がまったく異なる原因から発生することがあります。

ディスクI/Oメトリクスの理解

トラブルシューティングに飛び込む前に、I/O問題を示す主要なメトリクスを理解することが重要です。高レイテンシが主要な症状ですが、問題の深刻度と原因を確認するための補足データポイントが必要です。

I/O競合の主要な指標

  • 高レイテンシ(await): I/O要求が完了するまでの平均時間(ミリ秒単位)。これにはキューで待機する時間とサービスを受ける時間が含まれます。「高い」と見なされる値はストレージとワークロードに依存します。可能であればシステムの通常のベースラインと比較してください。
  • 高使用率(%util): このメトリクスが100%に近づくと、デバイスは飽和状態であり、要求を効率的に処理できません。
  • 高キューイング(avgqu-sz): 平均キューサイズが大きい場合、多くのプロセスがディスクの解放を待っていることを意味します。

ステップ1: iostatによる初期システムヘルスチェック

iostatユーティリティ(sysstatパッケージの一部)は、デバイスの使用率とパフォーマンス統計を監視するための基盤です。CPUとデバイスI/Oの履歴データと現在のデータを提供します。

I/Oパフォーマンスの実行中の集計を取得するには、間隔(例:2秒ごと)を指定してiostatを実行します:

sudo iostat -dxm 2

iostat -dxm出力の分析

デバイス統計列(xフラグ)に特に焦点を当てます:

説明 高値の意味
r/s, w/s 1秒あたりの読み取り/書き込み(IOPS) 高スループット需要を示します。
rkB/s, wkB/s 1秒あたりの読み取り/書き込みキロバイト スループット量を測定します。
await I/O要求の平均待機時間(ms)(サービス時間 + キュー時間) 高レイテンシの主要な指標。
%util デバイスが要求の処理でビジーだった時間の割合 100%に近いと飽和を示します。

シナリオ例: /dev/sdaawait時間150ms、%utilが98%を示している場合、そのディスクに深刻なI/Oボトルネックがあることが確認されました。

ヒント: 拡張統計には-xフラグを使用し、キロバイト(-k)よりも明確なことが多いメガバイト単位で報告するには-mを使用します。

ステップ2: iotopで原因プロセスを特定する

iostatが特定のデバイス(例:/dev/sda)で高レイテンシを確認したら、次の重要なステップは、その負荷を生成しているプロセスを特定することです。topコマンドの機能を模倣しながらI/Oアクティビティに焦点を当てたiotopユーティリティは、ここで不可欠です。

iotopがインストールされていない場合は、最初にインストールします:

# Debian/Ubuntu
sudo apt update && sudo apt install iotop

# RHEL/CentOS/Fedora
sudo yum install iotop  # または dnf install iotop

iotopをroot権限で実行し、アクティブにI/Oを行っているプロセスのみを表示します:

sudo iotop -oP
  • -o: アクティブにI/Oを行っているプロセスのみを表示。
  • -P: 個々のスレッドではなくプロセスを表示。

出力を調べ、IO_READおよびIO_WRITE列に注意を払います。上部にリストされているプロセスが最も多くのディスク帯域幅を消費しています。一般的な原因には、データベースサーバー(MySQL、PostgreSQL)、バックアップユーティリティ、ログローテーションスクリプト、またはスワップスペースに積極的に書き込むシステムが含まれます。

iotop出力の解釈

iotopは各プロセスの合計ディスク使用量を表示します。レイテンシが急上昇している間に、単一のアプリケーションがディスク使用率を支配している場合(例:バックアップスクリプトが50 MB/sで実行中)、直接的な原因が見つかりました。

ステップ3: pidstatによる詳細調査

iotopはプロセスごとの総I/Oを表示しますが、pidstatは特定のPIDによって開始されたI/O操作に関する詳細な履歴コンテキストを提供でき、長期実行または断続的な問題に役立ちます。

すべてのプロセスのI/O統計(ブロックの読み取りと書き込み)を5秒ごとに5回監視するには:

sudo pidstat -d 5 5

-d出力の主要なメトリクスは次のとおりです:

  • kB_rd/s: タスクによってディスクから1秒あたりに読み取られたデータ量。
  • kB_wr/s: タスクによってディスクに1秒あたりに書き込まれたデータ量。
  • kB_ccwr/s: スワップスペースに書き込まれたデータ量(c=キャンセル/コミット書き込み)。

ユーザーが一時停止を報告するたびに、同じプロセスの読み取りと書き込みが急増する場合、有用な手がかりがあります。pidstatは、iotopが短いスパイクを示した後、読み取る前にクリアしてしまう場合に特に役立ちます。

ステップ4: メモリスラッシング(スワップ使用量)の診断

システムが低速な物理ディスクを仮想RAMとして使用せざるを得ないため、高いスワップアクティビティはしばしば高いディスクI/Oレイテンシとして現れます。freeコマンドを使用してメモリプレッシャーを確認します:

free -h

使用済みメモリが合計メモリに近く、スワップ使用済み値が急速に増加している場合、システムはメモリ不足であり、I/Oレイテンシはスワッピングの二次的な症状です。

スラッシングの解決策:

  1. topまたはhtopを使用してメモリを大量に消費するプロセスを特定します。
  2. 可能であればシステムRAMを増やします。
  3. アプリケーションがより少ないメモリを使用するように調整します。

問題が発生している間にvmstatも確認します:

vmstat 1

siおよびso列は、スワップインおよびスワップアウトアクティビティを示します。時折の非ゼロ値は自動的に危機ではありません。システムが遅い間に持続的なアクティビティがある場合、より強いシグナルです。wa CPU列も役立ちます:高いI/O待機は、タスクがCPUで実行されるのではなく、ストレージでブロックされて時間を費やしていることを意味します。

ステップ5: デバイスをファイルシステムに一致させる

iostatはブロックデバイスを報告します:sdanvme0n1dm-0md0など。アプリケーションログは通常、パスを言及します:/var/lib/mysql/var/log/home/data。間違ったディスクを非難する前に、パスをデバイスにマッピングします。

df -hT /var/lib/mysql
findmnt /var/lib/mysql
lsblk -f

これは、LVM、ソフトウェアRAID、クラウドボリューム、または個別のマウントポイントを持つホストで重要です。dm-0で高レイテンシが表示されるかもしれませんが、実際のバッキングデバイスはEBSボリューム、mdraidアレイ、または暗号化されたマッパーデバイスである可能性があります。ビジーなファイルシステムがネットワークストレージ上にある場合、ローカルディスクツールはストーリーの一部しか伝えません。NFS、iSCSI、クラウドボリュームメトリクス、またはストレージアプライアンスも確認する必要があります。

ステップ6: カーネルとハードウェアの手がかりを探す

レイテンシは高いがスループットは高くない場合、ストレージエラーを確認します。故障中のディスクまたはリセットしやすいコントローラは、控えめなI/Oでもシステムを遅くする可能性があります。

dmesg -T | egrep -i 'error|reset|timeout|nvme|scsi|blk_update|i/o error'
journalctl -k --since "30 minutes ago"

物理ディスクの場合、SMARTデータが役立ちます:

sudo smartctl -a /dev/sda

NVMeデバイスの場合:

sudo nvme smart-log /dev/nvme0

単一のSMARTフィールドを単独で読み過ぎないでください。ベンダーによって異なるカウンターが公開されます。しかし、再割り当てされたセクター、メディアエラー、繰り返されるコマンドタイムアウト、またはカーネルI/Oエラーは即座の注意が必要です。ディスクが本番データベースをバックアップしている場合、それをチューニング演習として扱うのをやめ、冗長性、フェイルオーバー、または交換に移行します。

ステップ7: 帯域幅の問題とレイテンシの問題を区別する

2つのインシデントが両方とも「遅いディスク」を示しながら、異なる修正を必要とすることがあります。

シーケンシャルバックアップは、高いwkB/sと高い%utilを押し上げる可能性があります。これは帯域幅の問題です。バックアップを調整する、ピーク時から移動する、増分バックアップを使用する、または別のボリュームに書き込むことが役立つ場合があります。

インデックスが欠落しているデータベースは、控えめなスループットだが苦痛なawait、多くの小さな読み取り、およびユーザーに見えるクエリ遅延を示す可能性があります。これは多くの場合、ランダムI/Oとクエリ形状の問題です。より多くの帯域幅を投入するよりも、適切なインデックスを追加するか、ワーキングセットを減らす方が効果的です。

このクイックリードを使用します:

  • 高いrkB/sまたはwkB/s、高い%util、明らかな大規模ジョブ:バルク読み取り/書き込みを探します。
  • 高いr/sまたはw/s、高いawait、低いスループット:多くの小さなランダム操作を探します。
  • 高いスワップアクティビティ、高いwa、低い空きメモリ:メモリプレッシャーを根本原因として扱います。
  • カーネルエラーを伴う高レイテンシ:ストレージの健全性を根本原因として扱います。

ステップ8: アプリケーションレベルのコンテキストを確認する

システムツールは、誰がストレージに触れているかを教えてくれます。なぜそうしているのかを常に教えてくれるわけではありません。

データベースの場合、スロークエリログとバッファ/キャッシュメトリクスを確認します。iotopのトップにあるMySQLプロセスは、バックアップ中は正常、ピークトラフィック時は悪い、または再起動後バッファプールがコールドな間は予想される場合があります。PostgreSQLは、autovacuum、チェックポイント書き込み、またはディスクにあふれるクエリを行っている可能性があります。MongoDBは、圧縮、インデックス構築、またはRAMに収まらなくなったワーキングセットの読み取りを行っている可能性があります。

Webサーバーとアプリケーションワーカーの場合、ログストームを探します。有効のままのデバッグログは、安定した同期書き込みを作成する可能性があります。失敗した依存関係は、繰り返しエラーログを作成し、それがディスクプレッシャーを作成し、元のインシデントを悪化させる可能性があります。

コンテナの場合、ノイズの多いプロセスがcontainerddockerd、またはオーバーレイファイルシステムの下に表示される可能性があることを覚えておいてください。コンテナレベルのツールも使用します:

docker stats
docker ps --format 'table {{.ID}}\t{{.Names}}\t{{.Status}}'

Kubernetesノードでは、ホストレベルのI/Oをポッド配置と比較します。emptyDir、hostPath、またはローカル永続ボリュームに大量に書き込む単一のポッドは、同じノード上の無関係なポッドを異常に見せることがあります。

一般的な原因と修復戦略

原因が特定されたら、適切な修正を適用します:

1. バックアップまたはメンテナンスジョブ

症状: スケジュールされたジョブ(例:cronジョブ)と一致する高いI/O使用率。 修復: 大規模なI/Oジョブを再スケジュールし、ユーティリティがサポートしている場合は調整し、または一時出力を別のボリュームに移動します。たとえば、rsync --bwlimitionice、およびデータベースネイティブのバックアップスロットルは、影響範囲を減らすことができます。

2. 非効率的なデータベースクエリ

症状: データベースプロセス(例:mysqld)がiotopのトップコンシューマーである。 修復: フルテーブルスキャンを強制し、大規模なランダム読み取りにつながる、インデックスが不十分なクエリを最適化します。

3. 過剰なロギング

症状: アプリケーションまたはシステムのロギングプロセスが大量のデータを書き込んでいる。 修復: アプリケーションのロギングレベルを確認します。ログをバッファリングするか、リモートロギングソリューション(SyslogやELKスタックなど)を使用してローカルディスク書き込みを減らすことを検討します。

4. ディスク障害または設定ミス

症状: 高スループットと相関しない非常に高いawait時間、または奇妙な読み取り/書き込みパターン。これは、ハードウェア障害または不適切なRAID設定を示している可能性があります。 修復: SMARTデータ(smartctl)でディスクの健全性を確認します。RAIDを使用している場合は、アレイのステータスを確認します。

5. ファイルシステムまたはマウントオプション

症状: メタデータを多用するワークロード(多数の小さなファイルの作成、ディレクトリの削除、ログのローテーション、アーカイブの解凍)の周りでレイテンシが発生する。

修復: ファイルシステムのタイプ、マウントオプション、inode使用量、およびジャーナルの動作を確認します。満杯のファイルシステム、枯渇したinode、またはほぼ満杯のシンプロビジョニングボリュームは、アプリケーション側からはI/Oレイテンシの問題のように見えることがあります。

df -h
df -ih
findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS

inode使用量が100%の場合、1つの巨大なファイルを削除しても役に立ちません。多数の小さなファイルを削除するか、そのワークロードをそれ用に設計されたファイルシステムレイアウトに移動する必要があります。

プロアクティブな監視のためのベストプラクティス

I/Oボトルネックを防ぐことは、事後的に修正するよりも優れています。継続的な監視を実装します:

  • アラートを設定する: ディスクレイテンシ、キュー深度、I/O待機、ファイルシステムの満杯度、およびエラーカウンターの持続的な変化についてアラートを発するように監視ツールを設定します。普遍的な数値をコピーするのではなく、ストレージクラスとワークロードに一致するしきい値を使用します。
  • パフォーマンスのベースライン化: 特定のワークロードにとって「通常の」I/Oレイテンシがどのように見えるかを把握します。これにより、異常を発見しやすくなります。
  • ワークロードタイプを理解する: ランダムI/Oパターン(データベースで一般的)は、シーケンシャルI/O(メディアストリーミングや大きなファイル読み取りで一般的)よりもはるかに高いレイテンシを引き起こします。

最良のディスクレイテンシ調査は、質問を絞り込み続けます:どのデバイス、どのファイルシステム、どのプロセス、どのワークロード、そしてどの最近の変更か?その連鎖が得られれば、修正は通常より明確になります。カーネル設定をランダムに調整するのをやめ、バックアップスケジュールの変更、メモリの追加、ストレージの修復、クエリの修正、またはノイズの多いワークロードを共有ディスクから移動し始めます。