プロンプトとコンテキスト
Linuxホストにおいて、%iowait が3%から38%に上昇し、アプリケーションのp99レイテンシが2倍になる一方で、CPU全体の利用率は30%にとどまっています。ローカルブロックデバイス、NFSまたはその他のリモートストレージ、メモリ回収(memory reclaim)、ハイパーバイザのsteal、そしてホストとサービス測定値間のスコープの不一致をどのように区別するかを説明してください。
まず、/proc/stat におけるiowaitの意味と限界から始めます。次に、vmstat、iostat、pidstat、PSI、タスク状態、cgroupメトリクス、カーネルログを使用して証拠を構築します。提示された数値は演習用の架空のデータであり、普遍的なアラート閾値ではありません。
面接官が見ているポイント
会計境界(Accounting boundary)
候補者は、iowaitがCPUの統計集計フィールドであり、デバイスの利用率や全タスクが待機に費やした合計時間を表すものではないことを理解している必要があります。マルチコアのスケジューリングにより、正確な帰属が難しくなります。
証拠のレイヤー
優れた回答では、ホスト全体の平均から、CPU単位、スレッド、cgroup、デバイス、そしてビジネスのテールレイテンシの証拠へと掘り下げ、それぞれの観察結果によって何が変わるかを説明します。
待機パス
ローカルブロックI/O、NFS/FUSE、データベースRPC、メモリ回収、ハイパーバイザのstealを切り分ける必要があります。各パスによって証拠と緩和策が異なります。
安全なクローズ
候補者は証拠を保全し、仮説に直結した低リスクの緩和策を選択し、デフォルトで再起動したり並行性を増やしたりするのではなく、復旧を確認します。
最初に確認すべき明確化のための質問
- iowaitはホストからのものですか、それともコンテナからのものですか? ホストの
/proc/statとサービスのcgroupメトリクスは対象母集団が異なる場合があります。 - すべてのCPUが高いのですか、それとも1つだけですか? 平均値はアフィニティ、NUMA、クォータ起因の局所的な飽和を隠してしまいます。
- リクエストはファイル、ブロックデバイス、ネットワークRPCのどれを待っていますか? NFS、データベース、HTTPの待機では証拠が異なります。
- p99とI/Oシグナルは完全に同じ時間枠を共有していますか? サンプリング、デプロイ、バックアップ、トラフィックの変動を揃えて比較します。
- スワップ、メジャーフォールト、メモリPSI、またはsteal timeは増加していますか?
- スレッドのスタックやcgroupファイルを読み取ることができますか? 本番環境の調査では最小権限の原則に従ってください。
30秒での回答
「38%のiowaitは手がかりに過ぎず、ディスク障害の証明ではありません。まずホスト、サービス、p99の時間枠を揃え、CPUごとの mpstat、vmstat r/b、CPU/IO/メモリのPSI、cgroupクォータ、steal timeを調査します。
デバイスキュー、レイテンシ、プロセスの読み書き、カーネルエラーが揃って異常である場合は、ブロックストレージを調査します。ローカルデバイスが正常であるにもかかわらずスレッドがNFSやファイルシステムパスで待機している場合は、マウント、ネットワーク、サーバーを調査します。メモリPSI、スワップ、メジャーフォールトが増加している場合はワーキングセットを調査し、stealが増加している場合はハイパーバイザを調査します。緩和後はビジネスのテールレイテンシ、待機タスク、PSI、リソースを確認します。」
ステップバイステップの詳細な回答
ステップ 1: iowaitの境界を定義する
/proc/stat のiowaitは、I/O完了の待機に関連するCPU時間の集計です。あるタスクが待機している間も別のタスクが実行される可能性があり、マルチコアの集計では待機を常に正確に帰属できるとは限りません。iowaitが低いからといってリモートストレージやカーネルの待機を除外できるわけではなく、iowaitが高いからといってディスク障害が証明されるわけでもありません。
ステップ 2: CPUごとのデータとキューを確認する
mpstat -P ALL 1 10
vmstat 1 10
cat /proc/loadavgCPUがビジーな状態での持続的な r はCPUキューイングを裏付け、持続的な b は割り込み不能な待機(uninterruptible wait)を示唆します。CPUごとのデータ、アフィニティ、cgroupクォータ、スロットリングにより、「全体で30%だが、局所的に飽和している」状態が明らかになります。
ステップ 3: PSIで停滞時間を測定する
for r in cpu io memory; do echo "[$r]"; cat /proc/pressure/$r; donePSIの some は少なくとも一部の処理が停滞した時間を測定し、full はアイドル状態以外のすべての処理が停滞した時間を測定します。avg10/60/300 で傾向を確認します。対象cgroupのpressureファイルを読み取り、サービスのプレッシャーをホストのノイズから分離します。
ステップ 4: スレッドと待機ポイントを特定する
ps -eLo state,pid,tid,wchan:32,comm --sort=state
pidstat -d -p ALL 1 10R/Dステータス、コマンド、cgroup、wchan ごとにグループ化します。許可されている場合は、代表的なスレッドの /proc/PID/stack を検査します。wchanは現在のスリープ位置を示すものに過ぎないため、原因と断定する前に時間的相関、PSI、ビジネスレイテンシを確認する必要があります。
ステップ 5: 関連するサブシステムを掘り下げる
iostat -xz 1 10
dmesg -T | tail -200
cat /proc/meminfo | egrep 'Swap|Dirty|Major'ブロックデバイスの場合は、await、キューの深さ、スループット、エラーを検査します。NFS/FUSEの場合は、マウント、再送、ネットワーク、サーバーの健全性を検査します。メモリの場合は、メモリPSI、スワップ、メジャーフォールトを相関付けます。データベースやHTTP RPCの待機にはトレーシングやプールメトリクスが必要であり、iostat単体では検知できません。
ステップ 6: 緩和と検証
スレッド、PSI、デバイス、ログのスナップショットを取得した上で、証拠に基づいてレート制限の適用、バッチ処理の一時停止、正常なレプリカへの切り替え、マウントの修復などを行います。Dステートのタスクに対して kill -9 を繰り返し実行しないでください。通常、シグナルを処理する前に割り込み不能待機を抜ける必要があります。p99、エラー、R/Dカウント、PSI、リソースレイテンシ、バックログを合わせて検証します。
模範解答
「38%のiowaitは手がかりであり、結論ではありません。マルチコアスケジューリングの影響を受けるCPU集計値であるため、即座にディスク障害と判断することはありません。スコープと時間枠を揃え、CPUごとの mpstat、vmstat r/b、CPU/IO/メモリのPSI、cgroupクォータ、steal timeを調査します。
DステートのスレッドとI/O PSIが増加し、wchanがブロックI/Oを指し、iostatがレイテンシとキューの増加を示している場合は、デバイス、ファイルシステム、カーネルエラーを検査します。ローカルデバイスが正常であるのにスレッドがNFS待機に集中している場合は、マウント、再送、ネットワーク、サーバーを検査します。メモリPSI、スワップ、メジャーフォールトが増加している場合はワーキングセットを制御し、stealが増加している場合はハイパーバイザを調査します。
証拠を保全しつつ、I/Oを増幅させるバッチ処理を一時停止するか、レート制限をかけるか、正常なレプリカへ切り替えます。復旧とは単にiowaitが低下することではなく、ビジネスのp99とエラー、R/D待機数、PSI、リソースレイテンシ、バックログがベースラインに向けて回復することを意味します。」
よくある間違い
- iowaitをディスク利用率として扱うこと。
iostatやデバイスのベースラインと相関させてください。 - iowaitが上昇した途端にCPUを追加すること。まずCPUごとのデータ、R/D状態、PSIを確認してください。
- iowaitが低いからといってI/Oの問題を除外すること。Dステート、リモートストレージ、I/O PSIを検査してください。
- すべてのDステートをローカルディスクの問題と決めつけること。NFS、ファイルシステム、ドライバもブロックの原因になります。
- ホストのメトリクスしか見ないこと。サービスのcgroupには異なる制限やプレッシャーが存在する場合があります。
- 1回しかサンプリングしないこと。リクエスト曲線に揃えた、タイムスタンプ付きの継続的なサンプルを使用してください。
- 直ちに再起動やkillを行うこと。証拠を保全し、データの安全性を評価してください。
- iowaitの低下だけを待つこと。ユーザーのレイテンシとリソースキューを確認してください。
フォローアップ質問
フォローアップ 1: なぜディスク使用率(util)が低いのにiowaitが高くなることがあるのですか?
待機がNFS、FUSE、データベース、またはネットワークRPCで発生しているか、デバイスマッピングと集計時間枠が異なっている可能性があります。スレッドの待機ポイント、トレーシング、I/O PSI、マウント、ネットワークのシグナルを追跡してください。
フォローアップ 2: なぜリクエストが滞っているのにiowaitが低くなることがあるのですか?
タスクがロック、プール、CPUクォータ、メモリ回収、またはリモートRPCで待機している可能性があります。R/D状態、スタック、CPU/メモリPSI、依存関係のレイテンシを比較してください。CPU会計はすべての待機をiowaitとして分類するわけではありません。
フォローアップ 3: コンテナ自体にI/Oプレッシャーがあるかどうかをどのように判別しますか?
対象cgroupの io.pressure、I/O統計、スロットリングイベントを読み取り、ホストの /proc/pressure/io やサービスのp99と比較します。ホストのプレッシャーが高くてもサービスのプレッシャーが低い場合、サービスをスケールさせても効果がない可能性があります。
フォローアップ 4: Dステートのスレッドをkillできますか?
シグナルを送信することは可能ですが、通常、割り込み不能待機から復帰するまで処理されません。スタックと待機ポイントを取得し、デバイス、マウント、ドライバを修復し、冗長性とデータの安全性が確認された後にのみ再起動を検討してください。
フォローアップ 5: iowaitに対してどのようにアラートを設定しますか?
画一的な割合の使用は避けてください。iowaitに加えて、I/O PSI、ローカルまたはリモートストレージのレイテンシ、Dステート数、ビジネスSLO、および継続時間を組み合わせ、ワークロードのベースラインに合わせて調整します。