Kafka Fundamental - Bài 3: Producers & Message Keys

0 0 0

Người đăng: Đức Phúc

Theo Viblo Asia

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é:

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 đó. image.png

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.

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 image.png

  • 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ặp keyvalue riêng biệt. Đừng nhầm lẫn phần này với keyvalue 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à keyvalue 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ạ: image.png

Ta có thể thấy, ban đầu, key mang giá trị là 1202, thuộc kiểu INTvalue 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ị 01 đượ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

image.png

Một lần nữa, đừng quên connect với mình để cùng trao đổi nhé

Bình luận

Bài viết tương tự

- vừa được xem lúc

001: Message-driven programming với Message broker và Apache Kafka

Bài viết nằm trong series Apache Kafka từ zero đến one. . . Asynchronous programming.

0 0 168

- vừa được xem lúc

002: Apache Kafka topic, partition, offset và broker

Bài viết nằm trong series Apache Kafka từ zero đến one. Nói qua về lịch sử, Kafka được phát triển bởi LinkedIn (các anh em dev chắc chẳng xa lạ gì) và viết bằng ngôn ngữ JVM, cụ thể là Java và Scala.

0 0 158

- vừa được xem lúc

003: Gửi và nhận message trong Apache Kafka

Bài viết nằm trong series Apache Kafka từ zero đến one. . . Nếu muốn các message được lưu trên cùng một partition để đảm bảo thứ tự thì làm cách nào.

0 0 226

- vừa được xem lúc

004: Apache Kafka consumer offset, Broker discovery và Zookeeper

Bài viết nằm trong series Apache Kafka từ zero đến one. 1) Consumer offset.

0 0 133

- vừa được xem lúc

Change account

Tài khoản cũ của mình có chút vấn đề nên mình chuyển sang dùng tài khoản mới để viết bài. Xin cảm ơn mọi người.

0 0 33

- vừa được xem lúc

[MSDP] - Event Carried State Transfer

Trong hướng dẫn này, chúng ta cùng tìm hiểu về Microservice Desin Pattern - Event Carried State Transfer (chuyển trạng thái theo sự kiện) để đạt được sự nhất quán về dữ liệu giữa các microservice. Tro

0 0 35