Xin chào, lại là mình - Đức Phúc, anh chàng hơn 6 năm trong nghề vẫn nghèo technical nhưng thích viết Blog để chia sẻ kiến thức bản thân học được trong quá trình “cơm áo gạo tiền” đây. Các bạn có thể theo dõi mình thêm qua một số nền tảng bên dưới nhé:
- Linkedin: https://www.linkedin.com/in/phuc-ngo-728433346
- Viblo: https://viblo.asia/u/NHDPhucIT
- Patreon: https://www.patreon.com/felix_ngo
- Facebook: https://www.facebook.com/DucPhucIT
Như đã đề cập ở bài viết trước, hôm nay, chúng ta sẽ tìm hiểu chi tiết về:
- Producers
- Message Keys
Với nội dung này, bạn sẽ hiểu hơn về cách mà Producer gửi message đến Topic và kiến trúc của những Message đó như thế nào. Bắt đầu thôi
1. Producers
Chúng ta đã biết rằng Topic là nơi chứa dữ liệu. Nhưng để có dữ liệu trong topic, chúng ta cần một
Kafka Producer. Producer có nhiệm vụ ghi dữ liệu vào topic, partition
Trước khi gửi dữ liệu, Producer sẽ xác định trước:
- Partition nào mà nó sẽ ghi dữ liệu vào.
- Kafka Broker đang nắm giữ partition đó.
Chúng ta sẽ tìm hiểu về Kafka Broker sớm thôi. Nhưng có 2 lưu ý cực kỳ quan trọng mà chúng ta phải “khắc cốt ghi tâm”:
- Producer quyết định trước partition nào sẽ nhận dữ liệu, không phải Kafka server.
- Trong trường hợp Kafka server chứa partition bị lỗi, Producer sẽ biết cách tự động khôi phục.
Kafka hỗ trợ cân bằng tải (load balancing) vì dữ liệu có thể được gửi đến nhiều partition trong một topic. Mỗi partition có thể nhận dữ liệu từ một hoặc nhiều producer khác nhau.
2. Message Key trong Kafka Producer
Như vậy, Producers bây giờ sẽ có message key cho mỗi message. Mỗi message gửi từ Producer có thể có một Key (không bắt buộc). Key có thể là bất cứ thứ gì chúng ta muốn: String, Number, Binary, v.v.
Vì key
là không bắt buộc, nên ta sẽ có 2 trường hợp:
- Nếu
key = null
, dữ liệu sẽ được gửi ngẫu nhiên theo vòng tròn (round-robin) giữa các partition. - Nếu
key ≠ null
, tất cả các tin nhắn có cùng key sẽ được ghi vào cùng một partition, nhờ vào thuật toán băm (hashing strategy).
Ví dụ, khi đề cập đến bài toán vận chuyển ở bài trước, ta có thể sử dụng packageId
(ID của gói hàng) hoặc truckId
(ID của xe vận chuyển) như 1 key cho mỗi message. Từ đó, ta luôn đảm bảo dữ liệu của mỗi gói hàng hay mỗi xe sẽ được gửi đến cùng 1 Partition xuyên suốt quá trình vận chuyển
3. Cấu trúc một Kafka Message
Cấu trúc của một Kafka Message có thể được biểu diễn như dưới đây
- Như vậy, chúng ta có
key
và nó có thể là null như chúng ta đã đề cập trước đó và nó ở định dạng nhị phân (Binary). - Sau đó, chúng ta có
value
, là nội dung tin nhắn. Nó cũng có thể lànull
, nhưng thường thì chúng ta ít khi phải gửi giá trị này vào Kafka, - Tiếp theo, chúng ta có thể thêm nén tin nhắn của mình để giúp cho dữ liệu chiếm ít bộ nhớ hơn trước khi gửi vào Partition. Chúng ta có thể chỉ định một cơ chế nén nếu muốn, ví dụ: gzip, snappy, lz4 hoặc zstd.
- Tiếp đến, chúng ta cũng có thể thêm
headers
vào tin nhắn của mình, đây là danh sách tùy chọn các cặpkey
vàvalue
riêng biệt. Đừng nhầm lẫn phần này vớikey
vàvalue
của Message nhé - Một phần cực kỳ quan trọng tiếp theo là Partition và Offset mà message sẽ được gửi đến.
- Và cuối cùng là
timestamp
. Giá trị này có thể do hệ thống hoặc người dùng đặt.
Tất cả những thành phần trên kết hợp thành một Kafka Message để rồi nó được gửi vào Apache Kafka và lưu trữ.
4. Cách mà Message được tạo ở Producer
Chúng ta đã biết những thành phần của Message, vậy cách mà nó được tạo ra như thế nào?
Trước hết, phải nhắc lại rằng, Kafka là một công nghệ rất tốt. Và thêm một lý do khiến nó tốt nữa, là nó chỉ chấp nhận đầu vào là 1 chuỗi byte
từ Producer. Tương tự, nó cũng gửi dữ liệu đầu ra dưới dạng 1 chuỗi byte
như vậy
Tuy nhiên, khi chúng ta xây dựng Message, chúng không phải là byte mà là những kiểu dữ liệu khác. Vì vậy, Kafka cần có 1 công cụ để chuyển đổi những dữ liệu đó sang byte
, và nó được gọi là Kafka Message Serializer.
Một điều quan trọng mà bạn phải cực kỳ lưu ý là:
Kafka Message Serializer chỉ thực hiện chuyển đổi trên 2 thành phần đầu tiên của 1 Message là
key
vàvalue
của nó. Những thành phần khác sẽ không được chuyển đổi
Dưới đây là 1 ví dụ minh hoạ:
Ta có thể thấy, ban đầu, key
mang giá trị là 1202
, thuộc kiểu INT
và value
mang giá trị là Phuc
, thuộc kiểu String
. Producer lúc này sẽ tiến hành lựa chọn instance phù hợp cho 2 kiểu dữ liệu này để chuyển hoá nó thành byte
. Cuối cùng, chúng ta có 2 chuỗi dạng byte
chỉ bao gồm các giá trị 0
và 1
được gửi đến Partition
5. Kafka Partitioner
Kafka Partitioner là một logic nhận đầu vào là một bản ghi, một Message và xác định Partition nào để gửi đến.
Do đó, khi chúng ta thực hiện gửi, logic tại Producer Partitioner sẽ xem xét bản ghi và sau đó gán nó cho một Partition,
Và quá trình key hashing được sử dụng để xác định ánh xạ của key
vào một Partition, và Partition mặc định, sau đó các khóa sẽ được băm (hashed) bằng thuật toán murmur2
Một lần nữa, đừng quên connect với mình để cùng trao đổi nhé
- Linkedin: https://www.linkedin.com/in/phuc-ngo-728433346
- Viblo: https://viblo.asia/u/NHDPhucIT
- Patreon: https://www.patreon.com/felix_ngo
- Facebook: https://www.facebook.com/DucPhucIT