この事例を読むべき理由
ライブスポーツ中継のように、トラフィックが秒単位でゼロから数百万に急増するワークロードでは、スケーリングそのものよりも「スケールアウトが効いていないように見える」状況の方が厄介です。NLBを2台から6台に増やしても500エラーが減らないなら、それはサーバの問題ではなくDNSルーティングポリシーの問題である可能性が高いです。
本記事は、モバイルオブザーバビリティ基盤bitdriftがT20ワールドカップのクリケット中継中に1億2100万台の同時gRPC接続を処理した実例を扱います。ポイントはわずか1つの設定変更でした。コードもアーキテクチャも変更していません。
根拠資料: AWS Architecture Blog — How bitdrift scaled to 121 million concurrent gRPC connections
本記事を読み終えると、以下を判断できるようになります。
- 自サービスのDNSルーティングポリシーがpersistent connection環境でボトルネックになり得るか
- CloudFront + 複数NLB構成でなぜスケールアウトが無効化されるのか
- Multi-Value Answerルーティングへ切り替える際の実務チェックリスト

問題の本質: Weightedルーティングは「1クエリにつきIP1つ」しか返さない
多くのチームがRoute 53のWeightedルーティングを「負荷分散」と理解しています。しかし実際の挙動は異なります。WeightedルーティングはDNSクエリ1件につきIPを1つしか返しません。重みは「どのIPを引くかの確率」であり、「複数IPを同時に通知する仕組み」ではありません。
これがCloudFront規模で発生すると、次のような連鎖が起きます。
- CloudFrontエッジノードがoriginドメインをresolve → IPを1つ取得
- そのIPをTTL(60秒)の間キャッシュ
- すべてのエッジノードが同じタイミングで同じIPに集中
- 該当NLB1台がthundering herdで過負荷
- NLBを6台に増やしても、依然としてクエリあたり1IPしか返らないため分散しない
ここで決定的な違いがあります。HTTPはリクエストが短命ですが、gRPCは接続が長命です。接続が確立した瞬間にresolveされたoriginにそのまま居座るため、statelessトラフィックでは「やや偏る程度」で済むDNS設定が、persistent connectionでは致命的な過負荷に増幅されます。
解決策: Multi-Value Answerルーティング
Multi-Value AnswerルーティングはDNSクエリ1件につき最大8個のIPを返し、レコード単位のヘルスチェックを内蔵します。CloudFrontエッジノードは最初のresolve時点から複数originへ接続を分散できます。
# 既存のWeightedレコードを確認
aws route53 list-resource-record-sets \
--hosted-zone-id Z0123456789ABCDEFGHIJ \
--query "ResourceRecordSets[?Name=='origin.example.com.']"
# 各NLB用のヘルスチェックを作成 (Multi-Valueではヘルスチェック必須)
aws route53 create-health-check --caller-reference "nlb-1-$(date +%s)" \
--health-check-config '{
"Type": "TCP",
"FullyQualifiedDomainName": "nlb-1-abcdef.elb.us-east-1.amazonaws.com",
"Port": 443,
"RequestInterval": 10,
"FailureThreshold": 3
}'
# Multi-Value Answerレコードを作成 (IPベースのAレコード、Alias不可)
aws route53 change-resource-record-sets \
--hosted-zone-id Z0123456789ABCDEFGHIJ \
--change-batch '{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "origin.example.com",
"Type": "A",
"SetIdentifier": "nlb-1",
"MultiValueAnswer": true,
"TTL": 60,
"ResourceRecords": [{"Value": "203.0.113.10"}],
"HealthCheckId": "abcdef12-3456-7890-abcd-ef1234567890"
}
}]
}'
必ず守るべき制約
- Aliasレコードは使用不可。 Multi-Value AnswerはIPベースのAレコードのみ対応します。NLBの各AZにElastic IPを割り当てる必要があります。
- ALBはこのパターンに使えません。 ALBは固定IPをサポートしていないためです。
- 同じレコード名にルーティングポリシーを混在させられません。 Multi-Valueレコード検証後に既存のWeightedレコードは削除が必要です。
- TTLは60秒程度に低く保ってください。フェイルオーバーが高速化します。
切り替え前後の比較は以下の通りです。
| 項目 | Before (Weighted) | After (Multi-Value) |
|---|---|---|
| DNSクエリあたりの返却IP | 1個 | 最大8個 |
| origin分散 | TTL期間中は単一NLBに集中 | 初回resolveから複数NLBに分散 |
| 急増時の挙動 | thundering herd、単一NLBが過負荷 | 均等分散、単一障害点なし |
| ピーク時のエラー | CloudFront ↔ NLB間で5xx多発 | サーバサイドエラー0件 |
| 顧客側の変更 | — | DNS設定変更のみ |

実測データが示すもの
この事例で最も印象的なのは、**「コードもアーキテクチャも変えていない」**という事実です。純粋にRoute 53のルーティングポリシーのみを差し替え、結果は次の通りでした。
| 指標 | Before (3/1〜2) | After (3/7〜9) | 改善 |
|---|---|---|---|
| ピーク5xxエラー率 | 79.80% | 0.033% | 99.96%削減 (約2,418倍) |
| 平均5xxエラー率 | 1.87% | 0.003% | 99.84%削減 (約623倍) |
| サーバサイド障害 | 複数origin失敗 | 0件 | 100%排除 |
| 同時接続デバイス (3/8) | — | 1億2100万台 | ゼロエラー処理 |
| ピークRPS | 563K | 164K | イベント規模の差 |
特に注目すべきは、2月27日のイベントで約80%のリクエストがHTTP 500で失敗した点です。3月1日にはNLBを4台に増やしたにもかかわらず問題が再発しました。Weightedルーティングが依然としてIPを1つしか返さなかったため、originを増やす行為自体が無意味だったのです。
この技術の限界と注意点
- Multi-Valueが万能ではありません。 DNSベースの分散であるため、クライアント側のDNSキャッシュやリゾルバの挙動により実際の分布が偏る可能性があります。
- ヘルスチェックの遅延に注意。 Request intervalを10秒(Fast)にしても、unhealthy判定まで最低数十秒かかります。瞬間的な障害には依然として脆弱です。
- Elastic IPの管理負担。 NLBの各AZにEIPを付与する必要があり、IP管理ポリシーが求められます。オートスケーリングとは相性が良くありません。
- HTTPワークロードでは効果が限定的。 短命なリクエスト-レスポンスパターンでは、従来のWeightedルーティングでも大きな問題にならないことがあります。persistent connection(gRPC、WebSocket)で特に致命的である点を覚えておいてください。
- 日本のエンタープライズ環境では、事前審査やセキュリティレビューのプロセスにより、障害発生中の緊急DNS変更が難しい場合があります。平時のうちにMulti-Value切り替えを検証しておくのが安全です。
次のステップ学習方向
- Route 53のルーティングポリシー4種比較 — Simple、Weighted、Latency、Multi-Value Answer、Failoverの実際の挙動差を検証してみてください。
- gRPCロードバランシングの深掘り — クライアントサイドLB(例: gRPCのround_robin)とサーバサイドLBのトレードオフを整理しておくと有用です。
- CloudFront originフェイルオーバー設計 — Multi-ValueとOrigin Groupを組み合わせた二重防御戦略を検討してください。
フロントエンド側のスケーリング課題も並行して見ているなら、Interop 2026で注目すべきCSS新機能まとめも参考にしてください。サーバレス/エッジ配信パイプラインを運用中の場合は、Vercel Node.js 20サポート終了マイグレーションガイドも早めに確認しておくと良いでしょう。

まとめ: スケールアウトが効かない時に疑うべきもの
本件の教訓は明確です。
- DNSルーティングポリシーは極限スケールにおいてアーキテクチャ決定と同等に重要です。 WeightedとMulti-Value Answerの差は単なる好みの問題ではありません。
- persistent connectionはDNS問題を増幅させます。 HTTPでは無視できる程度の偏りが、gRPC/WebSocketではサービス全体の障害に繋がります。
- スケールアウトが効かないなら、まずルーティング層を疑ってください。 NLBを2台から6台に増やしてもエラーが変わらないなら、それはoriginの問題ではありません。
- 事前キャパシティレビューを習慣化してください。 ライブイベント中に根本原因を分析するのは地獄です。
もし今CloudFrontの背後に複数NLBを置いてgRPCやWebSocketを配信しているなら、今日すぐにRoute 53コンソールを開いてルーティングポリシーを確認することをお勧めします。設定1行が1億台の接続を支えることも、あるいは崩壊させることもあります。