Part 04 · PostgreSQL & Redis · 4.4

Sai lầm và checklist dữ liệu

Tự đánh giá không phải kiểm tra nhớ thuật ngữ. Bạn phải nối invariant với schema/transaction, query với plan, cache với consistency window và HA với evidence từ failure drill.


6 red flags trong câu trả lời

“Index luôn tốt và miễn phí”

Index tăng storage, WAL, cache pressure và write/maintenance cost. Chỉ tạo từ access pattern và xác nhận bằng plan cùng production-like data.

“ACID tự bảo vệ mọi business invariant”

Database chỉ bảo vệ invariant được biểu diễn bằng constraints, transaction logic và isolation phù hợp. Application vẫn phải model state transition, idempotency và external effects.

“Read replica luôn có dữ liệu mới”

Async replication có lag. Read-after-write cần route primary, session strategy hoặc wait-for-position trong deadline.

“Redis nhanh nên dùng cho mọi thứ”

Cache thêm invalidation, memory, failure và operational cost. Nếu hit ratio thấp hoặc freshness mạnh, Redis có thể làm hệ thống phức tạp hơn mà không cải thiện outcome.

“TTL là invalidation strategy hoàn chỉnh”

TTL chỉ giới hạn lifetime/stale window; nó không giải quyết stale repopulation, tenant/auth keying, out-of-order events hoặc stampede.

“Redis replication/failover không mất write”

Replication mặc định asynchronous. Acknowledged write có thể chưa tới replica được promote; WAIT cũng không tự tạo strong consistency hay guarantee fsync.

8 lỗi triển khai thường gặp

1. Connection pools lớn hơn database capacity

Mỗi application replica nhân pool size thành tổng sessions. Hậu quả là queue multiplication, context switching, memory và lock contention. Theo dõi acquisition wait và size từ end-to-end capacity.

2. Long transaction giữ snapshot hoặc lock

Remote call, user wait hoặc idle transaction kéo dài blocking và ngăn VACUUM reclaim tuples. Đặt timeout, transaction boundary ngắn và alert theo transaction age.

3. Chỉ validate ở application, không có constraint

Hai writers có thể race hoặc writer khác bỏ qua validation. Dùng NOT NULL, CHECK, UNIQUE, foreign key/exclusion khi database biểu diễn được invariant.

4. Đọc EXPLAIN chỉ để tìm chữ “Index”

Phải đọc actual-vs-estimated rows, loops, buffers, join order, sort/hash spill và heap fetches. Sequential scan có thể đúng; index scan cũng có thể rất đắt.

5. Dùng OFFSET cho pagination sâu mà không đo

Database vẫn scan/discard rows trước offset và results drift khi data đổi. Dùng stable keyset cursor khi access pattern cho phép.

6. Cache key không namespace/version hoặc để hot/big key vô hạn

Key collision có thể lộ dữ liệu giữa tenant/version; unbounded structures gây memory và latency spikes. Thiết kế key schema, TTL, size/cardinality limit và migration.

7. Không có fallback khi Redis down

Toàn bộ miss dồn vào DB có thể tạo cascading failure. Cache timeout ngắn, origin concurrency cap, coalescing, rate limit, stale policy và controlled warmup là bắt buộc.

8. Distributed lock thiếu owner token hoặc fencing

Delete mù có thể xóa lock của owner mới; lease expiry không chặn stale owner ghi downstream. Compare-token release là tối thiểu, fencing hoặc primitive tại database bảo vệ invariant mạnh hơn.

Checklist kiến thức và evidence

Readiness gate

Chưa đạt nếu: câu trả lời chỉ nêu feature mà không có failure mode; lab không tái hiện failure trước khi fix; plan/metric không ghi workload; backup chưa từng restore; cache failover chưa đo lost-write/stale window.
  1. Chọn ngẫu nhiên 10/49 câu và trả lời không xem tài liệu; ít nhất 8 câu đúng, có trade-off.
  2. Vẽ một transaction timeline, một PostgreSQL HA topology và một Redis Cluster slot flow trong 15 phút.
  3. Review evidence của 3 labs bất kỳ: người khác phải chạy lại được từ README.
  4. Giải thích một quyết định bạn sẽ không dùng Redis hoặc không thêm index, kèm số đo.
  5. Nêu một known limitation còn chấp nhận và metric/runbook phát hiện khi assumption bị phá.
Ôn lại