プロンプトとスコープ
マルチスレッドかつ非同期のPythonサービスにおいて、ピーク負荷時に断続的なCPUスパイクが発生しています。チームは、すべての関数呼び出しをインストルメントしたりプロセスを停止したりすることなくコールスタックを取得し、開発者がその結果をリプレイできるようにしたいと考えています。Python 3.15ではprofiling.samplingが追加され、PEP 799によってトレースとサンプリングが単一の名前空間の下に整理されました。
サンプリングと決定論的トレースの使い分け、CPUクロックとウォールクロックの選択方法、および推定値を正確な時間計測として扱うことなくスレッドやフリータスク(free-threaded)ビルドをカバーする方法を説明してください。
面接官が評価するポイント
面接官は、統計的サンプリング誤差への理解や、その低オーバーヘッドとcProfileのインストルメンテーションおよびカバレッジとの違いを把握しているかを評価します。
優れた回答では、単一のコマンドを提示するのではなく、アタッチ権限、機密データ、サンプリング周波数、短時間の処理、プロファイルのバージョニング、およびリプレイについて網羅的に説明します。
事前に確認すべき明確化のための質問
- 問題はCPUの飽和、I/O待ち、ロック競合、それとも一時的なスパイクのどれですか?
- 本番環境で許容されるCPU、メモリ、およびディスクのオーバーヘッドはどの程度ですか?
- スレッド、非同期タスク、GILの状態、またはネイティブ拡張のスタックは必要ですか?
- オペレータは既存のプロセスにアタッチできますか?また、データには誰がアクセスできますか?
- 目的はホットスポットの発見、バージョン比較、それともリグレッションの解消の証明ですか?
30秒で答える要約
「低オーバーヘッドのサンプリングを使用して継続的なホットスポットを特定し、その後、小規模なカナリア環境やオフラインでの再現環境において決定論的トレースで短い実行パスを確認します。profiling.samplingはサンプルの推定値を報告するものであり、正確な関数実行時間ではありません。CPUビューとウォールビューの両方を収集し、スレッドやビルドのメタデータを保持し、プロファイルを暗号化・秘匿化(マスキング)して、プロファイラ自体のコストも監視します。オーバーヘッドやプライバシーのリスクが許容できない場合は、アタッチ権限を取り消し、オフラインプロファイリングに切り替えます。」
ステップバイステップの解決策
サンプリングの目的を定義する
サンプリングは、低い侵入度で時間の経過に伴うホットスポットを推定しますが、非常に短い関数が観測されることを保証したり、呼び出しごとの正確なタイミングを提供したりすることはできません。クロックと収集期間を選択する前に、CPU、ウォール、ロック待ち、およびテールレイテンシのシグナルを定義してください。
サンプリングとトレースを分離する
PEP 799では、決定論的ツールはprofiling.tracingの下に配置され、互換性のためのエイリアスとしてcProfileが維持されています。サンプリングはprofiling.samplingの下に配置されます。トレースはすべての呼び出しを記録するため、高いコストを伴いますが短い処理フローや呼び出し回数の把握に適しています。サンプリングはスタックを定期的に観測するため、本番環境のホットスポットや時間のかかるリクエストに適しています。
python -m profiling.sampling record --pid 1234 --clock cpu --duration 30 --output profile.bin
python -m profiling.sampling replay profile.bin --view flamegraph対象となる3.15ビルドに対してコマンドオプションを確認してください。このスニペットはワークフローを説明するものであり、すべてのベータ版で同一のフラグが存在することを保証するものではありません。
CPUクロックとウォールクロックを選択する
CPUクロックはスレッドが消費したプロセッサ時間を示し、ウォールクロックはスリープ、I/O、および待機時間を含みます。CPUのみのサンプリングではエンドツーエンドのレイテンシ問題を見逃す可能性があり、ウォールクロックのみのサンプリングでは待機状態を誤って計算処理として判定してしまう可能性があります。プロファイルのメタデータにクロックタイプを記録してください。
スレッド、非同期処理、フリータスクビルドをカバーする
メインスレッドのみを見るのではなく、スレッドやタスクごとにスタックを集計します。非同期サービスの場合は、イベントループの計算処理とI/O待ちを区別します。フリータスクビルドでは、競合状態やネイティブ拡張のコンテキストが必要です。デプロイ環境間での比較を可能にするため、インスタンス、インタプリタビルド、およびスレッド識別子を記録してください。
オーバーヘッドと見逃された短時間処理の制御
周波数を高くすると解像度は向上しますが、スタックの読み取りおよび書き込みコストが増加します。短時間のタスクはサンプルの合間に終了する可能性があり、サンプル数がゼロであっても実行されなかったことの証明にはなりません。ドロップされたサンプル数やプロファイラのCPU使用率を測定しながら、収集ウィンドウを広げる、インスタンス間で集計する、またはクリティカルパスに対してオフラインでトレースを使用します。
データと権限の保護
アタッチにはプロセスレベルの権限が必要であり、プロファイルにはモジュール名、パス、ビジネスロジックの関数が含まれる場合があります。アタッチできるオペレータを制限し、ラベルにリクエストデータを含めないようにし、バイナリを暗号化し、TTLを設定し、秘匿化されたコピーのみを共有します。運用ログには、キーやペイロードではなく、プロファイルID、バージョン、および設定情報を含めます。
リプレイ、比較、リグレッションゲートの設定
クロック、レート、期間、インタプリタのバージョン、コミットハッシュ、および負荷ウィンドウを保存します。ホットスポットの割合、スレッド分布、ウォールとCPUの差分、サンプル数を比較します。異なるサンプリングレートから得られたパーセンテージを直接比較することはできません。プロファイルと同一のベンチマーク負荷を紐付け、事前定義されたしきい値を超えた場合にのみリリースをブロックします。
カナリア、停止、およびロールバック
まず1つのインスタンスで、短時間かつ取り消し可能なウィンドウを有効にします。CPU、メモリ、権限、またはプライバシーのリスクが許容値を超える場合は、新規のアタッチを停止し、一時的なアクセス権を取り消し、期限切れのファイルを削除します。サービスは稼働させたままにし、その後の分析はオフラインでの再現とトレースに切り替えます。
質の高い模範解答
「サンプリングは侵入度の低いロケータであり、正確なタイマーではありません。まず単一のインスタンスでprofiling.samplingを使用してCPUビューとウォールビューを収集し、その後profiling.tracingまたは制御されたベンチマークを用いて短いパスを確認します。すべてのプロファイルには、ビルド、コミット、クロック、レート、および負荷のメタデータが付与され、ファイルは暗号化、秘匿化、アクセス制御され、短期間で失効します。比較には同一のパラメータを使用し、ホットスポットの割合、スレッド分布、しきい値に焦点を当てます。プロファイラのコストが高すぎる場合やデータが露出するリスクがある場合は、アタッチ権限を取り消してオフライン分析に戻します。」
よくある間違い
- サンプリング時間を正確な時間として扱う → 最適化ターゲットを誤る → サンプリングの推定値と限界について説明する。
- CPUのみに着目する → I/O待ちを見逃す → 目的に応じてCPUビューとウォールビューの両方を収集する。
- メインスレッドのみをサンプリングする → ワーカーやイベントループのホットスポットが見えなくなる → スレッド、タスク、ビルドのメタデータを保持する。
- 周波数は高いほど良いと思い込む → 収集コストが増加する → プロファイラのオーバーヘッドを測定する。
- 異なるレートのパーセンテージを比較する → 結果を適切に比較できない → パラメータと負荷を標準化する。
- プロファイルを永久に保持する → パスや機密データが漏洩する → 秘匿化、暗号化、アクセス制限、有効期限の設定を行う。
フォローアップの質問と回答
フォローアップ1:トレースを使用しなければならないのはどのような場合ですか?
呼び出しごとの回数、正確な呼び出し関係、または非常に短いパスを把握する必要がある場合にトレースを使用します(オフラインまたは小規模なカナリア環境が望ましい)。低侵入度を維持しなければならない長時間実行中の本番ホットスポットにはサンプリングを使用します。
フォローアップ2:サンプリングで短時間のタスクを見逃した場合はどうしますか?
観測ウィンドウを長くしたりインスタンス数を増やしたりすることで捕捉確率は上がりますが、完全な捕捉は保証されません。ベンチマーク、タイムスタンプ付きログ、またはオフラインでのトレースを活用して相互検証します。サンプル数がゼロであることは実行がゼロであったことを意味しません。
フォローアップ3:なぜフリータスクビルドを記録するのですか?
スケジューリング、ロック競合、スタックの形状はビルドモードによって変化する可能性があります。ビルド情報がないとプロファイルの差異を説明できず、ある最適化が特定のインタプリタ上でのみ有効である可能性を見落とすことになります。
フォローアップ4:プロファイルを使用してどのようにリリースを判定(ゲート)できますか?
負荷、クロック、レート、期間を固定し、単一のサンプルではなく分布を比較します。ホットスポットの割合、テールレイテンシ、またはプロファイラコストが事前定義されたしきい値を超えた場合にのみリリースをブロックし、その他の差分はレビューに回します。