Họ đang đo gì
Bạn có hiểu tính nhất quán là thứ chọn theo từng đường đọc, chứ không phải một công tắc toàn hệ thống.
Trả lời ngắn~30 giây
Đây là replication lag phá vỡ read-your-writes. Bốn cách xử lý, từ thô tới tinh: đọc primary cho mọi thứ (mất lợi ích replica); ghim người vừa ghi vào primary trong vài giây (đơn giản, hiệu quả, mình hay dùng cách này); truyền LSN/GTID của lần ghi rồi chờ replica bắt kịp mới đọc (chính xác nhất, phức tạp nhất); hoặc chấp nhận lag nhưng dựng giao diện từ dữ liệu vừa ghi thay vì tải lại từ server.
Người dùng lưu hồ sơ. Primary commit và trả về thành công ngay.
Giải thích sâu
Điểm quan trọng là bạn KHÔNG cần tính nhất quán mạnh cho mọi đường đọc. Bảng xếp hạng trễ 3 giây thì không ai chết; hồ sơ vừa sửa mà hiện dữ liệu cũ thì người dùng bấm lưu lần nữa và bạn có bug đúp. Nên câu trả lời tốt là phân loại đường đọc: loại nào cần thấy ngay việc mình vừa làm, loại nào không.
Cách ghim theo phiên hoạt động vì lag thực tế thường dưới một giây, còn hành vi “ghi rồi đọc lại ngay” chỉ kéo dài vài giây. Đặt cookie hoặc khoá Redis w:{user} với TTL 5 giây, trong khoảng đó mọi truy vấn của người này đi vào primary. Chi phí là một phần rất nhỏ lưu lượng đọc quay về primary, đổi lấy việc bug biến mất hoàn toàn.
Cách chờ LSN là thứ đáng nói ở vòng senior: sau khi ghi, lấy pg_current_wal_lsn(), gửi kèm cho tầng đọc, và trước khi đọc thì so với pg_last_wal_replay_lsn() của replica; chưa tới thì hoặc chờ ngắn hoặc rơi về primary. Nó cho đúng ngữ nghĩa cần thiết mà không hy sinh toàn bộ lưu lượng đọc — nhưng phải xử lý cả trường hợp replica không bao giờ bắt kịp vì đang bị treo.
Điều cuối cùng cần nói ra: lag không phải hằng số. Nó nhảy vọt khi có backfill lớn, khi VACUUM chạy nặng, hoặc khi replica bị nghẽn I/O. Nếu hệ thống của bạn ngầm giả định “lag luôn dưới 100ms” thì nó sẽ hỏng đúng vào ngày bận nhất. Đo và cảnh báo trên lag là phần bắt buộc của câu trả lời, không phải phần thêm.
Câu hỏi tiếp theo họ sẽ hỏi
?Replication đồng bộ có giải quyết triệt để không?
Có, nhưng bạn trả bằng độ trễ ghi — mỗi commit phải chờ ít nhất một replica xác nhận — và bằng tính sẵn sàng: replica chết thì ghi đứng lại, trừ khi bạn cấu hình synchronous_standby_names với số lượng đủ. Đây chính là chữ “Else” trong PACELC.
?Đo lag bằng byte hay bằng giây?
Cả hai, vì chúng nói hai chuyện khác nhau. Byte (pg_wal_lsn_diff) cho biết còn bao nhiêu phải replay; giây (replay_lag) cho biết người dùng đang thấy dữ liệu cũ bao lâu. Hệ thống ít ghi có thể lag 0 byte mà replay_lag vẫn nhảy do không có gì để replay.
Trả lời thế này là mất điểm
- “Cho tất cả đọc từ primary” và coi như xong. Vậy thì replica của bạn chỉ còn là bản dự phòng đắt tiền.
- Coi lag là hằng số nhỏ. Nó là phân phối có đuôi dài, và cái đuôi mới là thứ gây sự cố.
Nguồn
- PostgreSQL — Hot Standby: xung đột replay và `pg_last_wal_replay_lsn()`
- PostgreSQL — Synchronous Replication (`synchronous_commit`, `synchronous_standby_names`)
- Daniel Abadi — PACELC: kể cả khi không có phân mảnh mạng, vẫn phải chọn giữa độ trễ và tính nhất quán