Case Study: Design Google Maps

“Ngày xưa, muốn đi từ Sài Gòn ra Hà Nội, ông bà phải trải bản đồ giấy ra sàn, dùng ngón tay đo theo quốc lộ 1A. Hôm nay, một cái chạm vào màn hình — Google Maps tính cho bạn đường nhanh nhất trong 0.5 giây. Đằng sau sự ‘đơn giản’ đó là một trong những hệ thống phức tạp nhất thế giới.”

Tags: system-design case-study google-maps navigation geo alex-xu-vol2 Student: Hieu Prerequisite: Tuan-02-Back-of-the-envelope · Tuan-03-Networking-DNS-CDN · Tuan-08-Message-Queue Lien quan: Case-Design-Proximity-Service · Tuan-07-Database-Sharding-Replication · Tuan-06-Cache-Strategy · Tuan-13-Monitoring-Observability · Tuan-14-AuthN-AuthZ-Security · Tuan-15-Data-Security-Encryption Reference: Alex Xu, System Design Interview Volume 2 — Chapter 2: Nearby Friends / Google Maps


Context & Why — Từ bản đồ giấy đến bản đồ số thông minh

Analogy: Mê cung thành phố

hãy tưởng tượng bạn đứng giữa một mê cung khổng lồ — mê cung đó chính là mạng lưới đường phố của một thành phố. Bản đồ giấy ngày xưa giống như bạn cầm một tấm ảnh chụp từ trên cao, rồi tự mình đo đường bằng mắt. Vấn đề là:

  • Bản đồ giấy không biết traffic — bạn không biết đường nào đang kẹt xe
  • Bản đồ giấy không cập nhật — con đường mới xây xong tháng trước chưa có trên bản đồ
  • Bản đồ giấy không tính được ETA — bạn chỉ ước lượng bằng cảm giác
  • Bản đồ giấy không zoom được — muốn xem chi tiết phải mua bản đồ tỉ lệ khác

Google Maps giải quyết tất cả những vấn đề này bằng cách số hóa toàn bộ bản đồ thế giới, chia nhỏ thành hàng tỉ tile nhỏ, và sử dụng algorithm để tìm đường nhanh nhất trong thời gian thực.

Tại sao bài này quan trọng?

Khía cạnhLý do
Geo-spatial dataĐây là nền tảng cho mọi ứng dụng location-based (Grab, Uber, delivery apps)
Scale khổng lồ1 billion DAU, hàng chục triệu navigation requests/ngày
Real-time processingTraffic data thay đổi mỗi giây, ETA phải cập nhật liên tục
Pre-computationKhông thể tính routing on-the-fly cho mọi request — cần pre-compute
CDN & CachingMap tiles là bài toán CDN kinh điển — Tuan-03-Networking-DNS-CDN
Stream processingLocation updates từ hàng tỉ device — Tuan-08-Message-Queue

Step 1 — Understand the Problem & Establish Design Scope

1.1 Clarifying Questions (Câu hỏi làm rõ)

Câu hỏiTrả lờiGhi chú
Hệ thống cần hỗ trợ những feature chính nào?Map rendering, navigation (routing + ETA), location update3 pillars chính
Scale bao lớn?~1 Billion DAUQuy mô Google-level
Cần hỗ trợ real-time traffic?Có — traffic overlay trên map và ETA tính toánStream processing
Map data từ đâu?Satellite imagery, street-level photography, user contributions, third-party dataKhông thiết kế phần thu thập, chỉ dùng data có sẵn
Hỗ trợ bao nhiêu loại phương tiện?Xe hơi, xe máy, đi bộ, xe đạp, transit (bus/tàu)Mỗi loại có routing algorithm riêng
Offline support?Có — download map tiles cho một regionMobile-first concern
Turn-by-turn navigation?Có — real-time voice guidanceStreaming direction updates
Search (geocoding)?Có — tìm địa điểm bằng tên, địa chỉGeocoding + reverse geocoding

1.2 Functional Requirements (Yêu cầu chức năng)

  • FR1: Map Rendering — hiển thị bản đồ tại bất kỳ vị trí nào trên thế giới, hỗ trợ zoom in/out (21 zoom levels)
  • FR2: Navigation/Routing — tìm đường đi ngắn nhất hoặc nhanh nhất giữa 2 điểm (hoặc nhiều điểm), tính ETA
  • FR3: Location Update — nhận và lưu vị trí hiện tại của user (GPS coordinates) để phục vụ traffic và personalization
  • FR4: Geocoding — chuyển đổi giữa địa chỉ text và tọa độ (lat/lng) và ngược lại
  • FR5: Traffic Overlay — hiển thị tình trạng giao thông real-time trên bản đồ (xanh/vàng/đỏ)
  • FR6: Alternative Routes — đề xuất 2-3 tuyến đường thay thế với ETA khác nhau
  • FR7: Turn-by-turn Navigation — hướng dẫn chi tiết từng bước trong quá trình di chuyển

1.3 Non-Functional Requirements (Yêu cầu phi chức năng)

Yêu cầuMục tiêuGiải thích
Availability99.99%Navigation là safety-critical — user đang lái xe trên cao tốc
Latency (Map)Tile load < 200msUser kỳ vọng bản đồ hiển thị gần như tức thì khi scroll/zoom
Latency (Routing)Route calculation < 3sBao gồm tính toán trên server + network round trip
Scalability1B DAU, 33M location updates/s peakXem phần Estimation bên dưới
Accuracy (ETA)Sai lệch < 10% so với thực tếETA sai = user mất tin tưởng
Freshness (Traffic)Cập nhật mỗi 30-60 giâyTraffic cũ 5 phút là vô nghĩa
Offline SupportDownload map tiles cho offline useMobile users ở vùng yếu signal
Data Durability99.999999999% (eleven 9s)Map data là tài sản core — mất là mất tất cả

Step 2 — High-Level Design

2.1 Ba service chính

Google Maps có thể chia thành 3 service chính (theo Alex Xu):

ServiceNhiệm vụInputOutput
Location ServiceThu thập và lưu vị trí của userGPS coordinates từ mobile clientLocation history, real-time traffic data
Navigation ServiceTìm đường và tính ETAOrigin + Destination + preferencesRoute (list of coordinates), ETA, turn-by-turn instructions
Map Rendering ServicePhục vụ map tiles cho client hiển thịTile coordinates (zoom level, x, y)Image tiles hoặc vector tiles

Ngoài ra còn có các supporting services:

ServiceNhiệm vụ
Geocoding ServiceChuyển đổi địa chỉ > tọa độ
Traffic ServiceXử lý và aggregation traffic data real-time
ETA ServiceTính toán ETA dựa trên historical + real-time + ML
Search/POI ServiceTìm kiếm địa điểm (Points of Interest)

2.2 High-Level Architecture Diagram

graph TB
    subgraph Clients
        MobileApp["Mobile App<br/>(iOS/Android)"]
        WebApp["Web Browser"]
    end

    subgraph "API Gateway & Load Balancer"
        APIGW["API Gateway<br/>Rate Limiting, Auth, Routing"]
    end

    subgraph "Core Services"
        LocSvc["Location Service<br/>(Write-heavy)"]
        NavSvc["Navigation Service<br/>(Compute-heavy)"]
        MapSvc["Map Rendering Service<br/>(Read-heavy)"]
        GeoSvc["Geocoding Service"]
        TrafficSvc["Traffic Service"]
        ETASvc["ETA Service"]
        SearchSvc["Search/POI Service"]
    end

    subgraph "Data Layer"
        Kafka["Apache Kafka<br/>Location Stream"]
        LocDB["Location History DB<br/>(Cassandra/TimescaleDB)"]
        RoadGraph["Road Graph DB<br/>(Adjacency list, pre-computed)"]
        TileStorage["Tile Storage<br/>(Object Storage — S3)"]
        GeoDB["Geocoding DB<br/>(Elasticsearch)"]
        TrafficDB["Traffic DB<br/>(Time-series)"]
    end

    subgraph "CDN Layer"
        CDN["Tile CDN<br/>(CloudFront/Akamai)<br/>Global Edge PoPs"]
    end

    subgraph "ML Pipeline"
        MLPipeline["ML Model<br/>ETA Prediction<br/>Traffic Prediction"]
    end

    MobileApp --> APIGW
    WebApp --> APIGW
    MobileApp -->|"Tile requests"| CDN

    APIGW --> LocSvc
    APIGW --> NavSvc
    APIGW --> MapSvc
    APIGW --> GeoSvc
    APIGW --> SearchSvc

    LocSvc -->|"Publish location"| Kafka
    Kafka --> TrafficSvc
    Kafka --> LocDB
    TrafficSvc --> TrafficDB
    TrafficSvc --> MLPipeline

    NavSvc --> RoadGraph
    NavSvc --> ETASvc
    ETASvc --> TrafficDB
    ETASvc --> MLPipeline

    MapSvc --> TileStorage
    TileStorage --> CDN

    GeoSvc --> GeoDB
    SearchSvc --> GeoDB

2.3 Request Flow — 3 luồng chính

Luồng 1: Map Rendering (User mở app, xem bản đồ)

  1. Client tính toán cần tiles nào dựa trên viewport (vị trí + zoom level)
  2. Kiểm tra local cache (mobile) hoặc browser cache (web)
  3. Nếu cache miss → request tới CDN
  4. Nếu CDN cache miss → request tới Map Rendering Service → lấy từ Tile Storage (S3)
  5. CDN cache tile → trả về client
  6. Client render tiles ghép lại thành bản đồ hoàn chỉnh

Luồng 2: Navigation (User bấm “Chỉ đường”)

  1. Client gửi origin (vị trí hiện tại) + destination + preferences (xe hơi/đi bộ/…)
  2. API Gateway route tới Navigation Service
  3. Navigation Service gọi Geocoding Service (nếu user nhập địa chỉ text)
  4. Navigation Service query Road Graph DB để tìm route
  5. Navigation Service gọi ETA Service để tính thời gian cho mỗi route
  6. ETA Service lấy traffic data real-time + historical patterns + ML prediction
  7. Trả về 2-3 routes với ETA, khoảng cách, turn-by-turn instructions

Luồng 3: Location Update (Background, liên tục)

  1. Mobile client thu thập GPS coordinates (mỗi 1-3 giây khi navigating, mỗi 15-30 giây khi idle)
  2. Client batch nhiều data points lại → gửi 1 request mỗi 15-30 giây (tiết kiệm battery + bandwidth)
  3. Location Service nhận batch → publish lên Kafka
  4. Kafka consumers: (a) Lưu vào Location History DB, (b) Feed vào Traffic Service để tính real-time traffic

Step 3 — Deep Dive

3.1 Map Tiles — Chia bản đồ thành miếng ghép hình

Khái niệm Tile Pyramid

hãy tưởng tượng bạn có một bức ảnh vệ tinh chụp toàn bộ Trái Đất. Bức ảnh này có độ phân giải cực kỳ lớn — nếu in ra sẽ to bằng một sân bóng đá. Hiển thị nguyên bức ảnh này trên điện thoại là bất khả thi (quá nặng, quá lớn). Giải pháp: cắt nhỏ bức ảnh thành nhiều mảnh vuông (tiles), và chỉ load những mảnh mà user đang nhìn thấy.

21 Zoom Levels (từ 0 đến 20):

Zoom LevelSố tilesMỗi tile bao phủSử dụng
01 tile (1x1)Toàn bộ thế giớiOverview toàn cầu
14 tiles (2x2)1/4 thế giớiNhìn các lục địa
216 tiles (4x4)1/16 thế giớiNhìn các quốc gia lớn
364 tiles (8x8)Nhìn nhóm quốc gia
10~1 triệu tiles~150m x 150mNhìn thành phố
15~1 tỉ tiles~5m x 5mNhìn khu phố, đường
20~1 ngàn tỉ tiles~0.15m x 0.15mNhìn chi tiết nhà, vỉa hè

Công thức tính số tiles tại mỗi zoom level:

Ví dụ:

Tile Pyramid Diagram

graph TD
    subgraph "Tile Pyramid — Zoom Levels"
        Z0["Zoom 0<br/>1 tile<br/>Toan bo the gioi"]
        Z1["Zoom 1<br/>4 tiles (2x2)<br/>Cac luc dia"]
        Z2["Zoom 2<br/>16 tiles (4x4)<br/>Cac quoc gia"]
        Z10["Zoom 10<br/>~1M tiles<br/>Thanh pho"]
        Z15["Zoom 15<br/>~1B tiles<br/>Duong pho"]
        Z20["Zoom 20<br/>~1T tiles<br/>Chi tiet nha"]
    end

    Z0 -->|"Moi tile chia thanh 4"| Z1
    Z1 -->|"Moi tile chia thanh 4"| Z2
    Z2 -->|"..."| Z10
    Z10 -->|"..."| Z15
    Z15 -->|"..."| Z20

    style Z0 fill:#e1f5fe
    style Z1 fill:#b3e5fc
    style Z2 fill:#81d4fa
    style Z10 fill:#4fc3f7
    style Z15 fill:#29b6f6
    style Z20 fill:#0288d1

Vector Tiles vs Raster Tiles

Đặc điểmRaster TilesVector Tiles
FormatPNG/JPEG imageProtocol Buffers (binary data)
Kích thước20-100 KB/tile5-30 KB/tile (nhỏ hơn 3-5x)
RenderingServer render sẵn → client chỉ hiển thịClient render từ data (GPU-accelerated)
ZoomMờ khi zoom giữa 2 level (pixelated)Mượt mà ở mọi mức zoom (smooth)
CustomizationKhông — ảnh đã render cố địnhCó — client tự style (dark mode, highlight roads, etc.)
Offline sizeLớnNhỏ hơn nhiều
CPU clientThấp (chỉ hiện ảnh)Cao hơn (phải render)
BandwidthLớn hơnTiết kiệm hơn

Xu hướng hiện tại: Google Maps, Apple Maps, Mapbox đều chuyển sang vector tiles. Lý do chính: bandwidth tiết kiệm + smooth zoom + dynamic styling (dark mode khi lái xe ban đêm).

Tại sao vector tiles thắng? hãy nghĩ thế này: raster tile giống như bạn chụp ảnh bản đồ rồi gửi qua. Vector tile giống như bạn gửi data (đường này ở đâu, nhà này hình gì, tên đường là gì) rồi để điện thoại tự vẽ. Gửi data nhẹ hơn gửi ảnh, và điện thoại ngày nay đủ mạnh để vẽ rất nhanh.

Tile Addressing — Cách xác định tile nào cần load

Mỗi tile được xác định bởi 3 tham số: (zoom, x, y)

  • zoom: zoom level (0-20)
  • x: column index (0 đến )
  • y: row index (0 đến )

URL pattern:

https://tiles.maps.example.com/{zoom}/{x}/{y}.pbf

Ví dụ: https://tiles.maps.example.com/15/26177/15123.pbf — tile ở zoom 15, cột 26177, hàng 15123.

Client tính toán tiles cần hiển thị dựa trên:

  1. Viewport (màn hình đang nhìn thấy phạm vi nào)
  2. Zoom level hiện tại
  3. Pre-fetch tiles xung quanh viewport (anticipatory loading)

3.2 Map Rendering — Từ tile đến bản đồ trên màn hình

Tile CDN Architecture

Map tiles là static content (ít thay đổi — chỉ cập nhật khi có road mới hoặc building mới). Đây là bài toán CDN kinh điển — tham khảo Tuan-03-Networking-DNS-CDN.

Multi-layer caching strategy:

LayerNơi lưuCache DurationHit Ratio (ước tính)
L1: Client CacheMobile app local storage / Browser cache30 ngày (tiles ít thay đổi)~70-80%
L2: CDN EdgeCloudFront/Akamai edge PoPs7-30 ngày~95-99% của requests còn lại
L3: CDN Origin ShieldRegional origin cache30 ngày~99% của requests còn lại
L4: Origin (S3)Object storagePermanent100% (source of truth)

Key insight: Với 4 layers này, chỉ khoảng 0.01-0.1% tổng request thực sự chạm tới origin storage. Đây là lý do tại sao map rendering có thể phục vụ hàng tỉ request/ngày mà chỉ cần vài chục origin servers.

Tính toán cache hit ratio tổng thể:

Chỉ 7.5 trong 100,000 requests thực sự phải lấy tile từ origin. Đây là sức mạnh của multi-layer caching.

Progressive Loading

Khi user zoom từ level 10 xuống level 15, bản đồ không đổi tức thì — nó progressive load:

  1. Hiển thị tiles cũ (level 10) đang có trong cache — upscale (phóng to, hơi mờ)
  2. Request tiles mới (level 15) từ CDN
  3. Khi tiles mới về → fade-in thay thế tiles cũ → bản đồ sắc nét dần

Kỹ thuật này gọi là “show stale, fetch fresh” — user luôn nhìn thấy gì đó thay vì màn hình trắng, tạo cảm giác instant response.

Tile Pre-rendering Pipeline

Map tiles được pre-render offline (không render on-the-fly khi user request):

graph LR
    RawData["Raw Map Data<br/>(Roads, Buildings,<br/>POIs, Terrain)"]
    Pipeline["Tile Rendering Pipeline<br/>(Batch processing)"]
    TileStore["Tile Storage<br/>(S3 / GCS)"]
    CDN["CDN<br/>Global Distribution"]
    Client["Client<br/>Mobile / Web"]

    RawData -->|"Nightly batch +<br/>incremental updates"| Pipeline
    Pipeline -->|"Pre-rendered tiles<br/>21 zoom levels"| TileStore
    TileStore -->|"Origin"| CDN
    CDN -->|"Edge cache"| Client

Khi nào re-render tiles?

  • Scheduled: Mỗi tuần hoặc mỗi tháng — cập nhật roads mới, buildings mới
  • Incremental: Chỉ re-render tiles bị ảnh hưởng bởi thay đổi (không render lại toàn bộ)
  • Priority: Khu vực đông dân (thành phố lớn) re-render thường xuyên hơn khu vực hoang vũ

3.3 Location Service — Thu thập vị trí từ hàng tỉ device

Bài toán

Mỗi giây, hàng triệu device gửi vị trí của mình (latitude, longitude, timestamp, speed, heading) về server. Đây là write-heavy workload với volume cực lớn.

Batching Strategy

Gửi GPS coordinates mỗi giây là lãng phí (tốn battery, tốn bandwidth, server không cần độ chi tiết). Thay vào đó:

Trạng thái userTần suất gửiLý do
Đang navigate (lái xe)Batch mỗi 15 giây (gồm 15 data points)Cần độ chính xác cao để cập nhật traffic
App mở nhưng không navigateBatch mỗi 30 giây (gồm 5-10 data points)Tiết kiệm battery, vẫn cập nhật traffic
App chạy backgroundBatch mỗi 5 phút hoặc không gửiTối ưu battery
App đóngKhông gửiKhông cần

Payload của một batch:

FieldTypeSizeMô tả
user_idstring16 bytesAnonymized ID
timestamps[]int64 array8 bytes x NUnix timestamp mỗi data point
latitudes[]double array8 bytes x NVĩ độ
longitudes[]double array8 bytes x NKinh độ
speeds[]float array4 bytes x NTốc độ (m/s)
headings[]float array4 bytes x NHướng di chuyển (0-360 độ)
accuracyfloat4 bytesĐộ chính xác GPS (mét)
transport_modeenum1 byteCar, bike, walk, etc.

Với N = 15 data points, payload khoảng 700 bytes — rất nhẹ.

Ingestion Pipeline

graph LR
    subgraph "Millions of Devices"
        D1["Device 1"]
        D2["Device 2"]
        DN["Device N"]
    end

    subgraph "Ingestion Layer"
        LB["Load Balancer"]
        LS1["Location Service<br/>Instance 1"]
        LS2["Location Service<br/>Instance 2"]
        LSN["Location Service<br/>Instance N"]
    end

    subgraph "Message Queue"
        K["Apache Kafka<br/>Partitioned by<br/>geo-region"]
    end

    subgraph "Consumers"
        C1["Traffic Aggregator<br/>(Real-time)"]
        C2["Location History<br/>Writer (Batch)"]
        C3["ML Feature<br/>Pipeline"]
    end

    subgraph "Storage"
        TSDB["Location History<br/>Cassandra / TimescaleDB"]
        TrafficStore["Traffic Store<br/>Redis + Time-series DB"]
    end

    D1 --> LB
    D2 --> LB
    DN --> LB
    LB --> LS1
    LB --> LS2
    LB --> LSN
    LS1 --> K
    LS2 --> K
    LSN --> K
    K --> C1
    K --> C2
    K --> C3
    C1 --> TrafficStore
    C2 --> TSDB

Tại sao dùng Kafka? (Tham khảo Tuan-08-Message-Queue)

Lý doGiải thích
DecoupleLocation Service chỉ cần ghi vào Kafka — không cần biết ai sẽ đọc
BufferNếu Traffic Aggregator bị chậm, Kafka giữ data — không mất
Multiple consumersCùng một location event được đọc bởi Traffic Aggregator, History Writer, ML Pipeline — fan-out
PartitioningPartition theo geo-region → các consumer xử lý song song
ThroughputKafka xử lý được hàng triệu events/giây trên một cluster — phù hợp với 33M updates/s
DurabilityData được replicate, không mất khi node chết

Location History Storage

Lựa chọn database: Cassandra hoặc TimescaleDB

Tiêu chíCassandraTimescaleDB
Data modelWide-columnRelational (PostgreSQL extension)
Write throughputCực cao (hàng triệu writes/s)Cao (trăm nghìn writes/s)
Time-series queryCần thiết kế schema cẩn thậnBuilt-in time-series functions
CompressionTốt (50-70%)Rất tốt (90%+ với columnar compression)
ScaleHorizontal (thêm node)Horizontal (distributed hypertables)

Schema (Cassandra):

ColumnTypeMô tả
user_idUUIDPartition key — phân tán data theo user
timestampTIMESTAMPClustering key — sắp xếp theo thời gian
latDOUBLEVĩ độ
lngDOUBLEKinh độ
speedFLOATTốc độ
headingFLOATHướng
accuracyFLOATĐộ chính xác GPS

Partition key = user_id → tất cả location history của 1 user nằm trên cùng partition → query “lịch sử di chuyển của user X trong 7 ngày qua” chỉ cần đọc 1 partition.

TTL (Time-to-Live): Location history chỉ giữ 30-90 ngày → tự động xóa data cũ → tiết kiệm storage.


3.4 Navigation/Routing — Tìm đường trong mê cung

Đây là trái tim của Google Maps — và cũng là phần phức tạp nhất.

Road Network là một Weighted Graph

toàn bộ mạng lưới đường giao thông có thể biểu diễn như một đồ thị có trọng số (weighted graph):

Khái niệm đồ thịTương ứng trong bản đồ
Node (đỉnh)Giao lộ (intersection), điểm uốn của đường
Edge (cạnh)Đoạn đường nối 2 giao lộ
Weight (trọng số)Thời gian di chuyển (tính bằng giây/phút), KHÔNG phải khoảng cách

Tại sao weight là thời gian, không phải khoảng cách? Vì user muốn đến nhanh nhất, không phải ngắn nhất. Đường cao tốc 50km có thể nhanh hơn đường tắt 10km nếu đường tắt kẹt xe.

Quy mô của road graph:

Thông sốGiá trị ước tính
Số node (intersections) toàn cầu~500 triệu
Số edge (road segments) toàn cầu~1 tỉ
Average edges per node~4 (mỗi giao lộ thường có 3-5 nhánh)
Data size (adjacency list)~100 GB (compressed)

Tiến hóa của Routing Algorithm

Giai đoạn 1: Dijkstra’s Algorithm

  • Tìm đường ngắn nhất từ 1 điểm đến tất cả các điểm khác
  • Độ phức tạp: với priority queue
  • Vấn đề: Với 500M nodes, Dijkstra duyệt qua hàng triệu nodes trước khi tìm được đường — quá chậm cho real-time (có thể mất vài giây)

Giai đoạn 2: A Algorithm*

  • Cải tiến Dijkstra bằng heuristic — ưu tiên duyệt nodes theo hướng về đích
  • Heuristic: Khoảng cách đường chim bay (haversine distance) từ node hiện tại đến đích
  • Nhanh hơn Dijkstra ~2-5x vì loại bỏ nhiều nodes không cần thiết
  • Vấn đề: Vẫn chậm khi route dài (Sài Gòn → Hà Nội) vì graph quá lớn

Giai đoạn 3: Contraction Hierarchies (CH) — Pre-computation là chìa khóa

Đây là breakthrough giúp Google Maps tìm đường trong milliseconds thay vì seconds.

Ý tưởng cốt lõi: Pre-compute “shortcuts” trong graph.

BướcMô tảAnalogy
1. Xếp hạng nodesMỗi node được gán một “importance level” — giao lộ lớn quan trọng hơn giao lộ nhỏQuốc lộ quan trọng hơn hẻm
2. Contract nodesBắt đầu từ node ít quan trọng nhất, “loại bỏ” nó và thêm shortcut edges nối các node lân cậnLoại bỏ các hẻm nhỏ, thêm shortcut “từ giao lộ A đến giao lộ C, mất 5 phút”
3. Xây hierarchySau khi contract hết, ta có một hierarchy graph — level thấp là đường nhỏ, level cao là đường lớnGiống như bản đồ chỉ có quốc lộ + cao tốc
4. QueryTìm đường = search từ origin lên hierarchy + search từ destination lên hierarchy → gặp nhau ở giữa”Lật xe ra đường lớn gần nhất → đi đường lớn → rẽ vào đường nhỏ gần đích”

Hiệu quả:

Aha Moment: Pre-computation là lý do Google Maps trả lời route gần như tức thì. Việc contract graph mất vài giờ để tính (chạy offline), nhưng mỗi query chỉ mất < 1 millisecond. Trade-off kinh điển: offline compute time ↔ online query speed.

Nhưng pre-computation có vấn đề: Khi traffic thay đổi (kẹt xe), edge weights thay đổi → pre-computed shortcuts không còn chính xác. Giải pháp: Routing Tiles (xem bên dưới).

Routing Tiles — Partition Road Graph

Thay vì lưu toàn bộ road graph trong 1 cục, Google chia graph thành nhiều routing tiles (tương tự map tiles nhưng cho road data):

LevelTile bao phủChứa gìSử dụng
Level 0 (Local)~1km x 1kmĐường nhỏ, hẻm, ngõRouting trong phạm vi khu phố
Level 1 (Regional)~10km x 10kmĐường chính, tỉnh lộRouting trong thành phố
Level 2 (Country)~100km x 100kmQuốc lộ, cao tốcRouting liên tỉnh
Level 3 (Global)~1000km x 1000kmCao tốc quốc tếRouting quốc tế

Routing algorithm với tiles:

  1. Origin nằm trong tile A (local level) → load tile A
  2. Destination nằm trong tile B (local level) → load tile B
  3. Tìm đường trong tile A từ origin đến boundary của tile
  4. Tìm đường giữa boundaries bằng higher-level tiles (regional/country)
  5. Tìm đường trong tile B từ boundary đến destination
  6. Ghép 3 đoạn lại → route hoàn chỉnh

Lợi ích:

  • Chỉ cần load vài routing tiles thay vì toàn bộ graph → tiết kiệm memory
  • Có thể cache routing tiles tại CDN edge
  • Có thể cập nhật traffic cho từng tile độc lập (không cần re-compute toàn bộ)

Routing Algorithm Flow

graph TD
    Start["User request:<br/>Origin → Destination"]
    Geocode["Geocode dia chi<br/>(neu can)"]
    FindTiles["Xac dinh routing tiles<br/>chua Origin va Destination"]
    LoadTiles["Load routing tiles<br/>(local + regional + country)"]
    LocalO["Tim duong trong<br/>local tile cua Origin"]
    Regional["Tim duong qua<br/>regional/country tiles"]
    LocalD["Tim duong trong<br/>local tile cua Destination"]
    Merge["Ghep 3 doan<br/>thanh route hoan chinh"]
    Traffic["Overlay real-time<br/>traffic data"]
    ETA["Tinh ETA cho route"]
    AltRoutes["Tinh 2-3 alternative routes"]
    Response["Tra ve routes + ETA<br/>+ turn-by-turn instructions"]

    Start --> Geocode
    Geocode --> FindTiles
    FindTiles --> LoadTiles
    LoadTiles --> LocalO
    LoadTiles --> Regional
    LoadTiles --> LocalD
    LocalO --> Merge
    Regional --> Merge
    LocalD --> Merge
    Merge --> Traffic
    Traffic --> ETA
    ETA --> AltRoutes
    AltRoutes --> Response

Real-time Traffic Overlay

Pre-computed routes dựa trên static weights (tốc độ giới hạn của đường). Nhưng thực tế, traffic thay đổi mỗi phút. Giải pháp:

  1. Pre-compute routes với static weights (Contraction Hierarchies)
  2. Overlay real-time traffic data lên route:
    • Mỗi road segment có một traffic factor (1.0 = thông thoáng, 2.0 = chậm gấp đôi, 5.0 = kẹt nặng)
    • Nhân static travel time với traffic factor → adjusted travel time
  1. Nếu traffic làm route hiện tại chậm hơn alternative → re-route (tính lại route)

Alternative Routes

Google Maps thường hiển thị 2-3 routes. Cách tạo alternative routes:

Phương phápMô tả
Penalty methodSau khi tìm route tốt nhất, tăng weight của các edges trong route đó, rồi tìm lại → được route khác
Plateau methodTìm các đoạn đường “plateau” (đoạn mà route tốt nhất và alternative đều đi qua) → buộc route alternative đi đường khác ở phần còn lại
k-shortest pathsTìm k đường ngắn nhất trong graph (thường k = 3)

Mỗi alternative route được lọc để đảm bảo:

  • Khác biệt ít nhất 30% so với route chính (không muốn 2 routes gần giống nhau)
  • ETA không quá 50% lớn hơn route nhanh nhất (không đề xuất đường quá chậm)
  • Không đi qua những đoạn nguy hiểm hoặc bị cấm

3.5 Geocoding & Reverse Geocoding

Geocoding: Địa chỉ → Tọa độ

InputOutputVí dụ
Địa chỉ textLatitude, Longitude”227 Nguyen Van Cu, Q5, HCM” → (10.7594, 106.6815)

Cách hoạt động:

  1. Parsing: Tách địa chỉ thành các thành phần (số nhà, tên đường, quận, thành phố)
  2. Standardization: Chuẩn hóa viết tắt (“Q5” → “Quận 5”, “HCM” → “Hồ Chí Minh”)
  3. Lookup: Tìm trong geocoding database (Elasticsearch với geo-index)
  4. Interpolation: Nếu địa chỉ chính xác không có trong DB → nội suy vị trí giữa 2 địa chỉ đã biết

Address Interpolation (Nội suy địa chỉ):

Nếu DB có:

  • Số 221 Nguyen Van Cu → tọa độ A
  • Số 231 Nguyen Van Cu → tọa độ B

Thì số 227 ≈ vị trí (227 - 221) / (231 - 221) = 60% từ A đến B

Reverse Geocoding: Tọa độ → Địa chỉ

InputOutputVí dụ
Latitude, LongitudeĐịa chỉ text(10.7594, 106.6815) → “227 Nguyen Van Cu, Quan 5, TP.HCM”

Cách hoạt động:

  1. Tìm road segment gần nhất với tọa độ (nearest-neighbor search bằng spatial index — R-tree hoặc geohash)
  2. Project điểm lên road segment → tìm vị trí chính xác trên đường
  3. Interpolation ngược → ước tính số nhà
  4. Trả về địa chỉ đầy đủ

Database: Elasticsearch với geo_pointgeo_shape types, hoặc PostgreSQL + PostGIS extension.


3.6 Traffic Data — Mạch máu của bản đồ

Nguồn dữ liệu traffic

NguồnMô tảĐộ tin cậyLatency
User GPS dataVị trí + tốc độ của hàng triệu user đang đi trên đườngCao (số lượng lớn → trung bình chính xác)Real-time (30-60s delay)
Historical patternsDữ liệu giao thông lịch sử theo giờ/ngày/mùaCao cho patterns lặp lạiN/A (offline)
Government sensorsCamera giao thông, vòng từ (induction loops)Rất cao nhưng coverage thấpNear real-time
Third-party dataData từ taxi companies, ride-hailing, logisticsTrung bìnhNear real-time
EventsTai nạn, sửa đường, sự kiện lớn, thời tiếtBiến độngReported manually hoặc ML-detected

Real-time Traffic Processing Pipeline

  1. Ingest: Nhận location updates từ Kafka (33M updates/s peak)
  2. Map-match: Snap GPS coordinates lên road segments (GPS có sai số 5-15m → cần xác định user đang trên đường nào)
  3. Speed calculation: Tính tốc độ trung bình trên mỗi road segment trong window 2-5 phút
  4. Aggregation: Gom nhóm theo road segment → tính tốc độ trung bình, density
  5. Traffic level: So sánh tốc độ thực tế với tốc độ giới hạn → xác định traffic level
Traffic FactorMàuNghĩa
1.0 - 1.3Xanh láThông thoáng
1.3 - 2.0Vàng/CamChậm
2.0 - 5.0ĐỏKẹt xe
> 5.0Đỏ đậmKẹt nặng

Map-Matching — Bài toán không hề đơn giản

GPS coordinates có sai số (5-15m trong thành phố, lớn hơn trong khu vực nhiều tòa nhà cao tầng). Bài toán: xác định user đang trên đường nào?

Tình huống khóVấn đề
2 đường song song cách 10mGPS không đủ chính xác để phân biệt
Đường trên cầu và đường bên dướiCùng tọa độ lat/lng nhưng khác độ cao
User ở giao lộĐang trên đường nào trong 4 đường?
GPS nhảy (urban canyon)Tòa nhà cao phản xạ GPS signal

Giải pháp: Hidden Markov Model (HMM) — xem xét chuỗi các GPS points liên tiếp, không chỉ 1 point độc lập. Nếu 10 points trước đều trên đường A, thì point hiện tại có xác suất cao cũng trên đường A (dù GPS nhảy sang gần đường B).


3.7 Adaptive ETA — Tính thời gian đến chính xác

ETA (Estimated Time of Arrival) là metric quan trọng nhất của navigation. User đánh giá Google Maps dựa trên ETA có chính xác không.

3 nguồn dữ liệu cho ETA

NguồnMô tảƯu điểmNhược điểm
Historical dataTrung bình thời gian đi qua road segment X vào thứ 2, 8:00 AMỔn định, phù hợp patterns lặp lạiKhông biết tai nạn bất ngờ
Real-time trafficTốc độ hiện tại trên road segment XPhản ánh tình hình ngay lúc nàyChỉ biết hiện tại, không dự đoán tương lai
ML PredictionModel dự đoán traffic 15-30-60 phút tớiDự đoán trước — ETA tính cho đường bạn sẽ đi qua trong tương laiCần data + compute lớn

ML Model cho ETA Prediction

FeatureMô tả
Time featuresGiờ, thứ, tháng, ngày lễ, ngày thường
Current trafficTốc độ hiện tại trên route và các road segments xung quanh
Historical trafficTrung bình tốc độ của cùng giờ/thứ/mùa trong 12 tháng qua
WeatherMưa, sương mù, bão → ảnh hưởng tốc độ
EventsConcert, trận bóng đá, hỗ trợ → ảnh hưởng traffic
Road attributesSố làn, tốc độ giới hạn, có traffic light không
Segment sequenceCác road segments nối tiếp nhau trên route → model học dependencies

Output: ETA prediction cho mỗi road segment trên route → cộng lại = tổng ETA.

Google báo cáo ETA accuracy: sai lệch trung bình khoảng 5-8% so với thực tế — cực kỳ chính xác cho một hệ thống phục vụ hàng tỉ requests.

ETA Update trong quá trình navigate

Khi user đang lái xe, ETA được cập nhật liên tục (mỗi 30-60 giây):

  1. Hệ thống biết vị trí hiện tại của user (từ location updates)
  2. Tính lại ETA cho phần đường còn lại (không phải toàn bộ route)
  3. Nếu traffic thay đổi đáng kể → có thể re-route (đề xuất đường khác)

Capacity Estimation (Ước lượng dung lượng)

Assumptions (Giả thiết)

Thông sốGiá trịGhi chú
DAU1 Billion (1B)Google Maps scale
Users đồng thời gửi location updates10% DAU = 100MKhông phải ai cũng mở app cùng lúc
Location update interval30 giây/batchTrung bình (navigate: 15s, idle: 30s)
Navigation requests/user/day2Trung bình (đi làm + về nhà)
Map tile requests/user/session50 tilesScroll + zoom trung bình
Sessions/user/day3Mở app 3 lần/ngày
Peak multiplier3xGiờ cao điểm sáng + chiều

Location Update QPS

Lưu ý: Con số 33M/s (1B users / 30s) là theoretical maximum nếu tất cả user gửi cùng lúc. Thực tế, chỉ 10% DAU active tại một thời điểm → 10M peak.

Bandwidth cho location updates:

Con số 56 Gbps là rất lớn — cần nhiều server và Kafka cluster để xử lý.

Map Tile QPS

Nhưng nhờ multi-layer caching (99.99% cache hit), chỉ ~500/s thực sự chạm origin. CDN xử lý phần lớn.

Storage Estimation

Map Tile Storage

Nhưng không phải tất cả tiles đều có data (70% Trái Đất là biển, sa mạc, rừng không cần tiles chi tiết):

Location History Storage

Road Graph Storage

Road graph chỉ 80 GB — đủ nhỏ để load vào RAM của một cluster nhỏ. Đây là lý do routing có thể rất nhanh.

Tổng hợp Storage

DataSizeGhi chú
Map tiles (all zoom levels)~2.3 PBLớn nhất, lưu trên object storage + CDN
Location history (30 ngày)~430 TBTime-series, TTL 30 ngày
Road graph + CH~80 GBNhỏ, có thể in-memory
Geocoding index~50 GBElasticsearch cluster
Traffic data (7 ngày)~10 TBTime-series, TTL 7 ngày
Tổng~2.8 PBMap tiles chiếm ~80%

Security — Bảo vệ dữ liệu vị trí

4.1 Location Data Privacy — Vấn đề nghiêm trọng nhất

Vị trí của user là dữ liệu nhạy cảm bậc nhất — biết vị trí là biết nhà, chỗ làm việc, thói quen đi lại, mối quan hệ cá nhân.

Mối đe dọaMô tảGiải pháp
Data breachHacker lấy được location history của userEncryption at rest (AES-256), encryption in transit (TLS 1.3)
Internal abuseNhân viên truy cập data userAccess control nghiêm ngặt, audit log, least-privilege, data masking
Government requestChính phủ yêu cầu data vị tríLegal team review, chỉ cung cấp khi có lệnh tòa, minimization (chỉ cung cấp data cần thiết)
Third-party sharingBán data vị trí cho advertiserAnonymization, aggregation (chỉ chia sẻ aggregate traffic, không chia sẻ individual location)

4.2 Anonymization of Traffic Data

Khi sử dụng GPS data để tính traffic, cần anonymize để không thể truy nguồn về individual user:

Kỹ thuậtMô tả
K-anonymityChỉ hiển thị traffic data khi có ít nhất K users trên road segment (thường K >= 5) — không thể identify individual
Differential privacyThêm noise vào aggregate data — kết quả tổng thể vẫn chính xác nhưng không thể suy ra individual
Data aggregationChỉ lưu aggregate speed/density per road segment, không lưu “user X đi qua điểm Y lúc Z”
Ephemeral IDsThay user_id bằng random session ID, rotate mỗi session → không liên kết được sessions
Geo-fencing sensitive areasKhông thu thập chi tiết location gần bệnh viện, trụ sở tôn giáo, cơ sở quân sự

4.3 Fake GPS Injection Prevention

Một số user dùng app giả lập GPS (mock location) để gian lận (ví dụ: tài xế Grab giả vị trí). Cách ngăn chặn:

Kỹ thuậtMô tả
Sensor fusionSo sánh GPS với accelerometer, gyroscope, cell tower triangulation — nếu GPS nói user đang chạy 60 km/h nhưng accelerometer không rung → fake
Movement pattern analysisGPS teleport (vị trí nhảy đột ngột 10km) → flag suspicious
Speed consistencyTốc độ thay đổi quá nhanh (0 → 200 km/h trong 1 giây) → không hợp lý
Cell tower cross-referenceVị trí GPS phải gần cell tower đang kết nối
Device attestationAndroid SafetyNet / iOS DeviceCheck — xác minh device không bị root/jailbreak

4.4 Rate Limiting

EndpointRate LimitLý do
Location update10 requests/phút/userNgăn spam location (1 batch mỗi 15-30s là đủ)
Navigation request30 requests/phút/userNgăn automated scraping routes
Tile request1000 requests/phút/userNgăn bot download toàn bộ map data
Geocoding60 requests/phút/userNgăn batch geocoding (dịch vụ trả phí riêng)

Tham khảo Tuan-09-Rate-Limiter cho chi tiết implementation.

4.5 Data Retention Policies

Dữ liệuRetentionLý do
Raw GPS location30 ngàyChỉ cần cho traffic analysis, sau đó aggregate và xóa raw
Aggregated traffic2 nămHistorical patterns cho ML model
User search history90 ngày (hoặc user xóa)Personalization, GDPR right to delete
Navigation history90 ngày (hoặc user xóa)Trip history feature
Map tilesVĩnh viễn (cập nhật theo version)Core asset
Anonymized analytics5 nămBusiness intelligence

4.6 Compliance

RegulationYêu cầuẢnh hưởng
GDPR (EU)Right to access, right to delete, data minimizationUser có thể download hoặc xóa tất cả location data
CCPA (California)Tương tự GDPR cho California residentsOpt-out of data sale
LGPD (Brazil)Tương tự GDPR cho BrazilCần consent rõ ràng
PDPA (Vietnam/Thailand)Luật bảo vệ dữ liệu cá nhânCần consent, data localization có thể yêu cầu

DevOps — Monitoring & Observability

Tham khảo Tuan-13-Monitoring-Observability cho nền tảng. Dưới đây là các metrics đặc thù cho Google Maps.

5.1 Location Ingestion Pipeline Monitoring

MetricMục tiêuAlert khi
Kafka consumer lag< 10 giây> 30 giây (data cũ quá, traffic không real-time)
Location update throughput3-10M events/s< 1M events/s (có vấn đề ở ingestion) hoặc > 15M events/s (bất thường, có thể là attack)
Failed location updates< 0.1%> 1%
Map-matching accuracy> 95% GPS points matched thành công< 90%
Kafka partition skewEven distributionMột partition có > 2x trung bình

5.2 Routing Performance Monitoring

MetricMục tiêuAlert khi
Route calculation latency (p50)< 200ms> 500ms
Route calculation latency (p99)< 2s> 5s
Routing success rate> 99.9%< 99.5% (không tìm được route)
Contraction Hierarchies freshness< 24 giờ từ lần rebuild cuối> 48 giờ
Routing tile cache hit ratio> 90%< 80%
Alternative routes generated>= 2 routes cho 95% requests< 2 routes cho > 10% requests

5.3 Tile CDN Monitoring

MetricMục tiêuAlert khi
CDN cache hit ratio> 99%< 95% (cache invalidation sai?)
Tile latency (CDN edge, p50)< 50ms> 100ms
Tile latency (origin, p50)< 200ms> 500ms
404 rate (missing tiles)< 0.01%> 0.1% (tile generation pipeline bị lỗi)
Tile freshness< 7 ngày từ lần render cuối> 30 ngày cho khu vực thành phố
Bandwidth costBudget-based> 120% budget

5.4 ETA Accuracy Monitoring

MetricMục tiêuAlert khi
ETA error (median)< 8%> 15%
ETA error (p95)< 25%> 40%
ETA under-estimate rate< 30%> 50% (user đến trễ → trải nghiệm xấu)
ML model staleness< 24 giờ từ lần retrain cuối> 48 giờ

5.5 Overall System Health Dashboard

CategoryKey Metrics
AvailabilityService uptime per component, error rate (5xx), circuit breaker trips
Latencyp50/p95/p99 cho mỗi service (location, routing, tiles, geocoding)
ThroughputQPS cho mỗi service, Kafka throughput, CDN bandwidth
SaturationCPU/Memory/Disk cho mỗi cluster, Kafka partition fill rate
Business metricsDAU, navigation starts/completions, search queries, user ratings

5.6 Alerting Hierarchy

LevelMô tảVí dụResponse time
P0 — CriticalCore feature bị downNavigation không hoạt động, Kafka cluster down< 5 phút
P1 — HighPerformance degradation nghiêm trọngRouting latency p99 > 10s, ETA sai > 30%< 15 phút
P2 — MediumDegradation nhẹCDN cache hit < 95%, location lag > 1 phút< 1 giờ
P3 — LowCosmetic hoặc non-criticalTile render pipeline chậm, analytics delay< 24 giờ

Mermaid Diagrams — Tổng hợp

Overall System Architecture (Chi tiết)

graph TB
    subgraph "Client Layer"
        Mobile["Mobile Client<br/>iOS / Android"]
        Web["Web Client<br/>Browser"]
    end

    subgraph "Edge Layer"
        CDN["Tile CDN<br/>Global Edge PoPs<br/>99%+ cache hit"]
        APIGW["API Gateway<br/>Auth · Rate Limit · Route"]
    end

    subgraph "Application Layer"
        direction TB
        LocSvc["Location Service<br/>Write: 10M/s peak"]
        NavSvc["Navigation Service<br/>Read: 70K/s peak"]
        MapSvc["Map Rendering<br/>Tile metadata"]
        GeoSvc["Geocoding Service<br/>Address ↔ LatLng"]
        TrafficSvc["Traffic Aggregator<br/>Stream processing"]
        ETASvc["ETA Service<br/>ML-powered"]
    end

    subgraph "Message Queue"
        Kafka["Apache Kafka<br/>Location Events<br/>Partitioned by geo-region"]
    end

    subgraph "Storage Layer"
        S3["Object Storage (S3)<br/>Map Tiles — 2.3 PB"]
        Cassandra["Cassandra<br/>Location History — 430 TB"]
        TSDB["Time-series DB<br/>Traffic Data — 10 TB"]
        Graph["Road Graph (In-memory)<br/>+ Contraction Hierarchies<br/>80 GB"]
        ES["Elasticsearch<br/>Geocoding Index<br/>50 GB"]
        Redis["Redis Cluster<br/>Real-time traffic cache"]
    end

    subgraph "ML Platform"
        ETAModel["ETA Prediction Model"]
        TrafficModel["Traffic Prediction Model"]
        FeatureStore["Feature Store"]
    end

    Mobile -->|"Tile requests"| CDN
    Web -->|"Tile requests"| CDN
    Mobile --> APIGW
    Web --> APIGW
    CDN -->|"Cache miss"| S3

    APIGW --> LocSvc
    APIGW --> NavSvc
    APIGW --> GeoSvc

    LocSvc --> Kafka
    Kafka --> TrafficSvc
    Kafka --> Cassandra

    TrafficSvc --> TSDB
    TrafficSvc --> Redis
    TrafficSvc --> FeatureStore

    NavSvc --> Graph
    NavSvc --> ETASvc
    NavSvc --> GeoSvc

    ETASvc --> Redis
    ETASvc --> TSDB
    ETASvc --> ETAModel

    ETAModel --> FeatureStore
    TrafficModel --> FeatureStore

    GeoSvc --> ES
    MapSvc --> S3

Map Tile Pyramid (Visual)

graph TD
    subgraph "Tile Pyramid"
        L0["Level 0: 1 tile<br/>🌍 Toan cau<br/>~100 KB"]
        L5["Level 5: 1,024 tiles<br/>Cac quoc gia<br/>~10 MB total"]
        L10["Level 10: ~1M tiles<br/>Thanh pho<br/>~15 GB total"]
        L15["Level 15: ~1B tiles<br/>Duong pho<br/>~15 TB total"]
        L20["Level 20: ~1T tiles<br/>Chi tiet nha<br/>~2.3 PB total"]
    end

    L0 -->|"x4 moi level"| L5
    L5 -->|"x1024"| L10
    L10 -->|"x1024"| L15
    L15 -->|"x1024"| L20

    subgraph "Caching Strategy"
        Client["Client Cache<br/>~70-80% hit"]
        Edge["CDN Edge<br/>~97% hit"]
        Origin["Origin S3<br/>Source of truth"]
    end

    L20 -.->|"Served via"| Origin
    Origin -->|"Cached at"| Edge
    Edge -->|"Cached at"| Client

Location Update Pipeline (Chi tiết)

sequenceDiagram
    participant Device as Mobile Device
    participant LB as Load Balancer
    participant LS as Location Service
    participant K as Kafka
    participant TA as Traffic Aggregator
    participant HW as History Writer
    participant ML as ML Pipeline
    participant Redis as Redis (Traffic Cache)
    participant Cass as Cassandra (History)

    Note over Device: Thu thap GPS moi 1-3s
    Note over Device: Batch 15 data points

    Device->>LB: POST /location/batch (700 bytes)
    LB->>LS: Forward request
    LS->>LS: Validate + enrich data
    LS->>K: Publish to "location-events" topic
    LS-->>Device: 202 Accepted

    par Consumer Group 1
        K->>TA: Consume location events
        TA->>TA: Map-match GPS → road segments
        TA->>TA: Calculate speed per segment
        TA->>Redis: Update real-time traffic
    and Consumer Group 2
        K->>HW: Consume location events
        HW->>Cass: Write location history (TTL 30d)
    and Consumer Group 3
        K->>ML: Consume for feature engineering
        ML->>ML: Update feature store
    end
sequenceDiagram
    participant Client as Mobile Client
    participant APIGW as API Gateway
    participant Nav as Navigation Service
    participant Geo as Geocoding Service
    participant Graph as Road Graph (Memory)
    participant ETA as ETA Service
    participant Traffic as Traffic Cache (Redis)
    participant MLModel as ML Model

    Client->>APIGW: GET /route?origin=A&dest=B&mode=driving
    APIGW->>APIGW: Auth + Rate Limit
    APIGW->>Nav: Forward request

    Nav->>Geo: Geocode "A" → (lat1, lng1)
    Nav->>Geo: Geocode "B" → (lat2, lng2)
    Geo-->>Nav: Coordinates

    Nav->>Graph: Find route via Contraction Hierarchies
    Graph-->>Nav: Primary route (list of road segments)

    Nav->>Graph: Find 2 alternative routes
    Graph-->>Nav: Alt routes

    loop For each route
        Nav->>ETA: Calculate ETA for route
        ETA->>Traffic: Get real-time traffic per segment
        Traffic-->>ETA: Traffic factors
        ETA->>MLModel: Predict segment travel times
        MLModel-->>ETA: Predicted times
        ETA->>ETA: Combine: historical + real-time + ML
        ETA-->>Nav: ETA + traffic-adjusted times
    end

    Nav->>Nav: Rank routes by ETA
    Nav->>Nav: Generate turn-by-turn instructions
    Nav-->>APIGW: 3 routes + ETAs + instructions
    APIGW-->>Client: Response (< 3s total)

Aha Moments & Pitfalls

Aha Moments — Những insight quan trọng

#InsightGiải thích
1Pre-computation là chìa khóa của routingContraction Hierarchies mất vài giờ để build offline, nhưng mỗi query chỉ mất < 1ms. Đây là trade-off kinh điển: offline compute ↔ online speed. Không có pre-computation, Google Maps không thể phục vụ 70K routing requests/s.
2Tile caching tiết kiệm 99%+ computeNhờ multi-layer caching (client → CDN edge → origin shield → S3), chỉ 0.01% requests chạm origin. Map rendering service thực ra chỉ phục vụ pre-rendering pipeline, không phải user requests trực tiếp.
3Location data volume là massive10M updates/s, 14 TB/ngày, 430 TB/tháng — chỉ riêng location data. Cần Kafka để buffer, Cassandra/TimescaleDB để lưu, và TTL để tự động xóa data cũ. Không thể dùng traditional RDBMS.
4Real-time traffic đòi hỏi stream processingTraffic data phải được xử lý trong giây, không phải phút. Cần Kafka + stream processing framework (Flink/Spark Streaming). Batch processing (chạy mỗi 5 phút) là quá chậm.
5ETA accuracy cần MLSimple formula (khoảng cách / tốc độ giới hạn) cho ETA sai 30-50%. Cần combine historical patterns + real-time traffic + ML prediction để đạt sai số < 10%.
6Road graph nhỏ bất ngờToàn bộ road graph toàn cầu chỉ ~80 GB — đủ nhỏ để load vào RAM. Đây là lý do routing cực nhanh: không cần disk I/O.
7Map-matching không đơn giảnGPS có sai số 5-15m. Ở thành phố (nhiều tòa nhà), sai số còn lớn hơn. Cần HMM (Hidden Markov Model) để xác định user đang trên đường nào — chỉ GPS point đơn lẻ là không đủ.
8Vector tiles là tương laiNhỏ hơn 3-5x so với raster, smooth zoom, dynamic styling (dark mode) — tất cả các map providers lớn đều chuyển sang vector tiles. Client cần GPU nhưng smartphones hiện đại đủ mạnh.

Common Pitfalls — Các lỗi thường gặp khi thiết kế

#PitfallTại sao saiCách đúng
1Tính route on-the-fly bằng DijkstraO(V log V) với 500M nodes = vài giây/request. Không scale với 70K QPSDùng Contraction Hierarchies (pre-computed), query < 1ms
2Render tiles on-the-fly5M tile requests/s peak — không server farm nào render kịpPre-render offline + CDN caching
3Gửi GPS mỗi giây từ clientTốn battery, tốn bandwidth, server bị overwhelmBatch mỗi 15-30 giây, 15 data points/batch
4Dùng RDBMS cho location history14 TB/ngày writes, 10M writes/s — PostgreSQL không chịu nổiDùng Cassandra hoặc TimescaleDB (write-optimized)
5Bỏ qua map-matchingGPS “227 Nguyen Van Cu” nhưng thực tế user đang trên đường bên cạnh → traffic data saiDùng HMM-based map-matching trước khi xử lý traffic
6Không partition road graphLoad 80 GB graph mỗi lần routing request → chậm, tốn memoryDùng routing tiles — chỉ load tiles liên quan
7ETA chỉ dùng tốc độ hiện tạiTraffic sẽ thay đổi trong 30 phút tới — route dài cần dự đoán tương laiCombine historical + real-time + ML prediction
8Lưu raw GPS data vĩnh viễn430 TB/tháng → 5 PB/năm → không thể lưu mãiTTL 30-90 ngày, aggregate rồi xóa raw
9Không anonymize traffic dataVi phạm privacy — có thể truy nguồn user từ traffic patternsK-anonymity, differential privacy, ephemeral IDs
10Không có offline supportUser mất signal trong hầm, ở nông thôn → bản đồ trắngCho phép download tiles + routing data cho offline use

So sánh với các bài khác đã học

Khái niệmỞ Google MapsỞ bài đã học
CDNTile CDN — 99%+ cache hitTuan-03-Networking-DNS-CDN — lý thuyết CDN
Message QueueKafka cho location ingestion — 10M events/s, fan-out 3 consumersTuan-08-Message-Queue — lý thuyết message queue
Stream ProcessingTraffic aggregation real-time từ location eventsChưa học chi tiết — nhưng là extension của Tuan-08-Message-Queue
Geo-spatialRoad graph, routing tiles, map tiles, geocodingCase-Design-Proximity-Service — geohash, spatial index
Pre-computationContraction Hierarchies, tile pre-renderingKhái niệm mới — rất quan trọng cho interview
Time-series dataLocation history, traffic dataTương tự log data trong Tuan-13-Monitoring-Observability
PrivacyLocation anonymization, GDPR complianceTuan-15-Data-Security-Encryption — encryption, data protection

Câu hỏi tự kiểm tra

Level 1 — Recall (Nhớ lại)

  1. Google Maps có mấy zoom level? Mỗi level tăng bao nhiêu tiles so với level trước?
  2. Ba service chính của Google Maps là gì?
  3. Tại sao weight của road graph là thời gian, không phải khoảng cách?
  4. Contraction Hierarchies pre-compute gì?
  5. Tần suất gửi location update khi user đang navigate là bao nhiêu?

Level 2 — Understanding (Hiểu)

  1. Giải thích tại sao vector tiles tốt hơn raster tiles cho mobile.
  2. Tại sao cần multi-layer caching (client → CDN → origin) cho map tiles?
  3. Map-matching là gì và tại sao cần dùng HMM thay vì nearest-road?
  4. Tại sao ETA cần cả 3 nguồn (historical + real-time + ML) thay vì chỉ 1?
  5. Tại sao location history dùng Cassandra thay vì PostgreSQL?

Level 3 — Application (Vận dụng)

  1. Nếu CDN cache hit giảm từ 99% xuống 90%, ảnh hưởng gì đến origin? Tính QPS mới ở origin.
  2. Nếu GPS accuracy giảm (do urban canyon), hệ thống nào bị ảnh hưởng và cách xử lý?
  3. Thiết kế data retention policy cho một ứng dụng ride-hailing (Grab) sử dụng hệ thống này.
  4. Nếu cần hỗ trợ “avoid toll roads” và “avoid highways”, thay đổi gì trong routing?
  5. Tính storage cần thiết nếu tăng retention từ 30 ngày lên 90 ngày cho location history.

Tổng kết — What to Remember for Interview

1-minute Pitch (Nếu chỉ có 1 phút)

“Google Maps gồm 3 services chính: Location Service (thu thập GPS từ users qua Kafka, 10M events/s), Map Rendering (pre-rendered tiles phục vụ qua CDN, 99%+ cache hit), và Navigation (road graph với Contraction Hierarchies cho < 1ms query, overlay real-time traffic, ML-powered ETA). Key insight: pre-computation ở cả map tiles lẫn routing là lý do hệ thống có thể phục vụ 1B DAU.”

Checklist khi vẽ diagram

  • Client → CDN (tiles) và Client → API Gateway (navigation, location)
  • Location Service → Kafka → 3 consumers (traffic, history, ML)
  • Navigation Service → Road Graph (in-memory) + ETA Service
  • ETA Service → Traffic Cache (Redis) + ML Model
  • Multi-layer caching cho tiles (Client → CDN → Origin Shield → S3)
  • Geocoding Service (Elasticsearch) cho address ↔ coordinates

3 điều interviewer muốn nghe

  1. Pre-computation: “Contraction Hierarchies giúp routing query < 1ms thay vì vài giây. Tiles được pre-render offline và cache ở CDN.”
  2. Scale numbers: “10M location updates/s, 70K routing requests/s, 5M tile requests/s (nhưng 99%+ served by CDN).”
  3. Real-time traffic: “User GPS data → Kafka → stream processing → real-time traffic overlay → adaptive ETA với ML.”

  • bài này dài nhưng mỗi phần đều quan trọng. Google Maps là một trong những hệ thống phức tạp nhất — nó kết hợp CDN, stream processing, graph algorithms, ML, và geo-spatial data. Hiểu bài này, bạn sẽ có nền tảng vững cho bất kỳ bài toán location-based nào trong interview.*

Next: Case-Design-Proximity-Service — Proximity Service (geohash, quadtree) là nền tảng cho location-based search mà Google Maps sử dụng.