1. Giới Thiệu Tổng Quan Về Tính Tin Cậy Trong Kafka
Tính tin cậy của hệ thống Kafka không chỉ phụ thuộc vào cách cấu hình các broker mà còn chịu ảnh hưởng mạnh mẽ bởi cách cấu hình và xử lý của producer. Nếu không được thiết lập đúng cách, cả hệ thống có thể đối mặt với nguy cơ mất dữ liệu, ngay cả khi các broker được cấu hình ở mức tối ưu nhất.
Ví Dụ Minh Họa Về Mất Dữ Liệu
Dưới đây là hai kịch bản điển hình mà qua đó chúng ta có thể thấy rõ tầm quan trọng của việc cấu hình producer:
-
Trong kịch bản đầu tiên, chúng ta đã cấu hình các broker với ba bản sao (replicas) và đã vô hiệu hóa việc chọn leader không đồng bộ. Mặc dù không có message nào bị mất khi đã được cam kết, nhưng nếu producer cấu hình với giá trị
acks=1
, một thông điệp có thể mất khi leader gặp sự cố trước khi các bản sao khác kịp sao chép. Điều này có nghĩa là producer nghĩ rằng message đã được ghi thành công, nhưng thực tế không phải như vậy. -
Kịch bản thứ hai là khi producer gửi message với giá trị
acks=all
. Nếu leader của partition gặp sự cố trong quá trình ghi, và producer không xử lý lỗi, thì message sẽ bị mất. Vấn đề này không nằm ở broker mà ở cách mà producer quản lý các lỗi xảy ra.
Từ đó, chúng ta có thể rút ra hai bài học quan trọng cho các nhà phát triển khi làm việc với Kafka:
- Cấu hình acks một cách hợp lý để bảo đảm độ tin cậy.
- Xử lý lỗi một cách thận trọng trong cả cấu hình và mã nguồn (code).
2. Các Cấu Hình Xác Nhận Gửi (Send Acknowledgments)
acks=0
Với cấu hình này, message chỉ được coi là ghi thành công khi producer đã gửi nó qua mạng. Trong trường hợp có lỗi mạng hay không thể tuần tự hóa, chúng ta sẽ nhận thông báo lỗi, nhưng nếu partition đang offline hoặc có sự cố, producer không nhận được lỗi. Cấu hình này mang lại độ trễ gửi thấp nhưng không cải thiện độ trễ đầu cuối.
acks=1
Ở mức độ này, khi leader nhận message thành công và ghi vào partition data file (nhưng chưa chắc đã ghi lên đĩa), chúng ta có thể mất dữ liệu nếu leader gặp sự cố trước khi sao chép các thông điệp tới các bản sao khác. Việc này đồng nghĩa với việc message có thể được ghi vào leader nhưng không được sao chép.
acks=all
Khi sử dụng cấu hình này, leader sẽ chờ cho tất cả các bản sao đồng bộ nhận message trước khi xác nhận việc ghi. Đây là tùy chọn an toàn nhất, bảo đảm rằng message chỉ được xác nhận khi đã được cam kết bởi tất cả các bản sao đồng bộ. Tuy nhiên, mức độ trễ của producer sẽ cao hơn vì phải chờ cho tất cả các bản sao tương thích.
3. Cấu Hình Thử Lại Producer
Xử lý lỗi trong producer có thể chia thành hai phần: lỗi mà producer có thể tự động xử lý và lỗi mà các nhà phát triển cần tự quản lý. Producer có khả năng xử lý các lỗi có thể thử lại (retriable errors). Khi gửi message đến broker, lỗi có thể thuộc về loại có thể giải quyết hoặc không. Ví dụ, nếu broker trả về mã lỗi LEADER_NOT_AVAILABLE
, producer có thể thử gửi lại message, trong khi lỗi INVALID_CONFIG
là lỗi không thể thử lại.
Để đảm bảo không mất message, hãy cấu hình producer để tiếp tục gửi lại khi gặp lỗi. Số lần thử lại nên để mặc định (MAX_INT) và sử dụng delivery.timeout.ms
để xác định thời gian chờ tối đa cho việc gửi message.
Việc thử lại có thể gây ra tình huống trùng lặp message. Với cấu hình enable.idempotence=true
, producer sẽ thêm thông tin bổ sung vào các bản ghi, cho phép broker bỏ qua các message trùng lặp do các lần thử lại.
4. Xử Lý Lỗi Bổ Sung
Mặc dù việc sử dụng tính năng thử lại của producer là cách dễ dàng để quản lý lỗi, nhưng các nhà phát triển cũng cần chú ý đến những lỗi khác:
- Lỗi broker không thể thử lại như lỗi kích thước message hoặc lỗi ủy quyền.
- Lỗi xảy ra trước khi message được gửi như lỗi tuần tự hóa.
- Lỗi khi producer đã sử dụng hết tất cả các lần thử lại hoặc bộ nhớ đầy do lưu trữ message.
- Thời gian chờ (Timeouts).
5. Kết Nối và Trao Đổi Thông Tin
Nếu bạn muốn cùng thảo luận sâu hơn về bài viết này, hãy kết nối với mình qua LinkedIn và Facebook:
- LinkedIn: nguyentrungnam
- Facebook: trungnam.nguyen
Rất mong được kết nối và trao đổi thêm!
source: viblo