Loạt bài này mình sẽ nói về Kafka và chưa rõ nó sẽ gồm bao nhiêu phần cả . Ở bài này mình sẽ tổng hợp một số điều cần lưu ý ở Kafka architecture, đủ để có thể sử dụng được Kafka. Các phần sau sẽ đi sâu hơn nữa và thực hành một số kỹ thuật ở Kafka.
Apache Kafka is a publish/subscribe messaging system designed to solve this problem. It is often described as a “distributed commit log” or more recently as a “distributing streaming platform.”
Kafka là một nền tảng phân phối message(log) phân tán, phát triển theo model pub/sub. Producer được dùng để đẩy data vào Kafka, còn consumer được dùng để đọc data từ Kafka.
Kiểu dữ liệu trong Kafka được gọi chung là message. Các message này được lưu trữ tuần tự trong các topic. Mỗi message sẽ được đánh số thự tự gọi là offset. Có thể phân chia lưu trữ message trong topic ở nhiều partition, điều này cho phép scale horizontally topic ở Kafka dễ dàng giúp tăng tốc độ xử lý của hệ thống.
Khi chia topic thành nhiều partition thì thứ tự message chỉ được đảm bảo ở từng partition. Cho nên với các hệ thống cần xử lý đúng tuần tự message ở một topic thì không nên chia thành nhiều partition.
Message ở Kafka sẽ được lưu trữ ở file và sẽ không bị xóa, nên khi Kafka bị khởi động lại thì message vẫn sẽ được giữ nguyên.
Producers được dùng để đẩy message vào Kafka. Có 3 phương thức để đẩy message:
Khi deploy Kafka có nhiều bản replicas cần lưu ý thêm tham số acks:
Với topic được chia thành nhiều partition, mặc định producer sẽ ghi message lần lượt chia đều vào các partition theo cơ chế round-robin. Cũng có thể chỉ định message sẽ được ghi vào partition cụ thể.
Consumer được dùng để lấy message từ Kafka, một consumer có thể lấy message từ nhiều topic. Có thể nhóm các consumer thành một group để tăng tốc độ đọc message từ các partition của topic.
Có hai kiểu để phân chia các partition cho consumer:
Range: Gán cho consumer các partition liên tiếp. Ví dụ: có 2 topic T1, T2, mỗi topic có 3 partition và 1 consumer group gồm C1, C2. Thì C1 sẽ được gán partition P0, P1 của T1 và T2 còn C2 sẽ được gán P2 của T1 và T2. C1 được gán nhiều partition hơn do số lượng parition đang không chia hết cho tổng số consumer.
RoundRobin: Gán tuần tự partition cho consumer tuần tự, từng cái một. Ví dụ: có 2 topic T1, T2, mỗi topic có 3 partition và 1 consumer group gồm C1, C2. Thì C1 sẽ được gán parition P0 vs P2 của T1 và T2 còn C2 sẽ được gán P1 của T1 và T2.
Consumer không thể push message như RabbitMQ nên Kafka không được dùng cho service integration.
Khi consumer pull message từ topic, cần đánh dấu đã nhận message để Kafka có thể quản lí được message nào đã được đọc bởi consumer. Có 3 cách để làm điều này:
commitSync
sẽ đánh dầu offset mới nhất nhận
được khi pull message và sẽ đợi Kafka phản hồi thành công thì mới thực hiện message tiếp theo.Ngoài ra do pull message có thể trả về nhiều message cùng một lúc, nên có thể commit
một offset cụ thể bằng cách truyền thêm param vào hàm commit: commitAsync(currentOffsets, null)