パフォーマンス
パフォーマンスは機能です。平均ではなくP99を基準に設計し、最適化の前に測定してください。直感は、時間がどこで消費されているかについてほぼ常に間違っています。
ルール
- 最適化の前にプロファイリングを行う。 ホットパスを推測すると日数を無駄にします。まずフレームグラフ、APMトレース、または
EXPLAIN ANALYZEを使用してください。 - N+1クエリを撲滅する。 サービスコードにおける最大のレイテンシ要因です。行ごとのルックアップよりも、結合、バッチフェッチ、または
IN (...)を優先してください。 - すべてのリストエンドポイントをページネーションする。 制限のない結果セットは、最終的にPodのOOMやDBの飽和を引き起こします。大規模テーブルにはデフォルトでカーソルベースのページネーションを使用してください。
- すべてのカラムではなく、クエリ述語にインデックスを付ける。 追加のインデックスはすべて書き込みを遅くし、ストレージを肥大化させます。既知のクエリが必要とする場合にのみインデックスを追加してください。
- 必要なカラムのみを射影する。
SELECT *を広いDTOに使用すると、ネットワーク、メモリ、GCを無駄にします。リストAPIには狭い射影を返してください。 - 読み取り負荷が高く、冪等性のあるデータをキャッシュする。 ただし、キャッシュを追加する 前に 無効化戦略を決定してください。退避計画のないキャッシュはバグの温床です。
- 接続プールとスレッドプールのサイズを明示的に設定する。 デフォルトはあなたのワークロードに適していることはほとんどありません。ダウンストリームの容量に合わせてサイズを設定し、上流からではなく調整してください。
- アウトバウンドコールをバッチ化する。 100アイテムを含む1つのリクエストは、1アイテムずつ100回のリクエストよりも、レイテンシ、CPU、DB接続のすべての面で優れています。
- リモートコールの同期的な連鎖を避ける。 レイテンシは複合的に増大します。並列にファンアウトするか、処理を非同期に移行してください。
- ペイロードを小さく保つ。 レスポンスを圧縮し、未使用のフィールドを削除し、重要な箇所ではバイナリプロトコル(gRPC、Protobuf)を使用してください。
危険信号
- DBをループでクエリしている処理。
- 「全レコード」を返すAPI。
- TTLも無効化もないキャッシュ。
- 本番環境でフレームワークデフォルトのスレッドプール/コネクションプール設定。
- 平均のみ(P95/P99なし)を表示するレイテンシダッシュボード。