Cache & Redis Cơ bản
Thêm cache thường là cách nhanh nhất để giảm tải database. Đổi lại, hệ thống có thêm một bản sao dữ liệu, và mọi câu hỏi khó đều xoay quanh bản sao đó: cập nhật lúc nào, ai chịu trách nhiệm khi nó sai, chuyện gì xảy ra khi nó biến mất đúng lúc tải cao nhất.
Các bài và câu hỏi chúng trả lời
Phần tiêu đề “Các bài và câu hỏi chúng trả lời”| Câu hỏi | Bài | Kết luận chính |
|---|---|---|
| Ứng dụng đọc/ghi cache theo pattern nào? | Cache-aside | Ghi DB trước, xoá key sau; vẫn có race làm cache giữ bản cũ tới khi TTL hết. |
| Một hot key hết hạn thì sao? | Cache stampede | Nhiều request cùng miss và cùng đổ xuống DB; gộp request, khoá có token hoặc làm mới sớm. |
| Key biến mất vì hết hạn hay vì thiếu memory? | Expiration và eviction | So expired_keys với evicted_keys trước khi đụng tới TTL. |
| Redis thực thi command thế nào? | Event loop và I/O threads | Command chạy tuần tự trên một thread; một lệnh chậm làm PING của client khác chờ. |
| Lưu dữ liệu bằng kiểu nào? | Redis data structures | Chọn theo thao tác: sorted set để xếp hạng, HyperLogLog để đếm duy nhất, hash cho object. |
Restart hay kill -9 thì mất bao nhiêu? |
Persistence: RDB và AOF | Mặc định chỉ có RDB: mất mọi ghi sau snapshot cuối; AOF everysec mất khoảng 1 s khi máy sập. |
| Gom nhiều lệnh thì có nguyên tử không? | Pipelining, MULTI và Lua | Pipeline chỉ giảm round trip; kiểm tra-rồi-ghi cần Lua hoặc WATCH. |
| Lock Redis có bảo đảm chỉ một bên chạy? | Distributed lock | Lock có TTL vẫn có lúc hai chủ; cần fencing token ở tài nguyên đích. |
| Có cache mà DB vẫn quá tải? | Cache penetration & avalanche | Id không tồn tại xuyên cache; nhiều key hết hạn cùng lúc; dùng bloom filter, TTL jitter. |
Bốn vấn đề này độc lập: đúng cache-aside vẫn có thể sập vì stampede, không gặp stampede vẫn có thể có p99 xấu vì một job báo cáo chiếm luồng command.
Chọn đường đọc theo triệu chứng
Phần tiêu đề “Chọn đường đọc theo triệu chứng”| Tình huống đang gặp | Đọc theo thứ tự |
|---|---|
| Mới bắt đầu dùng Redis làm cache | Cache-aside → Event loop |
| p99 tăng đột ngột dù số request không đổi | Event loop → kiểm tra SLOWLOG và kích thước key |
| Database bị dồn tải mỗi khi cache hết hạn | Cache stampede |
| Hit rate giảm, key biến mất sớm hoặc Redis đầy RAM | Expiration và eviction |
| Dữ liệu trong cache lệch với database | Cache-aside, phần race và invalidation |
| Bán vượt tồn kho khi trừ trong Redis | Pipelining, MULTI và Lua |
| Cron chạy trùng trên nhiều pod dù đã có lock | Distributed lock |
| DB tăng tải theo chu kỳ hoặc bị bot gọi id rác | Cache penetration & avalanche |
| Redis restart xong mất session | Persistence: RDB và AOF |