Skip to content

Thiết kế WhatsApp — Messaging và End-to-End Encryption ở quy mô tỷ người dùng

100 tỷ tin nhắn mỗi ngày. 2 tỷ người dùng hoạt động hàng tháng. 500 triệu kết nối đồng thời. Và đây là phần quan trọng nhất — server KHÔNG THỂ đọc được nội dung bất kỳ tin nhắn nào. Đó không phải slogan marketing, đó là ràng buộc kiến trúc cốt lõi ảnh hưởng đến mọi quyết định thiết kế trong hệ thống này.

WhatsApp là một kỳ công kỹ thuật hiếm thấy: message delivery dưới 1 giây xuyên lục địa, hệ thống 3-tick trạng thái (✓ sent → ✓✓ delivered → ✓✓ read) hoạt động chính xác qua E2E encryption, và presence system theo dõi trạng thái online/offline cho 2 tỷ tài khoản. Trước khi Meta mua lại, chỉ khoảng 50 kỹ sư vận hành toàn bộ hệ thống này — chạy Erlang trên FreeBSD, một stack công nghệ mà phần lớn kỹ sư ngày nay chưa từng chạm tới.

Câu hỏi thiết kế trung tâm không phải "làm sao gửi tin nhắn" — điều đó đơn giản. Câu hỏi thực sự là: làm sao route tin nhắn khi bạn không thể đọc nội dung? Làm sao xử lý người dùng offline trong hệ thống encrypted? Làm sao scale WebSocket connections lên 500 triệu mà không biến data center thành lò nướng? Bài viết này sẽ mổ xẻ từng vấn đề đó.

Bức tranh tư duy

Hãy hình dung WhatsApp như một hệ thống bưu chính mật — người gửi khóa lá thư bằng ổ khóa mà chỉ người nhận có chìa khóa tương ứng. Người bưu tá (server) vận chuyển phong bì nhưng không thể mở ra đọc. Nếu người nhận vắng nhà, thư được giữ tại bưu cục cho đến khi họ quay lại lấy. Bưu cục cũng không mở được thư — họ chỉ biết phong bì này cần giao cho ai.

Mental model cốt lõi cho message flow:

Encrypt → Send → Route → Store (nếu offline) → Deliver → Acknowledge

Hệ thống 3-tick là cách WhatsApp biến message delivery thành trải nghiệm người dùng rõ ràng:

  • (một tick xám): Server đã nhận encrypted message từ thiết bị gửi
  • ✓✓ (hai tick xám): Thiết bị người nhận đã download và decrypt thành công
  • ✓✓ (hai tick xanh): Người nhận đã mở cuộc trò chuyện và xem tin nhắn

Mỗi trạng thái là một acknowledgment packet riêng biệt, cũng được encrypt, đi ngược lại từ recipient → server → sender.

Khi nào analogy bị phá vỡ? Group messaging. Trong bưu chính thật, bạn gửi 1 lá thư cho 1 người. Trong WhatsApp group, mỗi thành viên cần bản sao riêng được encrypt bằng key riêng của họ. Gửi tin nhắn vào group 256 người = 256 phiên bản encrypted khác nhau. Đây chính là lý do group messaging phức tạp hơn 1:1 messaging rất nhiều lần.

Cốt lõi kỹ thuật

Connection Management — 500 triệu kết nối đồng thời

Nền tảng của mọi messaging system là persistent connection giữa client và server. WhatsApp sử dụng kết hợp WebSocket và MQTT tùy theo điều kiện mạng — WebSocket cho kết nối ổn định, MQTT (lightweight publish-subscribe) cho mạng yếu và tiết kiệm pin trên mobile.

Quy mô connection cluster:

Thông sốGiá trịGhi chú
Concurrent connections500MPeak online users
Connections per server~500KSử dụng epoll (Linux) / kqueue (FreeBSD)
Tổng connection servers~1,000500M ÷ 500K
Memory per connection~10 KBSocket buffer + session state
RAM per server~5 GBCho connections + OS overhead
Total cluster RAM~5 TBChỉ tính connection layer
Heartbeat interval30 giâyDetect dead connections
Heartbeat throughput~17M/giây500M ÷ 30s

Mỗi connection server sử dụng epoll (Linux) hoặc kqueue (FreeBSD) để handle hàng trăm ngàn socket đồng thời trên một process duy nhất — đây là I/O multiplexing, không phải thread-per-connection. Erlang đặc biệt phù hợp cho workload này vì lightweight processes của nó chiếm chỉ ~2 KB memory mỗi process.

Heartbeat mechanism: Client gửi heartbeat packet mỗi 30 giây. Nếu server không nhận được heartbeat trong 90 giây (3 lần miss), connection được đánh dấu dead và tài nguyên được giải phóng. Trên mobile, khi app vào background, heartbeat interval tăng lên 5 phút để tiết kiệm pin.

Message Routing — Tìm người nhận trong biển 500 triệu connections

Khi Alice gửi tin nhắn cho Bob, server cần biết Bob đang kết nối tới connection server nào. WhatsApp sử dụng Distributed Hash Table (DHT) để duy trì mapping user_id → connection_server_id.

Routing Flow:
1. Alice gửi message → Connection Server A
2. Server A lookup DHT: Bob → Connection Server C
3. Server A forward encrypted blob → Server C
4. Server C push message → Bob device
5. Nếu Bob offline → Message Queue (persistent storage)

DHT được replicate across data centers với eventual consistency — delay vài giây trong routing lookup là chấp nhận được (tin nhắn đến chậm 200ms không ai nhận ra). Khi user reconnect sau khi mất kết nối, connection server mới cập nhật DHT entry và pull tất cả pending messages từ offline queue.

Multi-device considerations: Một user có thể online trên nhiều thiết bị (WhatsApp Web, Desktop, Phone). DHT mapping trở thành user_id → [device_1@server_A, device_2@server_B]. Message được fan-out tới tất cả active devices.

End-to-End Encryption — Signal Protocol

WhatsApp sử dụng Signal Protocol (trước đây là Axolotl Protocol) cho E2E encryption. Đây là protocol được đánh giá cao nhất trong ngành về bảo mật messaging.

3 thành phần cốt lõi:

1. X3DH Key Exchange (Extended Triple Diffie-Hellman)

Khi Alice muốn gửi tin nhắn cho Bob lần đầu tiên, cần thiết lập shared secret mà server không biết:

  • Bob đã upload lên server: Identity Key (dài hạn) + Signed Pre-Key (trung hạn) + One-Time Pre-Keys (dùng 1 lần)
  • Alice download public keys của Bob từ server
  • Alice tính shared secret từ 3 lần Diffie-Hellman exchange
  • Server chỉ thấy public keys đi qua, không bao giờ thấy shared secret

2. Double Ratchet Algorithm

Sau khi thiết lập shared secret, Double Ratchet tạo key mới cho mỗi message:

  • Symmetric ratchet: Hash chain tạo message key mới từ key trước đó
  • DH ratchet: Định kỳ trao đổi DH key mới để refresh chain
  • Kết quả: mỗi message dùng key duy nhất, không thể tái sử dụng

3. Forward Secrecy

Nếu attacker compromise key hiện tại, họ không thể decrypt các tin nhắn trong quá khứ — vì key cũ đã bị xóa sau khi sử dụng. Đây là thuộc tính bảo mật quan trọng nhất của Signal Protocol.

Điều server biết vs không biết:

Server BIẾTServer KHÔNG BIẾT
Ai gửi cho ai (metadata)Nội dung tin nhắn
Thời gian gửiMedia content
Kích thước encrypted blobEncryption keys
Device typeMessage history (sau khi deliver)

Group Messaging — Fan-out Encryption Challenge

Group messaging là bài toán phức tạp nhất trong WhatsApp. Có hai approach:

Approach 1: Pairwise Encryption (Ngây thơ)

  • Sender encrypt message riêng cho mỗi member bằng pairwise key
  • Group 256 người = 256 lần encrypt + 256 lần gửi
  • Bandwidth: message_size × 256
  • Vấn đề: Tốn tài nguyên gửi, đặc biệt với media lớn

Approach 2: Sender Keys (WhatsApp thực tế dùng)

  • Mỗi member tạo một "sender key" và phân phối cho cả group (qua pairwise encrypted channel)
  • Khi gửi message: encrypt 1 lần bằng sender key → server fan-out bản encrypted giống nhau
  • Mỗi member decrypt bằng sender key của người gửi
  • Ưu điểm: Encrypt 1 lần thay vì N lần
  • Trade-off: Nếu 1 member bị compromise, sender key cần được rotate cho toàn bộ group

Group metadata: Server lưu group membership list (ai trong group nào), nhưng không lưu tên group hoặc mô tả group — những thông tin đó được encrypt và chỉ tồn tại trên devices của members.

Media Storage — Tách biệt khỏi Message Flow

Media (hình ảnh, video, audio, documents) được xử lý khác hoàn toàn so với text messages:

Media Upload Flow:
1. Sender encrypt media file bằng random AES-256 key
2. Upload encrypted blob lên Object Storage (tương tự S3)
3. Server trả về URL của encrypted blob
4. Sender gửi text message chứa: URL + AES key + hash
   (text message này được E2E encrypt bằng Signal Protocol)
5. Recipient nhận text message → extract URL + key
6. Download encrypted blob từ Object Storage
7. Decrypt bằng AES key → hiển thị media

Tại sao tách biệt?

  • Hiệu quả: Media file lớn (MB) không đi qua message routing pipeline (được tối ưu cho KB)
  • Storage tiers: Text messages trên SSD (hot storage, cần deliver nhanh), media trên Object Storage (cold storage, rẻ hơn nhiều)
  • Group optimization: Media upload 1 lần, tất cả members download cùng encrypted blob (vì dùng cùng AES key được share qua sender key)
  • Thumbnail generation: Server không thể tạo thumbnail (encrypted). Client tạo thumbnail, encrypt riêng, upload như một blob nhỏ hơn

Capacity estimation cho media:

Thông sốGiá trị
Media messages/ngày20% × 100B = 20B
Average media size300 KB (compressed)
Daily media storage20B × 300KB = 6 PB/ngày
30-day retention180 PB
Bandwidth (upload + download)~600 Gbps sustained

Presence System — Online/Offline/Last Seen

Presence system tracking trạng thái online cho 2 tỷ users là bài toán pub/sub khổng lồ, nhưng WhatsApp giới hạn scope rất thông minh:

Nguyên tắc thiết kế:

  • Presence updates chỉ gửi cho contacts của user, không phải toàn bộ hệ thống
  • Một user trung bình có ~100 contacts, trong đó ~20 online cùng lúc
  • User thay đổi trạng thái (online → offline) → push update cho ~20 subscribers
  • KHÔNG broadcast global — đây là sai lầm thiết kế phổ biến nhất

Implementation:

  • Mỗi user có một subscription list (contacts đang online muốn biết trạng thái của user này)
  • Khi user connect → push "online" cho subscribers
  • Khi user disconnect → push "offline" + last_seen timestamp
  • Rate limiting: cập nhật presence tối đa 1 lần/10 giây để tránh flapping (user với mạng yếu liên tục on/off)

Presence consistency: AP (Available + Partition-tolerant). Nếu Bob thấy Alice "online" nhưng thực tế Alice đã offline 5 giây trước — hoàn toàn chấp nhận được. Eventual consistency là đủ cho presence.

Kiến trúc tổng thể

Data flow tóm tắt:

  1. Text message: Client → Connection Gateway → Message Router → DHT lookup → Target Gateway → Recipient
  2. Media message: Client → Media Store (upload) → Client gửi URL qua text message flow
  3. Presence: Client connect/disconnect → Connection Gateway → Presence Service → Fan-out to subscribers
  4. Key exchange: Client → Key Store (upload pre-keys) / Client → Key Store (download peer keys)

Thực chiến

Tình huống: Giao thừa Tết Nguyên Đán — Traffic spike 5x

Bối cảnh: 23:50 đêm giao thừa Tết Nguyên Đán. 100 triệu người dùng Việt Nam đồng loạt gửi tin nhắn chúc Tết. Message volume tăng 5x so với bình thường. Media messages (ảnh, video chúc Tết) tăng 10x. Stickers và GIF tăng 15x.

Vấn đề nổ ra theo thứ tự:

  1. T+0s (00:00:00): Connection servers nhận burst 16M messages/giây (bình thường 3.2M)
  2. T+5s: Message queue backlog tăng từ 0 → 500M messages chưa deliver
  3. T+30s: Media upload saturate bandwidth — mỗi user gửi 5-10 ảnh chúc Tết
  4. T+2min: Một số connection servers bắt đầu drop connections do memory pressure

Giải pháp — Pre-planning + Runtime adaptation:

Trước Tết 2 tuần:

  • Scale connection servers từ 1,000 → 2,500 (150% headroom)
  • Pre-warm message queue partitions: tăng từ 10K → 25K partitions
  • Deploy media upload rate limiter: max 5 media/phút/user trong giờ cao điểm
  • Tăng offline message queue capacity 3x

Runtime (khi spike xảy ra):

  • Backpressure mechanism: Khi message queue depth > threshold → connection servers bắt đầu throttle tin nhắn mới
  • Priority queuing: Text messages được ưu tiên cao hơn media trong queue
  • Staggered delivery: Accept tất cả messages ngay lập tức (sender thấy ✓ sent), nhưng delivery có thể delay 2-5 giây trong peak
  • Media deferral: Thumbnail gửi ngay, full-resolution media download bị delay cho đến khi load giảm

Kết quả mong đợi:

MetricBình thườngPeak TếtXử lý
Message QPS3.2M16MScale + backpressure
Connection servers1,0002,500Pre-provisioned
Message delay (P99)200ms2-5sAcceptable degradation
Media upload600 Gbps2 TbpsRate limit + defer
Dropped messages00At-least-once guarantee

Bài học: Message delivery phải là zero-loss. User chấp nhận delay vài giây, nhưng KHÔNG chấp nhận tin nhắn bị mất. "Chậm nhưng chắc" là triết lý đúng cho messaging system.

Sai lầm điển hình

Sai lầm 1: Lưu tin nhắn plaintext trên server

Thiết kế sai: Server decrypt message để lưu trữ, index, và search — "tiện cho việc hỗ trợ khách hàng và chống spam".

Tại sao sai: Tạo single point of failure cho privacy. Một vụ data breach lộ TOÀN BỘ lịch sử tin nhắn của tỷ người dùng. Vi phạm GDPR, luật bảo vệ dữ liệu, và phá hủy trust — thứ không thể xây lại sau khi mất.

Cách đúng: Server chỉ lưu encrypted blobs. Không index, không search phía server. Tất cả search functionality hoạt động trên device (local database). Spam detection dựa trên metadata (tần suất gửi, số lượng recipients) chứ không phải nội dung.

Sai lầm 2: Polling thay vì persistent connection

Thiết kế sai: Client gửi HTTP GET request mỗi 2 giây để kiểm tra tin nhắn mới — "đơn giản hơn WebSocket".

Tại sao sai: 500M users × 1 request/2 giây = 250M HTTP requests/giây. Mỗi request tốn TCP handshake + TLS negotiation + HTTP overhead. Battery drain trên mobile cực kỳ nghiêm trọng. 99% requests trả về empty response (không có tin nhắn mới) → lãng phí tài nguyên khổng lồ.

Cách đúng: Persistent WebSocket/MQTT connection. Server push message ngay khi có. Một connection duy trì cho đến khi user offline. Heartbeat mỗi 30 giây chỉ tốn vài bytes — so với full HTTP request tốn hàng trăm bytes header.

So sánh:

ApproachRequests/giây (500M users)Battery impactLatency
Polling (2s)250MRất cao0-2s (avg 1s)
Long polling50MCao~0s
WebSocket~17M (heartbeat)Thấp<100ms
MQTT~17M (heartbeat)Rất thấp<100ms

Sai lầm 3: Encrypt group message một lần cho cả group

Thiết kế sai: Tạo một "group key" duy nhất, tất cả members dùng chung key này để encrypt/decrypt.

Tại sao sai: Khi một member rời group hoặc bị compromise, bạn phải rotate key cho toàn bộ group. Trong thời gian rotate, messages có thể bị decrypt bởi member cũ. Worse: nếu member cũ backup group key, họ có thể decrypt TẤT CẢ tin nhắn tương lai cho đến khi key thực sự được rotate.

Cách đúng: Sender Keys. Mỗi member có sender key riêng. Khi member rời group, chỉ cần xóa sender key của họ — các sender keys khác vẫn hoạt động. Forward secrecy vẫn được bảo toàn ở cấp độ individual sender.

Sai lầm 4: Global presence broadcast

Thiết kế sai: Khi user X online → broadcast "user X is online" tới TẤT CẢ 2 tỷ users.

Tại sao sai: Một user thay đổi trạng thái = 2 tỷ push notifications. 500M users thay đổi trạng thái mỗi giờ = 277 nghìn tỷ notifications/giờ. Không hệ thống nào trên trái đất xử lý được volume này. Đây là broadcast storm kinh điển.

Cách đúng: Presence updates chỉ gửi cho contacts của user đó (trung bình ~100 contacts, ~20 online). Một user thay đổi trạng thái = 20 push notifications. 500M thay đổi/giờ = 10 tỷ notifications/giờ — vẫn lớn nhưng khả thi (khoảng 2.8M/giây, phân tán trên 1000 servers = 2,800 notifications/server/giây).

Under the Hood

Connection Scaling: Từ C10K đến C500K

Vấn đề C10K cổ điển (handle 10,000 concurrent connections trên 1 server) đã được giải quyết từ đầu những năm 2000 với epoll (Linux) và kqueue (FreeBSD). WhatsApp push giới hạn này lên C500K — 500,000 connections per server.

Cách hoạt động:

  • epoll/kqueue: Kernel thông báo cho application khi socket có data, thay vì application phải check từng socket (polling)
  • Event-driven architecture: Một thread xử lý hàng ngàn events, không tạo thread cho mỗi connection
  • Erlang lightweight processes: Mỗi connection = 1 Erlang process (~2 KB memory). 500K connections = ~1 GB chỉ cho processes
  • Zero-copy messaging: Kernel transfer data trực tiếp từ network buffer → application buffer, không copy qua kernel space

Memory breakdown per connection:

ComponentSizeGhi chú
Socket buffer (recv)4 KBTunable, giảm cho mobile clients
Socket buffer (send)4 KBTunable
Erlang process2 KBHeap + stack + mailbox
Session state0.5 KBUser ID, device info, encryption state
Tổng~10.5 KBPer connection

Signal Protocol Deep Dive

X3DH Key Exchange (đơn giản hóa):

Bob pre-publish lên server:
  - IK_B: Identity Key (dài hạn, 1 per account)
  - SPK_B: Signed Pre-Key (trung hạn, rotate hàng tuần)
  - OPK_B: One-Time Pre-Key (dùng 1 lần, batch upload 100 keys)

Alice muốn gửi message cho Bob:
  1. Download IK_B, SPK_B, OPK_B từ server
  2. Tính: DH1 = DH(IK_A, SPK_B)
         DH2 = DH(EK_A, IK_B)     # EK = Ephemeral Key
         DH3 = DH(EK_A, SPK_B)
         DH4 = DH(EK_A, OPK_B)    # Optional
  3. Shared Secret = KDF(DH1 || DH2 || DH3 || DH4)
  4. Xóa ephemeral keys ngay lập tức

Double Ratchet (đơn giản hóa):

Sau khi có shared secret, mỗi message dùng key khác nhau:

Root Key ─── Chain Key 1 ─── Message Key 1 (encrypt msg 1, rồi XÓA)
         │              └── Message Key 2 (encrypt msg 2, rồi XÓA)

         └── Chain Key 2 ─── Message Key 3 (encrypt msg 3, rồi XÓA)
                         └── Message Key 4 (encrypt msg 4, rồi XÓA)

Chain Key được ratchet (quay) mỗi khi hai bên trao đổi DH key mới — đây là "DH ratchet". Trong mỗi chain, message keys được derive bằng hash function — đây là "symmetric ratchet".

Trade-offs: WebSocket vs MQTT vs HTTP/2 SSE

Tiêu chíWebSocketMQTTHTTP/2 SSE
Connection overheadThấp (1 TCP)Rất thấpTrung bình
Bidirectional✅ Full-duplex✅ Pub/Sub❌ Server→Client only
Mobile batteryTrung bìnhRất tốtKém (HTTP overhead)
ReconnectionManualBuilt-in QoSAuto (browser)
Binary support✅ Native✅ Native❌ Text-based
Proxy friendlyCó thể bị blockÍt gặp vấn đềTốt nhất
Khi nào dùngWeb clientsMobile clientsDashboard, notifications

WhatsApp chọn MQTT variant cho mobile (tối ưu battery, reconnection tốt, lightweight) và WebSocket cho WhatsApp Web (browser environment, full-duplex cần thiết cho typing indicators).

CAP Analysis cho từng subsystem

SubsystemCAP ChoiceLý do
Message DeliveryAP (at-least-once)Không bao giờ mất message. Duplicate detection ở client side bằng message_id
Presence SystemAP (eventual)Stale 5-10 giây là OK. Availability quan trọng hơn strict consistency
Encryption KeysCP (strong)Key PHẢI chính xác. Sai key = không decrypt được = message bị mất. Quicker to retry than deliver wrong key
User RegistryCPAuth phải đúng. Gửi message nhầm người là thảm họa bảo mật
Group MembershipCPThêm/xóa member phải consistent. Race condition = lộ message cho người không nên thấy

Cost Estimation (Annual)

ComponentSpecSố lượngChi phí ước tính
Connection Servers64 GB RAM, 16 cores2,500~$15M/năm
Message Storage (SSD)NVMe, 30-day retention500 TB active~$3M/năm
Media Storage (Object)S3-class, 30-day TTL180 PB~$50M/năm
BandwidthMulti-TbpsGlobal~$30M/năm
Key StoreLow-latency SSDReplicated~$2M/năm
Tổng ước tính~$100M/năm

Media storage chiếm phần lớn chi phí — đây là lý do WhatsApp áp dụng aggressive compression (ảnh bị nén xuống ~100KB) và TTL (media tự xóa sau 30 ngày trên server, nhưng vẫn tồn tại trên device).

Checklist ghi nhớ

✅ Checklist triển khai

Connection & Routing

  • [ ] WebSocket/MQTT persistent connection cho real-time message delivery
  • [ ] Distributed Hash Table (DHT) cho mapping user → connection server
  • [ ] Heartbeat mechanism (30s interval) để detect dead connections
  • [ ] Graceful reconnection với automatic message replay từ offline queue

Encryption & Security

  • [ ] E2E encryption mặc định cho mọi message (Signal Protocol)
  • [ ] Forward secrecy — mỗi message sử dụng key duy nhất, key cũ bị xóa
  • [ ] Sender Keys optimization cho group messaging
  • [ ] Server chỉ lưu encrypted blobs — không plaintext, không index nội dung

Message Delivery

  • [ ] 3-tick delivery status: ✓ sent → ✓✓ delivered → ✓✓ read (blue)
  • [ ] Offline message queue với TTL 30 ngày
  • [ ] At-least-once delivery guarantee + client-side deduplication bằng message_id
  • [ ] Message ordering bảo toàn bằng server-assigned sequence numbers per conversation

Media & Presence

  • [ ] Media upload pipeline tách biệt khỏi message routing flow
  • [ ] Encrypted media trên Object Storage, decryption key gửi trong E2E message
  • [ ] Presence updates chỉ fan-out cho contacts, không global broadcast
  • [ ] Rate limiting cho presence updates (max 1 lần/10 giây) để tránh flapping

Bài tập luyện tập

Bài 1: Tính toán Connection Servers

Đề bài: WhatsApp có 500M concurrent users. Mỗi connection server handle được 500K connections. Mỗi connection tiêu tốn 10 KB RAM. Hãy tính:

  1. Số connection servers tối thiểu cần thiết
  2. Tổng RAM cần thiết cho connection layer
  3. Nếu cần 50% headroom cho peak, số server và RAM thực tế là bao nhiêu?

🧠 Quiz

Đáp án:

  1. Servers tối thiểu = 500,000,000 ÷ 500,000 = 1,000 servers
  2. Tổng RAM = 500,000,000 × 10 KB = 5,000,000,000 KB = ~4.65 TB
  3. Với 50% headroom:
    • Servers = 1,000 × 1.5 = 1,500 servers
    • RAM = 4.65 TB × 1.5 = ~7 TB

Mở rộng: Trong thực tế, cần thêm headroom cho OS overhead (~2 GB/server), application logic, và buffer cho traffic burst. Con số thực tế thường là 2x-2.5x số tối thiểu.

Bài 2: Thiết kế Read Receipts qua E2E Encryption

Đề bài: Thiết kế hệ thống read receipt (blue tick) hoạt động với E2E encryption. Yêu cầu:

  • Server không biết ai đã đọc message nào
  • Sender phải nhận được read receipt
  • Hoạt động khi sender hoặc recipient offline
💡 Xem gợi ý và lời giải

Phân tích:

Read receipt bản chất là một message ngược từ recipient → sender, nội dung là "tôi đã đọc message_id X".

Thiết kế:

1. Bob nhận và decrypt message (message_id = M123) từ Alice
2. Bob mở chat → app tạo read receipt:
   payload = { type: "read_receipt", message_id: "M123", timestamp: now() }
3. Encrypt payload bằng Signal Protocol (Bob → Alice session)
4. Gửi encrypted receipt qua message routing pipeline
5. Alice nhận, decrypt → cập nhật UI: ✓✓ → ✓✓ blue cho M123

Xử lý offline:

  • Nếu Alice offline khi Bob gửi read receipt → receipt được store trong offline queue (giống message thường)
  • Khi Alice online → receive tất cả pending receipts → batch update UI

Optimization:

  • Batch read receipts: thay vì gửi 1 receipt per message, gửi 1 receipt cho "tất cả messages đến timestamp T"
  • Giảm bandwidth đáng kể trong group chats

Server perspective:

  • Server thấy một encrypted blob đi từ Bob → Alice
  • Không phân biệt được read receipt với tin nhắn thường
  • Kích thước nhỏ hơn (vài chục bytes vs vài trăm bytes) là hint duy nhất, nhưng padding có thể mask điều này

Bài 3: Thiết kế Group Video Call cho 32 participants

Đề bài: Mở rộng kiến trúc WhatsApp để hỗ trợ group video call tối đa 32 người. Cần giải quyết:

  • Topology: Mesh vs SFU vs MCU
  • Bandwidth management
  • Encryption trong video call
  • Xử lý participant join/leave giữa chừng
💡 Xem gợi ý và lời giải

Topology Analysis:

TopologyMeshSFUMCU
ConceptMỗi peer gửi stream cho mọi peer khácPeers gửi lên server, server forwardServer mix tất cả thành 1 stream
Upload bandwidth (32p)31 streams1 stream1 stream
Download bandwidth (32p)31 streams31 streams1 stream
Server loadKhôngForward onlyEncode/decode (CPU-heavy)
E2E encryption✅ Dễ✅ Khả thi❌ Server phải decode
Scalable to 32?

Chọn SFU (Selective Forwarding Unit):

  • Giữ được E2E encryption (server forward encrypted streams mà không decode)
  • Upload bandwidth hợp lý: mỗi participant chỉ gửi 1 stream lên SFU
  • Download bandwidth: nhận 31 streams, nhưng có thể dùng simulcast (gửi multiple quality levels, server forward quality phù hợp)

Bandwidth Estimation (32 participants):

Video quality: 720p = ~1.5 Mbps per stream
Upload per participant: 1.5 Mbps (1 stream)
Download per participant: 31 × 1.5 Mbps = 46.5 Mbps (quá nhiều!)

Giải pháp - Simulcast + Adaptive:
- Active speaker: 720p (1.5 Mbps)
- 5 recent speakers: 360p (0.5 Mbps)
- 26 remaining: Thumbnail 180p (0.15 Mbps)
- Download thực tế: 1.5 + 5×0.5 + 26×0.15 = ~7.9 Mbps ✅

Encryption cho video call:

  • Sử dụng Insertable Streams API (WebRTC)
  • Frame-level encryption: mỗi video frame được encrypt trước khi gửi
  • SFU forward encrypted frames mà không cần decode
  • Mỗi participant có encryption key riêng, distributed qua Signal Protocol session

Join/Leave handling:

  • Participant join → SFU thêm vào forwarding table → gửi key exchange messages
  • Participant leave → SFU xóa khỏi forwarding table → rekeying cho remaining participants
  • Rekeying sử dụng mechanism tương tự group messaging sender key rotation

Liên kết học tiếp

Thuật ngữ

Thuật ngữGiải thích
E2E EncryptionEnd-to-End Encryption — mã hóa đầu-cuối, chỉ sender và recipient decrypt được
Signal ProtocolGiao thức mã hóa tin nhắn được sử dụng bởi WhatsApp, Signal, và nhiều ứng dụng khác
X3DHExtended Triple Diffie-Hellman — giao thức trao đổi key ban đầu
Double RatchetThuật toán tạo key mới cho mỗi message, đảm bảo forward secrecy
Forward SecrecyThuộc tính bảo mật: compromise key hiện tại không lộ message quá khứ
Sender KeysKỹ thuật tối ưu encryption cho group messaging
DHTDistributed Hash Table — bảng băm phân tán cho user→server mapping
SFUSelective Forwarding Unit — server forward video streams mà không decode
MQTTMessage Queuing Telemetry Transport — protocol lightweight cho IoT và mobile
epoll/kqueueI/O multiplexing APIs trên Linux/FreeBSD cho high-concurrency networking
PresenceTrạng thái online/offline/last seen của user trong hệ thống
At-least-onceGuarantee rằng message được deliver ít nhất 1 lần (có thể duplicate)