# Gu thiết kế Bộ nhớ đệm Redis (Redis Caching) của một kỹ sư backend - Mặc định sử dụng mô hình cache-aside: đọc từ Redis, truy xuất lại từ nguồn dữ liệu gốc (source of truth) khi không tìm thấy trong cache (cache miss), sau đó nạp dữ liệu vào cache. Độ tin cậy: 0.90 - Coi bộ nhớ đệm là dữ liệu có thể loại bỏ bất cứ lúc nào; hệ thống vẫn phải hoạt động chính xác (chỉ chậm hơn) nếu toàn bộ dữ liệu Redis bị xóa sạch (flushed). Độ tin cậy: 0.95 - Thiết lập thời gian hết hạn (TTL) trên mọi khóa cache; một khóa không có thời hạn sử dụng chính là mầm mống gây rò rỉ bộ nhớ (memory leak). Độ tin cậy: 0.90 - Thêm độ lệch ngẫu nhiên (random jitter) vào các giá trị TTL để các khóa được ghi cùng lúc không bị hết hạn đồng loạt. Độ tin cậy: 0.85 - Đặt không gian tên (namespace) cho khóa theo định dạng service:entity:id:version (ví dụ: catalog:product:42:v3) và tăng số phiên bản khi có thay đổi định dạng gây phá vỡ tương thích. Độ tin cậy: 0.85 - Vô hiệu hóa cache bằng cách xóa khóa sau khi ghi dữ liệu thành công, thay vì cập nhật trực tiếp giá trị đang lưu trong cache. Độ tin cậy: 0.80 - Bảo vệ các khóa có tần suất truy cập cao (hot keys) khỏi hiện tượng quá tải đột ngột (cache stampede) bằng khóa ngắn hạn (SET key value NX PX) hoặc gộp nhóm yêu cầu (request coalescing). Độ tin cậy: 0.80 - Lưu vào cache cả các kết quả rỗng (không tìm thấy) với TTL ngắn để giảm tải các truy vấn lặp lại cho những ID không tồn tại. Độ tin cậy: 0.70 - Lưu trữ các giá trị đã tuần tự hóa (serialized) nhỏ gọn (dùng JSON để dễ gỡ lỗi, dùng MessagePack khi kích thước là yếu tố quan trọng) và giữ kích thước giá trị dưới khoảng 100 KB. Độ tin cậy: 0.75 - Sử dụng kiểu dữ liệu hash cho các đối tượng có từng trường (fields) được đọc riêng lẻ, và dùng chuỗi đơn thuần (plain strings) cho các giá trị được đọc nguyên khối. Độ tin cậy: 0.70 - Không bao giờ chạy lệnh KEYS trên môi trường thực tế (production); hãy sử dụng lệnh SCAN với con trỏ (cursor). Độ tin cậy: 0.95 - Tránh tạo các khóa quá lớn (big keys) và các tập hợp khổng lồ; hãy tách nhỏ bất kỳ dữ liệu nào có thể khiến một lệnh đơn lẻ bị chặn (block) tới vài mili-giây. Độ tin cậy: 0.85 - Sử dụng kỹ thuật pipelining hoặc lệnh MGET để đọc theo lô (batch reads) thay vì gửi từng yêu cầu mạng riêng biệt cho mỗi khóa. Độ tin cậy: 0.85 - Đưa các logic nguyên tử (atomic) gồm nhiều bước vào một kịch bản Lua (Lua script) hoặc một hàm, chứ không thực hiện kiểm tra rồi mới gán giá trị (check-then-set) ở phía client. Độ tin cậy: 0.80 - Thiết lập maxmemory kèm theo chính sách trục xuất dữ liệu (eviction policy) rõ ràng (allkeys-lru cho bộ nhớ đệm thuần túy, noeviction cho dữ liệu tuyệt đối không được mất). Độ tin cậy: 0.90 - Tách biệt bộ nhớ đệm và dữ liệu bền vững (hàng đợi, giới hạn tốc độ, phiên đăng nhập) vào các phiên bản (instances) Redis riêng với các chính sách riêng. Độ tin cậy: 0.80 - Sử dụng Redis Streams hoặc một hệ thống message broker thực thụ cho các tác vụ nền (jobs); kiểu danh sách (lists) đơn thuần sẽ làm mất tác vụ khi tiến trình xử lý (consumer) bị sập. Độ tin cậy: 0.70 - Triển khai giới hạn tần suất (rate limiting) bằng kịch bản cửa sổ trượt (sliding window) hoặc xô thẻ bài (token bucket), không dùng cách kết hợp lệnh INCR và EXPIRE tạm bợ dễ gây lỗi tranh chấp (race conditions). Độ tin cậy: 0.75 - Thiết lập thời gian chờ (timeouts) ở phía client và bộ ngắt mạch (circuit breaker) để khi Redis bị chậm thì hệ thống chỉ chuyển sang trạng thái cache miss chứ không làm sập toàn bộ dịch vụ. Độ tin cậy: 0.90 - Giám sát tỷ lệ trúng cache (hit ratio), số lượng khóa bị trục xuất (evictions), độ phân mảnh bộ nhớ và độ trễ, đồng thời cảnh báo khi tỷ lệ trúng cache sụt giảm. Độ tin cậy: 0.85 - Bắt buộc xác thực (auth) và mã hóa TLS, vô hiệu hóa hoặc đổi tên các lệnh nguy hiểm (FLUSHALL, CONFIG), và tuyệt đối không phơi bày Redis trực tiếp ra ngoài internet. Độ tin cậy: 0.95 - Đừng đưa vào cache những gì vốn đã nhanh; hãy đo lường độ trễ của nguồn dữ liệu gốc trước khi thêm một lớp bộ nhớ đệm. Độ tin cậy: 0.80
Đánh giá các tiêu đề bộ nhớ đệm HTTP (Cache-Control, Expires, ETag, Last-Modified, Vary, Set-Cookie) cho các trang web, tài sản tĩnh (assets) và API. Tính toán thời gian còn hiệu lực (freshness) trên trình duyệt và CDN, gắn cờ cảnh báo các phản hồi chứa cookie hoặc dữ liệu cá nhân mà CDN có nguy cơ lưu chung, trang HTML được lưu đệm quá lâu, tài sản đã gắn mã băm (hashed) lại lưu đệm quá ngắn, thuộc tính immutable gắn trên các URL có nội dung thay đổi, phân mảnh bộ nhớ đệm do Vary, thiếu bộ xác thực (validator), lưu đệm theo suy đoán (heuristic caching) và lưu đệm cả các phản hồi lỗi. Đề xuất tiêu đề phù hợp cho từng loại tài nguyên. Bao gồm công cụ kiểm tra viết bằng thư viện chuẩn Python có hỗ trợ cờ `--self-test`.
Đánh giá các bảng PostgreSQL và MySQL (tệp schema.sql, bản dump hoặc lệnh CREATE TABLE trong pull request) để tìm ra các lỗi thiết kế có thể sửa dễ dàng và ít tốn kém trước khi có dữ liệu thực tế - thiếu khóa chính, lưu tiền tệ bằng cột số thực (float), khóa ngoại lệch kiểu dữ liệu hoặc thiếu chỉ mục (index), ID 32-bit, dấu thời gian (timestamp) không kèm múi giờ, các cờ (flags) cho phép NULL, trạng thái dạng văn bản tự do, đặt tên trùng từ khóa dành riêng và email duy nhất (unique) nhưng phân biệt chữ hoa chữ thường. Trả về mã DDL đã được hiệu chỉnh. Bao gồm một công cụ linter viết bằng thư viện chuẩn Python có hỗ trợ cờ --self-test.
Đánh giá các truy vấn SQL và kết quả EXPLAIN tùy chọn nhằm phát hiện các vấn đề hiệu năng phổ biến như SELECT *, dùng hàm hoặc ép kiểu (cast) trên các cột đã đánh chỉ mục, LIKE có ký tự đại diện (wildcard) ở đầu, vòng lặp truy vấn N+1, dùng OR giữa nhiều cột so với UNION ALL, lỗi thứ tự ưu tiên AND/OR, truy vấn con NOT IN, phân trang OFFSET sâu, quét tuần tự (seq scan) và sắp xếp trên ổ đĩa (disk sort). Giải thích từng vấn đề và cung cấp câu truy vấn viết lại. Đi kèm công cụ kiểm tra bằng thư viện chuẩn Python có hỗ trợ --self-test.
Đánh giá lược đồ (schema) và các truy vấn SQL chạy chậm, đề xuất các chỉ mục phức hợp (composite indexes) theo đúng thứ tự cột (so sánh bằng, sắp xếp, khoảng giá trị) kèm các cột bao phủ (covering columns) và sự đánh đổi hiệu năng, gắn cờ các bộ lọc không thể tận dụng chỉ mục (non-sargable) như dùng hàm trên cột hoặc LIKE có ký tự đại diện ở đầu, đồng thời cảnh báo về các chỉ mục trùng lặp, dư thừa và có độ chọn lọc thấp. Sử dụng khi người dùng chia sẻ một truy vấn chậm, kết quả EXPLAIN, hoặc schema và hỏi "tôi cần chỉ mục nào?" hoặc "có quá nhiều chỉ mục không?". Bao gồm công cụ hỗ trợ bằng thư viện chuẩn Python đã được kiểm thử.