Cache-aside (lazy loading) là pattern phổ biến nhất: đọc cache → miss → truy vấn DB → ghi cache → trả về.
js
const cached = await redis.get(key)
if (cached) return JSON.parse(cached)
const data = await db.query(...)
await redis.setex(key, 300, JSON.stringify(data))
return dataHai biến thể còn lại đánh đổi khác nhau: write-through ghi cache và DB cùng lúc — data luôn fresh nhưng write chậm hơn; write-behind ghi cache trước rồi flush xuống DB bất đồng bộ — write rất nhanh nhưng mất data nếu cache sập.
- Invalidation: TTL (đơn giản, chấp nhận data cũ), event-based (update xong thì xoá key), hoặc versioned key (
user:${id}:v${version}). - Chọn TTL theo tần suất đổi: data ít đổi → 1 giờ; data đổi nhiều → 30 giây hoặc invalidate ngay khi ghi.
- Cache warming: gọi
warmCache()sau khi server start để tránh cold start. - Thundering herd: nhiều request cùng lúc miss một key vừa hết hạn rồi đồng loạt truy vấn DB. Cách chữa: renew sớm theo xác suất, mutex cho một request đi query, hoặc stale-while-revalidate.
Lưu ý: tránh đụng key bằng cách luôn đặt namespace ${service}:${resource}:${id}.