Từ 250ms xuống 0ms: request “đi tắt” qua 4 tầng cache
Tóm tắt
Hệ thống thường có nhiều tầng cache: trình duyệt, CDN, Redis, rồi mới tới database. Request đi từ trên xuống và dừng ở tầng đầu tiên có dữ liệu. Lần đầu (miss hết) tốn nhiều nhất, nhưng trên đường về dữ liệu được lưu lại ở từng tầng cho các lần sau.
Một trang tải trong 250ms lần đầu và gần như tức thì từ lần thứ hai. Phần lớn sự khác biệt đến từ cache nhiều tầng. Hệ thống web thường xếp các tầng cache theo thứ tự: trình duyệt, CDN, Redis (hoặc cache ứng dụng), rồi mới tới database. Request đi từ trên xuống và dừng ở tầng đầu tiên có dữ liệu. Lần đầu (miss hết) tốn nhiều nhất, nhưng trên đường về dữ liệu được lưu lại ở từng tầng cho các lần sau.
Ba lượt request
| Lượt | Dừng ở tầng | Thời gian |
|---|---|---|
| 1 — cache nguội | Database (miss cả 3 tầng cache) | ~250ms |
| 2 | Browser | ~0ms |
| 3 — TTL tầng trên hết hạn | Redis | ~80ms |
Vai trò từng tầng
| Tầng | Lưu gì | Công cụ điều khiển |
|---|---|---|
| Trình duyệt | Tài nguyên tĩnh, API ít đổi | Cache-Control, ETag |
| CDN | Nội dung chung cho nhiều người dùng ở gần họ | Cache rule, purge, TTL |
| Redis / cache ứng dụng | Kết quả truy vấn, session, dữ liệu tính toán tốn kém | TTL, xoá key khi dữ liệu đổi |
| Database | Nguồn sự thật | Index, buffer cache của chính DB |
Càng sớm càng rẻ
Tầng càng sâu thì mỗi lượt truy cập càng tốn tài nguyên và thời gian. Cache ở trình duyệt không tốn băng thông, không tốn máy chủ; cache ở CDN đỡ cho máy chủ gốc; Redis đỡ cho database. Mục tiêu là chặn request ở tầng cao nhất có thể.
Những vấn đề kinh điển
- Dữ liệu cũ (stale): cache giữ giá trị cũ sau khi dữ liệu thay đổi.
- Cache stampede: khi key phổ biến hết hạn, nhiều request cùng lúc đập vào database; giảm bằng khoá hoặc làm mới sớm.
- Dữ liệu riêng tư lọt vào cache chung: CDN cache nhầm response cá nhân.
- Khó debug: không biết dữ liệu đến từ tầng nào; cần header/log chỉ rõ HIT/MISS.
Áp dụng thế nào?
- Chặn càng sớm càng tốt: ưu tiên cache ở browser/CDN cho nội dung tĩnh hoặc ít thay đổi (
Cache-Control,ETag). - Đặt TTL theo mức độ chấp nhận dữ liệu cũ của từng loại dữ liệu — giá sản phẩm khác ảnh đại diện.
- Có chiến lược invalidation khi dữ liệu thay đổi (xoá key Redis, purge CDN), đừng chỉ chờ TTL.
- Cẩn thận dữ liệu riêng tư: không để CDN cache response chứa thông tin cá nhân (
Cache-Control: private). - Theo dõi hit rate của từng tầng; hit rate thấp nghĩa là cache đang tốn tiền mà không giúp gì.
Nguồn & tham khảo
- HTTP caching — MDN Web Docs