Kafka replication: ISR, acks và min.insync.replicas bảo vệ dữ liệu ra sao Trung cấp
Thời gian đọc ước tính: 6 phút
Cần đọc trước
Vấn đề
Phần tiêu đề “Vấn đề”Producer nhận “thành công” cho OrderPaid, vài giây sau broker giữ leader chết và event biến mất. “Có ba broker nên dữ liệu đã nhân ba” không đủ: phải biết RF bao nhiêu, replica nào đang theo kịp, producer dùng acks gì, và cluster có cho ghi khi chỉ còn một replica đồng bộ hay không.
Durability là kết quả của producer config, topic/broker config và tình trạng cluster cùng lúc.
Công thức khuyến nghị
Phần tiêu đề “Công thức khuyến nghị”Cho topic quan trọng:
| Cài đặt | Giá trị | Mặc định của Kafka |
|---|---|---|
| Replication factor (RF) | 3 | default.replication.factor=1 |
min.insync.replicas |
2 | 1 |
acks (producer) |
all |
all ở producer 4.x |
unclean.leader.election.enable |
false |
false |
enable.idempotence |
true |
true ở 4.x (bài) |
Mặc định broker (RF=1, min ISR=1) không bền: topic tự tạo trên cluster mặc định chỉ có một bản. Nên tắt auto-create topic ở production và tạo topic với RF=3 tường minh.
Khái niệm
Phần tiêu đề “Khái niệm”- RF: số replica gán cho mỗi partition; một leader, còn lại là follower fetch từ leader. RF là mục tiêu, không phải cam kết cả ba đều có record mới.
- ISR: tập replica đang theo kịp leader. Follower không fetch kịp trong
replica.lag.time.max.ms(mặc định 30000 ms) bị loại khỏi ISR, và quay lại khi bắt kịp. acks=all: leader ack khi toàn bộ ISR hiện tại có record, với điều kiện kích thước ISR đạtmin.insync.replicas. Nó không đợi replica đã rời ISR.min.insync.replicas: ngưỡng ISR tối thiểu để chấp nhận writeacks=all; thấp hơn thì broker trảNOT_ENOUGH_REPLICAS.acks=1: chỉ leader ghi nhận; leader chết trước khi follower fetch thì mất dữ liệu đã báo thành công.acks=0: producer không biết broker nhận hay chưa.
ISR co lại từng bước
Phần tiêu đề “ISR co lại từng bước”OrderPaidRF=3, min.insync.replicas=2, ISR = 3 replica. Leader chờ cả ISR có record rồi mới ack: ghi thành công.
| RF | ISR | min ISR | acks=all |
|---|---|---|---|
| 3 | 3 | 2 | Nhận |
| 3 | 2 | 2 | Nhận (một replica ngoài ISR) |
| 3 | 1 | 2 | Từ chối: chọn bền hơn sẵn sàng ghi |
| 3 | 1 | 1 | Nhận, nhưng chỉ một bản: rủi ro cao |
Với min ISR=1, “all” không còn nghĩa là ba bản. minISR chỉ ràng buộc write acks=all; producer dùng acks=1 không được bảo vệ, nên audit cấu hình mọi client.
Leader chết và unclean election
Phần tiêu đề “Leader chết và unclean election”Khi leader chết, controller chọn leader mới trong ISR, nên không mất record đã committed. Nếu ISR rỗng:
| Cấu hình | Hành vi | Đánh đổi |
|---|---|---|
unclean.leader.election.enable=false (mặc định) |
Partition offline cho tới khi một replica ISR sống lại | Mất availability, giữ dữ liệu |
true |
Replica ngoài ISR lên leader | Có thể mất record đã ack |
Với dữ liệu tiền bạc, giữ false.
Lưu ý Kafka 4.1+: Eligible Leader Replicas (ELR, KIP-966) bật mặc định trên cluster mới.
- Khi ISR rỗng, controller có thể chọn leader từ ELR (replica rời ISR nhưng được bảo đảm có đủ dữ liệu tới high watermark) trước khi coi partition là offline.
- Docs ghi ngữ nghĩa của
min.insync.replicasthay đổi khi ELR bật.
Kiểm tra trạng thái ELR của cluster bạn trước khi suy luận theo bảng trên.
Record chỉ hiển thị cho consumer thường khi đã replicate tới toàn bộ ISR (committed, theo high watermark). Timeout ở producer không có nghĩa record chưa ghi: ack có thể mất trên đường về, nên dùng idempotent producer và event ID.
Khi nào đánh đổi
Phần tiêu đề “Khi nào đánh đổi”| Mục tiêu | Cấu hình |
|---|---|
| Không được mất (billing, ledger) | RF=3, minISR=2, acks=all, unclean=false |
| Chịu mất ít để ghi nhanh (metric, log) | RF=3, acks=1 hoặc minISR=1 |
| Cluster 2 broker | minISR=2 với RF=2 làm mất khả năng ghi khi một broker bảo trì; cân nhắc 3 broker |
Chi phí của acks=all: chờ follower, nên latency ack phụ thuộc replica chậm nhất trong ISR. Hãy đo trên cluster của bạn trước khi cam kết SLA; bài này không đưa con số latency vì chúng phụ thuộc phần cứng và mạng.
Ví dụ thực tế
Phần tiêu đề “Ví dụ thực tế”Mô hình điều kiện cấu hình (không mô phỏng fetch, election hay timeout; compose repo chỉ có một broker):
npx --prefix examples ts-node examples/src/kafka-replication/ack-policy-demo.tsOutput RF=3, minISR=2: eligible ở ISR=3, eligible ở ISR=2, reject ở ISR=1 với acks=-1; dòng acks=1, ISR=1 là eligible. Test thật cần ít nhất ba broker và ngắt từng broker.
Trade-offs
Phần tiêu đề “Trade-offs”Tăng an toàn dữ liệu
- RF cho phép partition sống sót khi broker lỗi.
acks=allcộng minISR chặn ack với quá ít bản đồng bộ.- ISR cho tín hiệu sức khoẻ cụ thể hơn số broker.
Đánh đổi
- minISR cao làm write bị từ chối sớm khi cluster suy giảm.
- Thêm disk, network và latency ack.
- Producer vẫn phải xử lý timeout, retry và duplicate.
Checklist production
Phần tiêu đề “Checklist production”- RF=3,
min.insync.replicas=2cho mọi topic quan trọng; tắt auto-create topic. - Producer
acks=all, idempotence bật; audit mọi client để không cóacks=1lọt vào. unclean.leader.election.enable=false.- Rải replica qua rack/AZ khác nhau.
- Alert: under-replicated partitions, ISR size, produce error rate theo partition.
- Chuẩn bị xử lý
NOT_ENOUGH_REPLICASở producer: retry có backoff và deadline, báo upstream khi không ghi được.
Sai lầm thường gặp
Phần tiêu đề “Sai lầm thường gặp”Tóm tắt
Phần tiêu đề “Tóm tắt”Tự kiểm tra: (1) RF=3, ISR=1, minISR=1 thì acks=all có bị từ chối không? (2) Vì sao minISR=2 không cứu producer acks=1? (3) Produce timeout có chứng minh record chưa ghi không?