TechPartner

← Quay lại Blog
Khóa học System Design cơ bản — thiết kế hệ thống scale 1 → 1 triệu user · Phần 4 / 10

Redis & CDN (4/10): Cache-aside System Design cho ~1.000 user

Redis cache-aside, TTL, invalidation, CDN static, rate limit — giảm tải PostgreSQL khi redirect ShortLink tăng; xử lý hot key viral.

· 3 min read

Khóa học System Design cơ bản — thiết kế hệ thống scale 1 → 1 triệu user · Phần 4/10
  1. 1Nền tảng metric & CAP
  2. 2Monolith 1 server
  3. 3Tách DB & vận hành
  4. 4Redis + CDN
  5. 5Read replica
  6. 6Load balancer
  7. 7Message queue
  8. 8Sharding & đa vùng
  9. 9Phỏng vấn & cheat sheet
  10. 10Capstone ShortLink
Mục lục
  1. Mục tiêu phần 4
  2. Kiến trúc
  3. Cache-aside — từng bước redirect
  4. Cache stampede (miss đồng loạt)
  5. CDN — cái gì đi CDN, cái gì không
  6. Rate limiting
  7. Hot key & memory Redis
  8. Checklist trước khi sang phần 5
  9. Bài tập
CDNUsers (~1K)AppRedis cachePostgreSQLRate limit (edge)
Giai đoạn ~1.000 người dùng: Redis cache-aside và CDN cho static.

Mục tiêu phần 4

Ở ~1.000 người dùng, redirect bắt đầu lặp lại cùng slug — database đọc nhiều hơn cần thiết. Phần này thêm Redis (cache-aside), CDN cho static, và rate limit — vẫn một app server.


Kiến trúc

Browser ──► CDN (static JS/CSS/img)
         └──► Nginx ──► App ──► Redis (cache slug → url)
                           └──► PostgreSQL (source of truth)
Component Vai trò cụ thể
Redis Giảm SELECT theo slug; chịu hot key viral
CDN Cache file tĩnh gần user; giảm egress app
Nginx limit_req Giới hạn POST tạo link theo IP
App Logic cache-aside + invalidate

Cache-aside — từng bước redirect

GET /:slug
  1. key = "sl:" + slug
  2. val = Redis GET key
  3. if val is null:
       row = DB SELECT target_url WHERE slug=?
       if row missing → 404
       Redis SET key JSON(row) EX 300
     else parse val
  4. (optional) record click — sync DB hoặc defer phần 6
  5. HTTP 302 Location: target_url
Quyết định thiết kế Khuyến nghị ShortLink
TTL 60–300 giây — cân bằng stale URL vs hit rate
Key naming sl:{slug} — namespace tránh collision
Value {"u":"https://...","v":3}v tăng khi đổi URL để debug
Invalidate DEL sl:{slug} ngay sau PATCH/DELETE
Thundering herd Optional: lock ngắn khi miss (singleflight)

Cache stampede (miss đồng loạt)

TTL hết cùng lúc → hàng trăm request cùng SELECT. Singleflight: request đầu giữ lock lock:sl:abc, các request khác chờ hoặc retry Redis sau 10ms.


CDN — cái gì đi CDN, cái gì không

Đi Không (hoặc TTL rất ngắn)
/assets/*, favicon, marketing GET /:slug redirect động
Dashboard bundle JS/CSS API JSON có auth

Redirect có thể cache ở CDN chỉ khi URL ít đổi và bạn chấp nhận stale — thường không cache redirect toàn cầu ở giai đoạn 1K user.


Rate limiting

limit_req_zone $binary_remote_addr zone=create_link:10m rate=1r/s;
# burst cho phép nhịp ngắn

App-level: token bucket 60 POST / phút / IP + captcha nếu vượt ngưỡng 2 lần.


Hot key & memory Redis

Slug viral: một key nhận 5k GET/s — Redis single-thread vẫn thường đủ (in-memory). Ước lượng: 100k slug hot × 500 byte ≈ 50 MB — nhỏ.

Monitor: used_memory, evictions (nếu bật maxmemory-policy).


Checklist trước khi sang phần 5

  • Hit rate cache > 90% trên redirect
  • Alert Redis down → fallback đọc DB (degraded, chậm hơn)
  • Document TTL và cách invalidate

Bài tập

  1. Peak 500 RPS read, hit rate 95% — DB chịu bao nhiêu RPS? (25)
  2. User đổi target_url — liệt kê 3 bước bắt buộc để không redirect sai.
  3. Vẽ sequence cache miss + singleflight.

Điều hướng seri: ← Phần 3 · Phần 5 →

Câu hỏi thường gặp

Phần 4 tập trung vào quy mô nào?

Redis cache-aside, TTL, invalidation, CDN static, rate limit — giảm tải PostgreSQL khi redirect ShortLink tăng; xử lý hot key viral.

Cache-aside khác write-through thế nào?

Cache-aside: app đọc cache trước, miss thì đọc DB rồi ghi cache. Write-through: mọi write ghi đồng thời DB và cache — đơn giản consistency nhưng write chậm hơn và cache chứa data ít dùng.

Startup của bạn cần tech partner?

Trao đổi miễn phí về MVP, timeline và mô hình chia lợi nhuận phù hợp.