ストーリー
高橋アーキテクトがホワイトボードに2つの線を描いた。
レイテンシ(Latency)
レイテンシとは、リクエストを送ってからレスポンスを受け取るまでの時間です。
レイテンシの構成要素
// APIリクエストのレイテンシ内訳
interface LatencyBreakdown {
dnsLookup: number; // DNS解決: 1-50ms
tcpHandshake: number; // TCP接続: 1-100ms
tlsHandshake: number; // TLS/SSL: 1-100ms
networkTransit: number; // ネットワーク転送: 1-500ms
serverProcessing: number; // サーバー処理: 1-5000ms
responseTransfer: number; // レスポンス転送: 1-1000ms
}
// 典型的なWebアプリのレイテンシ目標
const LATENCY_TARGETS = {
apiCall: 200, // API呼び出し: 200ms以下
pageLoad: 2000, // ページ読み込み: 2秒以下
dbQuery: 50, // DBクエリ: 50ms以下
cacheHit: 5, // キャッシュヒット: 5ms以下
searchResult: 500, // 検索結果: 500ms以下
};
有名な数値(Latency Numbers Every Programmer Should Know)
| 操作 | 時間 | 比喩 |
|---|---|---|
| L1キャッシュ参照 | 0.5ns | 1秒 |
| L2キャッシュ参照 | 7ns | 14秒 |
| メモリ参照 | 100ns | 3分20秒 |
| SSD読み取り | 150μs | 3.5日 |
| HDD読み取り | 10ms | 8ヶ月 |
| 同一DC内ラウンドトリップ | 0.5ms | 11.5日 |
| 大陸間ラウンドトリップ | 150ms | 9.5年 |
スループット(Throughput)
スループットとは、単位時間あたりに処理できるリクエストの数です。
// スループットの計測例
interface ThroughputMetrics {
requestsPerSecond: number; // RPS: 秒間リクエスト数
transactionsPerSecond: number; // TPS: 秒間トランザクション数
bytesPerSecond: number; // BPS: 秒間転送量
}
// スループットの計算
function calculateThroughput(
totalRequests: number,
durationSeconds: number
): number {
return totalRequests / durationSeconds; // RPS
}
// 例: 60秒間に3000リクエスト → 50 RPS
const rps = calculateThroughput(3000, 60); // 50
スループットに影響する要因
// リトルの法則: L = λ × W
// L: 同時処理数, λ: スループット, W: レイテンシ
function littlesLaw(
concurrency: number,
latencySeconds: number
): number {
return concurrency / latencySeconds; // スループット(RPS)
}
// 例: 同時接続100、平均レイテンシ0.2秒
const throughput = littlesLaw(100, 0.2); // 500 RPS
レイテンシとスループットの関係
トレードオフの発生
レイテンシとスループットは独立した指標ですが、相互に影響し合います。
// 負荷が増えるとレイテンシが悪化する典型例
interface LoadProfile {
rps: number; // リクエスト/秒
avgLatency: number; // 平均レイテンシ(ms)
p99Latency: number; // 99パーセンタイルレイテンシ(ms)
}
const loadProfiles: LoadProfile[] = [
{ rps: 100, avgLatency: 50, p99Latency: 100 },
{ rps: 500, avgLatency: 80, p99Latency: 200 },
{ rps: 1000, avgLatency: 150, p99Latency: 500 },
{ rps: 2000, avgLatency: 500, p99Latency: 2000 },
{ rps: 3000, avgLatency: 2000, p99Latency: 10000 }, // 飽和点
];
飽和点(Saturation Point)
システムの処理能力の限界に近づくと、レイテンシが急激に悪化します。この境界が「飽和点」です。
レイテンシ
│ ╱
│ ╱
│ ╱ ← 飽和点を超えると急激に悪化
│ ╱
│───────
└─────────── スループット(RPS)
パーセンタイル(Percentile)
平均値だけでは真のパフォーマンスはわかりません。パーセンタイルで分布を理解します。
function calculatePercentile(
sortedValues: number[],
percentile: number
): number {
const index = Math.ceil((percentile / 100) * sortedValues.length) - 1;
return sortedValues[index];
}
// 使用例
const latencies = [10, 15, 20, 25, 30, 50, 80, 100, 200, 5000];
latencies.sort((a, b) => a - b);
const p50 = calculatePercentile(latencies, 50); // 30ms - 中央値
const p95 = calculatePercentile(latencies, 95); // 200ms - 95%のユーザー
const p99 = calculatePercentile(latencies, 99); // 5000ms - 99%のユーザー
// p99が異常に高い → テールレイテンシ問題
| パーセンタイル | 意味 | 重要度 |
|---|---|---|
| p50(中央値) | 半数のリクエストの体験 | 基本指標 |
| p95 | 大多数のユーザーの体験 | SLA指標 |
| p99 | ほぼ全員の体験 | 品質指標 |
| p99.9 | 最悪ケースに近い | 上位サービス向け |
まとめ
| ポイント | 内容 |
|---|---|
| レイテンシ | リクエストからレスポンスまでの所要時間 |
| スループット | 単位時間あたりの処理量(RPS) |
| リトルの法則 | L = λ × W で3指標が結びつく |
| 飽和点 | 処理能力の限界でレイテンシが急激に悪化 |
| パーセンタイル | 平均値ではなくp50/p95/p99で評価する |
チェックリスト
- レイテンシとスループットの違いを説明できる
- リトルの法則を使ってスループットを計算できる
- パーセンタイルの重要性を理解した
- 飽和点の概念を理解した
次のステップへ
次は「ボトルネックの特定方法」を学びます。CPU、I/O、メモリ、ネットワークのどこが制約になっているかを見極める技術です。
推定読了時間: 25分