Ở bài trước, ta dùng replication factor để replicate các partition và lưu trữ trên các kafka broker. Kafka sẽ có 1 và chỉ 1 replication partition là leader, chính vì thế việc read/write message sẽ đều thông qua partition này.
Trong trường hợp Broker 101 gặp sự cố, replication leader của partition 1 không còn hoạt động. Lúc này, một trong các ISR còn lại sẽ trở thành Leader và partition trở lại hoạt động bình thường.
Một câu hỏi khác được đặt ra - Ai là người quyết định replication nào trở thành Leader hay ISR? Đó là nhiệm vụ của ZooKeeper.
Producer là người gửi message đến Message broker. Cụ thể với Kafka, producer write data vào partition của topic.
Producer tự động biết nên write vào broker nào và partition nào. Trong trường hợp đang write data mà broker gặp sự cố, producer sẽ có cơ chế tự động retry cho đến khi thành công.
Trong trường hợp gửi message đến topic mà không chỉ định partition, producer sẽ gửi message đến broker theo cơ chế round-robin.
Tiếp tục đến bài toán khác, làm thế nào producer biết message đã được write thành công ở partition? Chẳng cách nào khác ngoài cơ chế ack - acknowledgment.
Producer có thể lựa chọn nhận ack từ Kafka để chắc chắn rằng message được gửi thành công:
Dễ dàng nhận thấy cái giá phải trả cho việc đảm bảo không mất message là performance.
Làm thế nào để điều hướng message đến chính xác partition mình mong muốn để đảm bảo message ordering? Có 3 cách để thực hiện việc này:
Nếu muốn các message liên quan với nhau được gửi vào cùng partition và order theo thứ tự, cần define key cho mỗi message.
Kafka sử dụng các thuật toán hashing và rounting để điều phối message có cùng key đến cùng partition. Chúng ta hoàn toàn có khả năng điều phối message đến chính xác partition mong muốn bằng cách đọc code Kafka, tuy nhiên nó chẳng giúp giải quyết vấn đề gì.
Consumer là đầu nhận message.
Quay lại phần trước, consumer là nơi đọc message từ topic. Có nghĩa là một consumer có thể đọc toàn bộ message của tất cả partition thuộc cùng topic.
Nếu số lượng producer tăng lên và đồng thời gửi message đến tất cả partition trong khi chỉ có duy nhất một consumer thì khả năng xử lý sẽ rất chậm, có thể dẫn tới bottle-neck. Giải pháp là tăng số lượng consumer, các consumer có thể xử lý đồng thời message từ nhiều partition. Và tất cả các consumer sẽ thuộc cùng một nhóm được gọi là consumer group.
Như vậy, consumer group read toàn bộ data của các partition và chia vào các consumer bên trong để xử lý.
Mỗi consumer thuộc consumer group sẽ đọc toàn bộ data của một hoặc nhiều partition để đảm bảo message ordering. Không tồn tại nhiều consumer cùng đọc message từ một partition.
Một consumer có thể nhận message từ nhiều partition. Nhưng một partition không thể gửi message cho nhiều consumer trong cùng consumer group.
Nếu số lượng consumer trong consumer group lớn hơn số lượng partition thì những consumer dư thừa có trạng thái inactive - không nhận bất kì message nào từ topic.
Một vài trường hợp số lượng consumer trong group sẽ lớn hơn số lượng partition.
Trong trường hợp một active consumer gặp vấn đề và không thể tiếp tục hoạt động, một trong những inactive consumer còn lại được đẩy lên thay thế và tiếp tục công việc ngay lập tức.
Nếu không có inactive consumer nào, message sẽ được route tới một active consumer bất kì khác.
Quá trình re-assign này được gọi là partition rebalance
Chia thành càng nhiều partition và càng nhiều consumer thì số lượng message được xử lý đồng thời càng nhiều, phần nào cải thiện performance của hệ thống.
- Từ 1 partition/1 consumer thành 5 partition/5 consumer khả năng sẽ đem lại performance tốt.
- Nhưng lên 1000 partition/1000 consumer thì chưa chắc.