コンテンツにスキップ

Systems Performanceの振り返り・解説

トピック入口と開始文へ戻る。以下の数値例・図は概念説明で、本人の実測ではありません。

ChatGPT開始文
https://github.com/MFQWKMR4/tech2026 のCHATGPT.md、AGENTS.mdと次を読んでください。
- src/content/docs/systems/performance.mdx
- reviews/systems-performance.yaml
- sessions/2026-09-15-systems-performance-01.yaml
- public/diagrams/systems-performance/cpu-states.svg
- src/content/docs/career/learning/systems-performance.md
systems-performance のlearnとして、気になる節を一つ確認してから、説明→疑問→具体例→理解確認を一つずつ進めてください。
指定がなければneeds_revisitから始め、独力の回答とヒント・解説後を区別してください。
参照できたファイルとrevisionを示し、読めないものや未確認の事実を補完しないでください。
図の内容を読むことと描画の確認、教材検証と私の実績を区別してください。
開始時刻を確認できれば記録し、40分付近で区切りを提案してください。
終了時は既存テンプレートのYAML+Session narrativeで[Session Sync]をMFQWKMR4/tech2026へ作成し、URLを返してください。
作成できなければ未作成と明示してコピー可能な本文を返してください。

最終レビュー:2026-09-15 · 説明した(Explained)。ヒント後の理解と自力の説明を区別して記録しています。

次回、自力で確かめたいこと

  • 2026-09-15 (2026-09-15-systems-performance-01): run queueとCPU utilization/saturationの関係を、CPUが空いているのにrun queueが長い場合に何を疑うかまで再確認する。
  • 2026-09-15 (2026-09-15-systems-performance-01): connection poolのmax size、active、idle、wait timeを使って、pool待ちとdownstream latencyをどう切り分けるかを別条件で再確認する。
  • 2026-09-15 (2026-09-15-systems-performance-01): backpressureを、同期APIではbounded concurrency/queue/timeout/429・503、非同期処理ではqueue/consumer制御としてどう設計するかを次回確認する。
  • 2026-09-15 (2026-09-15-systems-performance-01): Issue #21の追記(2026-09-16)で希望: 性能劣化の最初の観測を、症状・影響区間・CPU/core/runnable・memory/I/O・app内待ちに対応するLinux/AWSコマンドと理由で短く説明する。追加テストは未実施。

2026-09-15のセッション

Systems Performanceの入口から、run queue、CPU utilizationとsaturation、CPU以外の待ち、外部API前のconnection pool待ち、pool拡大の下流影響、rate limit/queue/backpressureを一つの性能劣化シナリオで学習した。本人はrun queueを『実行可能なthreadが待つ状態』と概ね捉えていたが、CPU使用率との関係は不明だった。CPU全体40%でもcore別使用率を見る必要を事前説明後に指摘し、CPU/memory/disk/networkを順に切り分けた。AWS/EBSではVolumeQueueLength・IOPS・throughput、networkでは外部API所要時間、ENA系スロットリング、microburst、TCP retransmission、ss/tcpdumpを候補として挙げた。外部API呼び出し前の1.7秒待ちに対し、lock待ちまたはconnection pool待ちを仮説として提示した。pool 100→200では、自分側の待ちだけでなく下流APIの処理能力・rate limit・全Pod合計connection数を見る必要を解説後に整理できた。最後に、poolをこれ以上増やせない場合はqueueで平準化し、入口でrate limitして弾く案を自発的に提示した。backpressureの意味は未認知だったため解説した。途中、ChatGPT側が『接続数増加→接続確立1.5秒』という因果の弱い条件を提示し、本人が辻褄の弱さを指摘したため、その条件は撤回して一貫したconnection pool待ちシナリオへ修正した。

CPU以外のI/O、EBS/network指標、API前のlock/pool待ちと入口制御を提示。core別確認は事前説明あり、pool拡大の下流影響・backpressureは解説後。

問い・回答の流れをIssueで読む

回答で示せたこと(ヒントの有無を含む)
  • 2026-09-15 (2026-09-15-systems-performance-01): run queueについて『実行可能な…スレッドが待っている状態か』と回答し、runnable threadとCPU待ちの関係を概ね捉えた。ヒント: なし。
  • 2026-09-15 (2026-09-15-systems-performance-01): ホスト全体CPU 40%に対して『各コアのCPU使用率がどうなっているかは切り分ける必要がある』と回答し、平均値だけでCPU要因を除外しなかった。ヒント: CPU平均40%だけでは除外できないという事前説明あり。
  • 2026-09-15 (2026-09-15-systems-performance-01): CPU各core 30〜50%、run queue 0〜2、throttlingなしの条件で、CPU以外の候補として『I/Oまたはメモリー…有力候補はディスクI/OやネットワークI/O』と回答した。ヒント: なし。
  • 2026-09-15 (2026-09-15-systems-performance-01): AWS/EBSのdisk I/O切り分けで『EBSのキューの長さとか、IOPSやスループット』と回答した。ヒント: なし。
  • 2026-09-15 (2026-09-15-systems-performance-01): network切り分けで、外部API呼び出し時間のログ、AWS側のnetwork throttling、microburst、drop/retransmission、flow単位上限、Linuxのss/tcpdumpを挙げた。ヒント: なし。
  • 2026-09-15 (2026-09-15-systems-performance-01): 外部API呼び出し直前に1.7秒待つ条件で『ロック入った制御なのか、コネクションプールで有効なコネクションが空くのを待ってる』と回答した。ヒント: なし。
  • 2026-09-15 (2026-09-15-systems-performance-01): pool 100→200のtrade-off解説後、『下流側…200並列で処理しきれるか』『外部API側の能力』『ポッドがその分あると全体として倍になる』と整理した。ヒント: あり(下流の同時処理能力・rate limit・全Pod合計接続数を説明)。
  • 2026-09-15 (2026-09-15-systems-performance-01): poolを増やせない条件で『前段で処理を平準化できるようにキュー』『こちら側もレートリミット』『前段側で弾く』と回答した。ヒント: なし。
自力では説明しきれなかったこと
  • 2026-09-15 (2026-09-15-systems-performance-01): backpressureについて『バックプレッシャーは知らない』と回答。ヒント: その後、下流が処理しきれないときに上流側へ流量制御を返す概念として説明した。
理由・設計を詰めたいこと
  • 2026-09-15 (2026-09-15-systems-performance-01): 開始時は『CPU使用率40%だからCPUは原因ではない…そう考えちゃう』と回答した。core偏り、run queue、CPU quota/throttling等を確認するまではCPU要因を除外できないと説明後、core別CPUとrun queueを使った切り分けへ更新した。
  • 2026-09-15 (2026-09-15-systems-performance-01): connection poolの100→200拡大について、当初は『100個増やすぐらいだから…あんまり影響はないように思える』と考えた。下流処理能力・rate limit・複数Pod合計concurrencyの観点を説明後、自分側のwaitを下流へ押し付ける可能性を整理した。
修正が必要な説明

記録された項目はありません。

Default — 何も分からないときの最初の観測

Section titled “Default — 何も分からないときの最初の観測”

最初に「誰の、どのリクエストが、いつから、どれくらい遅いか」を絞る。p50/p95/p99、成功率・timeout、RPS、直近の変更、正常なホストとの差を同じ時間窓で照合する。traceがあればqueue/pool取得・DNS/TCP/TLS・外部API・DB・アプリ処理を分解する。CPU→memory→disk→networkを毎回全部たどる必要はない。変わった区間から、資源の使用量・待ち・エラーを調べる。

次に答えたい問い Linuxの入口例 AWS・アプリで照合するもの
一部coreだけ忙しいか、実行可能なのに待つか mpstat -P ALL 1vmstat 1pidstat -u -t 1 同時間帯のCPU、container quota/throttling、処理量
memoryを回収する負担が増えたか free -mvmstat 1のsi/so、pidstat -r 1/proc/pressure/memory(対応環境) working set、OOM、major fault、GC pause、swap入出力
deviceが遅いか、量が多いか iostat -xz 1のawait・aqu-sz・転送量 EBS VolumeQueueLength、Read/WriteOps・Bytes、平均latency、volume/instanceの上限
通信中か、呼び出す前か 区間trace、ss -tinsar -n DEV,TCP,ETCP 1 下流latency・429、ENA allowance超過カウンタ、drop/retransmission
内部の資源取得で待つか thread/lock profile、アプリ計測 pool max/active/idle、待機数・取得時間、接続保持時間

コマンド例はLinux/procps-ng/sysstat/iproute2向けで今回未実行。版・権限・containerからの可視範囲を確認する。vmstatの初回は起動以降の平均を含むため続くintervalを見る。CloudWatchのOps/BytesはSumを期間秒で割ってIOPS/bytes毎秒にし、QueueLengthやlatencyと単位を合わせる。EBS volume側だけでなくEC2側の帯域上限も確認する。ENAはethtool -S <interface>等の対応統計の増分を見る。microburstは粗い平均に隠れ得る。EBS指標ENA性能指標

Why — CPU使用率と実行待ちは別の問い

Section titled “Why — CPU使用率と実行待ちは別の問い”

CPU utilizationは時間の使用割合。70%で安定しlatencyが予算内、処理待ちが増えていなければ、効率よく使っている可能性がある。ただし30%がそのまま同量の負荷余力という保証にはならない。

Linuxのvmstat r実行中を含むrunnable task数で、CPUを待つtaskだけの数ではない。利用可能な論理CPU数・core偏り・時間窓と合わせる。bはI/O完了等を待つblocked task。load averageはrunnableに加えuninterruptible sleep(D state)も含むので、CPU待ちの人数と同一視しない。vmstat定義Linux USE checklist

2 CPUでrunnableが実行枠を超える場合と、I/O待ちでCPUが空く場合の状態比較

図を拡大

概念例Aは2 CPUにrunnable 6、うち2実行・4待機。rは6の目安となり、全CPUで高使用率と実行待ちが続くなら飽和を疑う。概念例BはI/O待ち4、runnable 1で、CPUが空いていても処理は進まない。waはCPU時間の分類で、I/O待ちtask数や特定deviceの障害率ではない。

host平均40%でも、一部coreへのaffinity、単一thread、container quotaが制約になり得る。全coreが空くのに長いrunnable待ちが継続するなら、同じ対象・時刻を測っているか、cpuset/affinity・quota・仮想化のsteal等を調べる。cgroup v2なら対象cgroupのcpu.maxcpu.statのnr_throttled/throttled_usecの増分を照合する。v1やmanaged環境へ同じpathを決め打ちしない。Linux cgroup v2

Trade-off — poolを倍にしたらどこへ待ちが移るか

Section titled “Trade-off — poolを倍にしたらどこへ待ちが移るか”

演習では外部API本体は約80msなのに、呼出し前に約1.7秒待っていた。pool max=100、active≈100、取得待ちp99≈1.6秒という追加条件はpool飽和を支持する。下流通信時間だけのログではこの待ちが抜ける。activeが高い理由として、呼出し増加、保持時間増大、接続返却漏れも比較する。別々のp99を足して全体のp99とするのではなく、遅い同一requestのtraceで区間を結ぶ。

演習上、10 Podsが各100接続の上限を持てば合計上限は1000、200へ変更すれば2000。上限分を常時張る意味ではなく、poolの生成・遅延接続の実装による。HTTP/1.1で一接続一処理とする例であり、HTTP/2等の多重化では接続数とrequest concurrencyを分ける。autoscalingによるPod増加も同じ下流に影響する。

pool拡大後に取得待ちが減っても、下流80→300ms、429・timeoutが増えるなら待ちを押し付けた可能性がある。同一負荷で全体latency・成功throughput・下流同時実行を比較し、段階的変更と戻す条件を決める。「変更した直後」だけでは因果確定ではない。

Exception — rate limit・queue・backpressureを区別する

Section titled “Exception — rate limit・queue・backpressureを区別する”
手段 制御するもの 限界
rate limit 単位時間あたりの流入・burst 1件が遅くなれば同時実行が積み上がり得る
concurrency上限 同時に下流へ進む処理数 上限外をどこで何件・何秒待たせるかが必要
bounded queue 短いburstの吸収 処理能力を増やさない。継続的な流入超過で満杯になる
backpressure 下流の余力に応じ上流の送信・取得を抑える 上流が応じる契約が必要。無制限retryで打ち消さない

同期APIでは待機枠・deadlineを制限し、rate制限なら429、過負荷で一時処理不可なら503等を契約に合わせて返す。拒否(load shedding)と、上流が実際に流量を減らすことは区別する。非同期化できる仕事ではqueueの長さだけでなく最古メッセージの年齢、consumer concurrency、再試行・DLQを見る。受理後の遅延と重複処理を許せるかが先で、「queueに入れれば解決」ではない。HTTP 503HTTP 429

口頭で最初の調査を説明する例

Section titled “口頭で最初の調査を説明する例”

AIによる一般的な説明例で、本人の過去回答ではない:

まず遅いリクエストの範囲と発生時刻、負荷・エラー・変更をそろえ、traceで伸びた区間を探します。CPUはhost平均だけで除外せずcore別・runnable・quotaを見ます。I/O区間ならmemory回収、device latency、通信のどこで待つかへ絞ります。外部APIが速ければ呼出し前のpoolやlock待ちを測ります。対策はその待ちを減らすものを一つ選び、下流の負荷と全体latencyが悪化しないか確かめます。

次のlearnではこれを暗記して再生せず、「CPU70%で安定、p99だけ悪化」「API80msだがpool待ち増加」等の別条件から、最初の観測と理由を一つずつ説明する。

補強元:2026-09-15-systems-performance-01 / Issue #21の3依頼と9/16追記。撤回された「接続数増加だから接続確立1.5秒」の条件は教材の因果例に採用しない。一次資料確認2026-09-21。Linux/kernelとAWSは現行Web文書(固定版なし)、実環境のkernel・ツール版はunknown。今回は実測・負荷試験なし。