Kafka Producer
Last updated
Last updated
Kafka Producer là thành phần chịu trách nhiệm gửi dữ liệu (message) vào Kafka topic. Producer có thể gửi dữ liệu có hoặc không có key, và Kafka sẽ phân vùng (partitioning) dữ liệu dựa trên key hoặc một cơ chế mặc định.
Partitioning là quá trình xác định xem record sẽ được đưa vào partition nào trong topic. Xét 3 trường hợp như sau:
Nếu ta chỉ định rõ số hiệu Partition trong Record thì Record sẽ được gửi vào Partition đó.
Ví dụ code Java
Dùng murmur2(key) % num_partitions
để xác định partition.
Trước Kafka 2.4: Dùng Round Robin, mỗi message sẽ được gửi đến partition kế tiếp theo thứ tự.
Từ Kafka 2.4+: Dùng Sticky Partitioner, giúp tối ưu hiệu suất bằng cách giữ nguyên partition trong một khoảng thời gian ngắn trước khi chuyển sang partition khác. Trước khi tìm hiểu rõ hơn về Sticky Partitioner ta cần tìm hiểu khái niệm về Batch.
Cụ thể trong Kafka, batch liên quan đến cách producer gửi dữ liệu đến các partition của topic:
Khi producer tạo ra các bản ghi, thay vì gửi từng bản ghi ngay lập tức qua mạng đến Kafka broker, nó có thể gom các bản ghi này thành một batch.
Batch này sẽ được gửi đi khi:
Kích thước batch đạt đến ngưỡng tối đa (được cấu hình qua batch.size
, đơn vị là byte).
Hoặc thời gian chờ tối đa đã hết (được cấu hình qua linger.ms
, đơn vị là mili giây), ngay cả khi batch chưa đầy.
Lợi ích của batch
Tăng thông lượng (throughput): Gửi nhiều bản ghi cùng lúc trong một batch giảm số lượng yêu cầu mạng, từ đó tăng hiệu suất.
Giảm độ trễ mạng: Thay vì gửi từng bản ghi nhỏ lẻ (có thể gây tắc nghẽn hoặc tăng thời gian xử lý), batch cho phép xử lý dữ liệu theo khối lớn hơn.
Tối ưu tài nguyên: Giảm tải cho cả producer, broker và mạng bằng cách xử lý dữ liệu tập trung.
Ví dụ minh họa
Giả sử bạn cấu hình:
batch.size = 16384 (16KB)
Producer tạo ra các bản ghi:
Bản ghi 1 (1KB), Bản ghi 2 (2KB), Bản ghi 3 (3KB).
Nếu tổng kích thước chưa vượt 16KB và chưa hết 5ms, producer sẽ tiếp tục gom thêm bản ghi vào batch.
Khi batch đầy (16KB) hoặc hết 5ms, toàn bộ batch sẽ được gửi đến Kafka broker.
Lợi ích của Sticky Partitioner
Tăng hiệu suất: Bằng cách gom các bản ghi vào cùng một partition trong một lô, nó giảm số lượng yêu cầu mạng và tối ưu hóa việc sử dụng tài nguyên.
Giảm độ trễ: Các bản ghi được gửi theo lô lớn hơn thay vì từng bản ghi nhỏ lẻ, cải thiện thông lượng (throughput).
Phân phối vẫn công bằng: Mặc dù "dính" vào một partition trong ngắn hạn, nó vẫn đảm bảo phân phối ngẫu nhiên giữa các partition trong dài hạn.
Tham số acks (acknowledgments) quyết định mức độ xác nhận mà Producer yêu cầu từ Kafka Broker trước khi coi một bản ghi là "đã gửi thành công". Có 3 giá trị chính:
acks=0 (Không cần xác nhận)
Producer gửi bản ghi và không chờ phản hồi từ Broker.
Ưu điểm: Tốc độ cao nhất, độ trễ thấp.
Nhược điểm: Không đảm bảo độ tin cậy. Nếu Broker không nhận được bản ghi (do lỗi mạng, Broker sập, v.v.), Producer sẽ không biết và bản ghi có thể bị mất.
acks=1 (Chỉ cần Leader xác nhận):
Producer chờ Leader của partition xác nhận rằng bản ghi đã được ghi vào log của Leader.
Ưu điểm: Cân bằng giữa tốc độ và độ tin cậy.
Nhược điểm: Nếu Leader sập ngay sau khi xác nhận mà bản ghi chưa được sao chép sang các Follower (replica), bản ghi có thể bị mất.
acks=all (Tất cả replica xác nhận)
Producer chờ Leader ghi bản ghi vào log và tất cả các Follower trong ISR (In-Sync Replicas) sao chép thành công bản ghi.
Ưu điểm: Độ tin cậy cao nhất, đảm bảo không mất dữ liệu trừ khi toàn bộ cluster sập.
Nhược điểm: Độ trễ cao hơn do phải chờ nhiều xác nhận.
Producer có thể được cấu hình để tự động thử lại khi gửi bản ghi thất bại thông qua các tham số:
retries: Số lần Producer sẽ thử lại nếu gửi bản ghi không thành công (mặc định là 0).
Cách hoạt động:
Nếu một lỗi tạm thời xảy ra (ví dụ: mạng gián đoạn, Broker tạm không phản hồi), Producer sẽ thử gửi lại bản ghi.
Chỉ áp dụng cho các lỗi có thể phục hồi (retriable errors), như lỗi mạng, chứ không áp dụng cho lỗi vĩnh viễn (ví dụ: bản ghi quá lớn vượt max.message.bytes).
Lưu ý:
Nếu không cấu hình retries, Producer sẽ thất bại ngay khi gặp lỗi và bản ghi có thể bị mất.
Khi kết hợp acks=all và retries > 0, độ tin cậy được tăng lên đáng kể.
Cách hoạt động:
Nếu một lỗi tạm thời xảy ra (ví dụ: mạng gián đoạn, Broker tạm không phản hồi), Producer sẽ thử gửi lại bản ghi.
💡Có trường hợp nào cùng key nhưng lại nằm ở 2 partition khác nhau không?
Câu trả lời là có. Ở một số trường hợp như sau:
Ta chỉ định thẳng định danh partition của 2 record có cùng key vào 2 partition khác nhau.
Khi số Partition tăng lên. Trường hợp này tuy cùng key nhưng có thể murmur2(key) % num_partitions
cho ra 2 giá trị khác nhau do num_partitions
đã thay đổi.
= 5 (5 mili giây)
Thay vì phân phối bản ghi ngay lập tức qua các partition khác nhau, Sticky Partitioner chọn một partition ngẫu nhiên và gửi tất cả các bản ghi vào partition đó cho đến khi lô (batch) hiện tại đầy hoặc hết thời gian chờ ().
Khi lô hoàn tất hoặc một điều kiện nhất định được đáp ứng (ví dụ: hết thời gian ), Sticky Partitioner chọn một partition ngẫu nhiên mới và tiếp tục "dính" vào partition đó cho lô tiếp theo.
Tham khảo thêm tại:
: Thời gian chờ giữa các lần thử lại (mặc định là 100ms).