Backend Interview: ドライバーのリアルタイム位置情報システム設計
問題¶
何千ものドライバーが毎秒位置情報を更新している。何千もの乗客がリアルタイムで近くのドライバーを探している。このシステムをどう設計するか?
要件の整理¶
機能要件¶
- ドライバーが現在地をリアルタイム送信(例: 5秒ごと)
- 乗客が指定範囲内(例: 半径5km)のドライバー一覧を取得
- ドライバーの位置情報は最新のもので十分
非機能要件¶
- ドライバー数: 例100万人がオンライン
- 書き込み: 100万 ÷ 5秒 = 20万 writes/sec
- 読み込み: 検索QPS × 1,000万乗客 → 数万〜数十万 reads/sec
- レイテンシ: 位置更新は数秒の遅延まで許容、検索は100ms以内
アーキテクチャ設計¶
位置情報の書き込みパス¶
なぜRedisか?
- 20万 writes/secに耐えられる(インメモリで高速)
- GEOADD コマンドで緯度経度を扱える
- GEORADIUS / GEOSEARCH で範囲検索が O(N+log M) でできる
# ドライバーの位置を登録/更新
GEOADD drivers:locations 139.6917 35.6895 "driver:42"
# 渋谷駅から5km以内のドライバーを取得
GEORADIUS drivers:locations 139.7016 35.6581 5 km ASC COUNT 10
乗客の検索パス¶
スケールアウト戦略¶
書き込みのスケール: - Location Update Serviceを複数インスタンスに - ロードバランサーでドライバーIDをハッシュ → 同じドライバーは同じインスタンスへ(スティッキーセッション不要でWebSocket管理が楽) - Redisはクラスタ構成、ドライバーIDでシャーディング
読み込みのスケール: - Query ServiceはステートレスなのでHPA(Horizontal Pod Autoscaler)で増減 - Redis Clusterのread replicaから読む
古い位置情報の削除¶
ドライバーがオフラインになったら位置情報を削除する。
または、TTL付きのキーを使って一定時間更新がなければ自動削除。
ボトルネックと改善点¶
| 問題 | 解決策 |
|---|---|
| Redisの書き込みホットスポット | Geohashでエリア分割、エリアごとにRedisインスタンス |
| 大都市圏での検索遅延 | QuadTree / S2 Geometryで空間インデックスを別途構築 |
| WebSocket接続の維持 | Connection Service + メッセージキュー(Kafka)で切り離す |
面接でのポイント¶
- まず規模を計算する(writes/sec、reads/sec)
- なぜRedisを選んだか説明できる(GEO系コマンド、インメモリ速度)
- 単一障害点(Single Point of Failure)を意識してクラスタ構成を提案
- データの鮮度(位置情報は古くて良い?)とトレードオフを議論