Cache Limitations & Cache Invalidation
Tổng quan
Caching không phải là giải pháp hoàn hảo.
Mọi hệ thống cache đều gặp 2 vấn đề lớn:
Cache Limitations
│
┌────────────┴────────────┐
▼ ▼
Cache Space Limited Cache Invalidation
(RAM đắt, có giới hạn) (Dữ liệu stale)
Cache Hit Ratio – KPI quan trọng nhất
Total Requests
┌──────────┴──────────┐
▼ ▼
Cache Hit Cache Miss
Cache Hit Ratio = Cache Hits / Total Requests
Ví dụ: 1.000 requests → 900 hit cache, 100 xuống Database:
Cache Hit Ratio = 900 / 1000 = 90%
- Hit Ratio cao → ít phải xuống Database → cache hiệu quả.
- Hit Ratio 10% → gần như vô dụng.
Limitation 1 – Cache Space Limited
Cache thường nằm trong RAM (Redis, Memcached) — RAM rất đắt, không thể cache toàn bộ Database.
Database: 5 TB → Cache toàn bộ → Cần Redis 5 TB RAM → Không khả thi
Phải chọn dữ liệu để cache
Good Cache Candidate
│
┌──────────────┴──────────────┐
▼ ▼
Frequently Read Rarely Updated
│ │
└──────────────┬──────────────┘
▼
Cache
Ví dụ:
| Sản phẩm | Lượt xem | Tần suất đổi giá | Nên cache? |
|---|---|---|---|
| Slow-moving item | Ít, 6 tháng/lần | Không đổi | ❌ Không |
| iPhone | 1.000/phút | 1 tuần/lần | ✔ Nên |
Kích thước object cũng quan trọng
Nếu cache capacity = 100 MB:
Small Objects (10 KB) Large Objects (1 MB)
→ Cache được 100 items → Chỉ cache 10 items
→ Hit Ratio cao hơn → Hit Ratio thấp hơn
Quy tắc: Nếu giá trị truy cập tương đương → ưu tiên cache Small Objects để tăng Hit Ratio.
Limitation 2 – Cache Invalidation
Bài toán nổi tiếng nhất của Caching.
Database Cache
Price = 90$ ←─ outdated ─→ Price = 100$
Khi Database cập nhật nhưng Cache chưa được làm mới → Stale Cache / Cache Inconsistency.
Chiến lược xử lý Stale Cache
Strategy 1 – Update/Delete Cache khi Update Source
Write Request
│
▼
Update DB
│
┌────────┴────────┐
▼ ▼
Update Cache Delete Cache
Delete Cache hoạt động như sau:
Delete Product #10 cache
│
▼
Next Request → Cache Miss → Database → Reload Cache → Return
Cache tự được build lại từ request tiếp theo.
Ưu điểm: Cache luôn gần giống Database, window inconsistency chỉ vài millisecond.
Nhược điểm: Chỉ làm được với cache do mình quản lý (Redis, Memcached, Object Cache). Không làm được với Proxy, CDN, Browser vì không kiểm soát được.
Strategy 2 – TTL (Time To Live)
Mỗi cache object có thời gian sống:
Cache Object
TTL = 300 seconds
0 ───────────► 300
│
▼
Expired
│
▼
Reload Database
HTTP cũng dùng TTL thông qua:
Cache-Control: max-age=300
TTL quá cao:
TTL = 1 giờ, DB update mỗi 5 phút
→ Cache sai trong 55 phút còn lại
TTL quá thấp:
TTL = 5 phút, DB update mỗi 1 giờ
→ Cứ 5 phút cache miss dù dữ liệu không đổi
→ Hit Ratio giảm
TTL luôn là Trade-off:
TTL
Too Low Too High
│ │
▼ ▼
More Cache Miss More Stale Data
TTL cao → Hit Ratio cao → Freshness thấp
TTL thấp → Freshness cao → Hit Ratio thấp
So sánh 2 chiến lược
| Update/Delete Cache | TTL |
|---|---|
| Đồng bộ ngay khi update DB | Hết hạn theo thời gian |
| Cache luôn mới | Có thể stale |
| Phù hợp Redis / Object Cache | Phù hợp Browser / CDN / Public Cache |
| Phức tạp hơn | Đơn giản hơn |
Tổng kết
Cache Strategy
│
┌───────────────┴───────────────┐
▼ ▼
Cache Space Cache Invalidation
│ │
▼ ▼
Select Best Objects Keep Cache Consistent
│ │
┌────┴─────┐ ┌─────────┴─────────┐
▼ ▼ ▼ ▼
Read Often Small Objects Update/Delete Cache TTL
(Expiration)
└──────────────────────┘
│
▼
High Cache Hit Ratio
- Cache Hit Ratio là thước đo quan trọng nhất. Hit Ratio càng cao → càng ít request xuống Database.
- Do RAM có chi phí cao, hãy ưu tiên cache dữ liệu đọc thường xuyên, ít thay đổi, kích thước nhỏ.
- Update/Delete Cache: nhất quán cao, chỉ áp dụng được với cache do hệ thống kiểm soát.
- TTL: đơn giản, áp dụng được cho cả Browser/CDN/Public Cache, nhưng luôn phải đánh đổi giữa Freshness và Hit Ratio.