Chìa khóa có cần thiết khi gửi tin nhắn đến Kafka không?


93
KeyedMessage<String, byte[]> keyedMessage = new KeyedMessage<String, byte[]>(request.getRequestTopicName(), SerializationUtils.serialize(message)); 
producer.send(keyedMessage);

Hiện tại, tôi đang gửi tin nhắn mà không có bất kỳ khóa nào như một phần của các tin nhắn có khóa, nó vẫn hoạt động với delete.retention.ms? Tôi có cần gửi khóa như một phần của tin nhắn không? Điều này có tốt để tạo chìa khóa như một phần của thông điệp?

Câu trả lời:


172

Các phím chủ yếu hữu ích / cần thiết nếu bạn yêu cầu thứ tự mạnh mẽ cho một khóa và đang phát triển một thứ gì đó giống như một cỗ máy trạng thái. Nếu bạn yêu cầu các thư có cùng khóa (ví dụ: một id duy nhất) luôn được hiển thị theo đúng thứ tự, thì việc đính kèm khóa vào các thư sẽ đảm bảo các thư có cùng khóa luôn đi đến cùng một phân vùng trong một chủ đề. Kafka đảm bảo thứ tự trong một phân vùng, nhưng không đảm bảo thứ tự trên các phân vùng trong một chủ đề, do đó, việc không cung cấp khóa - điều này sẽ dẫn đến việc phân phối luân phiên trên các phân vùng - sẽ không duy trì thứ tự như vậy.

Trong trường hợp máy trạng thái, các khóa có thể được sử dụng với log.cleaner.enable để loại bỏ các mục nhập trùng lặp với cùng một khóa. Trong trường hợp đó, Kafka giả định rằng ứng dụng của bạn chỉ quan tâm đến phiên bản mới nhất của một khóa nhất định và trình dọn dẹp nhật ký chỉ xóa các bản sao cũ hơn của một khóa nhất định nếu khóa đó không rỗng. Hình thức nén nhật ký này được điều khiển bởi thuộc tính log.cleaner.delete.retention và yêu cầu khóa.

Ngoài ra, thuộc tính phổ biến hơn log.retention.hours , được bật theo mặc định, hoạt động bằng cách xóa các phân đoạn hoàn chỉnh của nhật ký đã lỗi thời. Trong trường hợp này, bạn không cần phải cung cấp chìa khóa. Kafka sẽ chỉ xóa các phần nhật ký cũ hơn khoảng thời gian lưu giữ nhất định.

Đó là tất cả để nói, nếu bạn đã bật tính năng nén nhật ký hoặc yêu cầu thứ tự nghiêm ngặt cho các thư có cùng khóa thì bạn chắc chắn nên sử dụng khóa. Nếu không, các khóa rỗng có thể cung cấp khả năng phân phối tốt hơn và ngăn chặn các vấn đề phát hiện điểm nóng tiềm ẩn trong trường hợp một số khóa có thể xuất hiện nhiều hơn những khóa khác.


Tôi mới làm quen với Kafka, đó là lý do khiến tôi đặt ra rất nhiều câu hỏi: Có một vài câu hỏi về điều này: Câu hỏi đầu tiên, Chúng ta có thể sử dụng tin nhắn trên cơ sở quan trọng không, Hiện tại, tôi đang sử dụng tin nhắn từ MessagAndMetadata mm. hoặc bỏ qua phím tại thời điểm gửi tin nhắn cũng được. Tôi đang sử dụng Api Người tiêu dùng Cấp cao.
gaurav

1
@kuujo Tôi giả sử việc khử trùng lặp này chỉ dành cho các mục nhật ký, nó không nhất thiết phải khử trùng lặp các thư trên hàng đợi chủ đề?
user1658296,

2
@oblivion có các thư đi vào cùng một phân vùng theo tuần tự là rất quan trọng để xử lý các bản cập nhật không phải là tin nhắn, ví dụ: khách hàng chọn ngày gửi (một thư) nhưng đổi ý sau (thư thứ hai). Nếu các thông báo được chuyển đến các phân vùng khác nhau thì một trong hai thông báo có thể được xử lý trước / sau, ví dụ như với 2 người tiêu dùng sử dụng từ mỗi phân vùng. Nếu cả hai thông báo liên quan đến cùng một Phân phối đi vào cùng một phân vùng thì chúng được xử lý theo thứ tự xuất trước, đưa ra ngày gửi cuối cùng chính xác.
Kunal

3
Các đảm bảo thứ tự không đến từ khóa mà từ các thư nằm trong cùng một phân vùng. Việc định tuyến thư đến các phân vùng không cần phải dựa trên khóa. Bạn có thể chỉ định rõ ràng một phân vùng khi tạoProducerRecord
Malt

2
Tôi hiểu là ứng dụng khách nhà sản xuất chịu trách nhiệm chọn phân vùng ( kafka.apache.org/documentation.html#design_loadbalancing ), có thể dựa trên khóa hoặc không. Vậy tại sao bạn lại nói chìa khóa cần thiết để đặt hàng?
lfk

5

Ngoài câu trả lời được chấp nhận rất hữu ích, tôi muốn bổ sung thêm một số chi tiết

Phân vùng

Theo mặc định, Kafka sử dụng khóa của tin nhắn để chọn phân vùng của chủ đề mà nó viết. Điều này được thực hiện bởi một cái gì đó như

hash(key) % number_of_partitions

Nếu không có khóa nào được cung cấp, thì Kafka sẽ phân vùng dữ liệu ngẫu nhiên theo kiểu vòng tròn.

Đặt hàng

Như đã nêu trong câu trả lời đã cho, Kafka đảm bảo về việc sắp xếp các tin nhắn chỉ ở cấp độ phân vùng.

Giả sử bạn muốn lưu trữ các giao dịch tài chính cho khách hàng của mình trong một chủ đề Kafka với hai phân vùng. Các thông báo có thể trông giống như (key: value)

null:{"customerId": 1, "changeInBankAccount": +200}
null:{"customerId": 2, "changeInBankAccount": +100}
null:{"customerId": 1, "changeInBankAccount": +200}
null:{"customerId": 1, "changeInBankAccount": -1337}
null:{"customerId": 1, "changeInBankAccount": +200}

Vì chúng tôi chưa xác định khóa nên hai phân vùng có lẽ sẽ trông giống như

// partition 0
null:{"customerId": 1, "changeInBankAccount": +200}
null:{"customerId": 1, "changeInBankAccount": +200}
null:{"customerId": 1, "changeInBankAccount": +200}

// partition 1
null:{"customerId": 2, "changeInBankAccount": +100}
null:{"customerId": 1, "changeInBankAccount": -1337}

Người tiêu dùng của bạn đọc chủ đề đó cuối cùng có thể cho bạn biết rằng số dư trên tài khoản là 600 tại một thời điểm cụ thể mặc dù điều đó không bao giờ đúng! Chỉ vì nó đã đọc tất cả các thư trong phân vùng 0 trước các thư trong phân vùng 1.

Với một khóa hợp lý (như customerId), điều này có thể tránh được vì việc chia thành phần sẽ như thế này:

// partition 0
1:{"customerId": 1, "changeInBankAccount": +200}
1:{"customerId": 1, "changeInBankAccount": +200}
1:{"customerId": 1, "changeInBankAccount": -1337}
1:{"customerId": 1, "changeInBankAccount": +200}

// partition 1
2:{"customerId": 2, "changeInBankAccount": +100}

Ghi nhật ký nén

Nếu không có khóa trong thư của bạn, bạn sẽ không thể đặt cấu hình chủ đề cleanup.policythành compacted. Theo tài liệu "log compaction đảm bảo rằng Kafka sẽ luôn giữ lại ít nhất giá trị đã biết cuối cùng cho mỗi khóa thông báo trong nhật ký dữ liệu cho một phân vùng chủ đề."

Cài đặt hữu ích và tốt đẹp này sẽ không khả dụng nếu không có bất kỳ khóa nào.

Sử dụng các phím

Trong các trường hợp sử dụng thực tế, chìa khóa của thông điệp Kafka có thể có ảnh hưởng rất lớn đến hiệu suất và sự rõ ràng của logic kinh doanh của bạn.

Ví dụ, một khóa có thể được sử dụng tự nhiên để phân vùng dữ liệu của bạn. Vì bạn có thể kiểm soát người tiêu dùng của mình đọc từ các phân vùng cụ thể, điều này có thể đóng vai trò như một bộ lọc hiệu quả. Ngoài ra, khóa có thể bao gồm một số dữ liệu meta về giá trị thực của thông báo giúp bạn kiểm soát quá trình xử lý tiếp theo. Các khóa thường là giá trị nhỏ hơn và do đó sẽ thuận tiện hơn khi phân tích cú pháp một khóa thay vì toàn bộ giá trị. Đồng thời, bạn có thể áp dụng tất cả các tuần tự hóa và đăng ký lược đồ như đã thực hiện với giá trị của bạn cũng bằng khóa.

Lưu ý, cũng có khái niệm Header có thể dùng để lưu trữ thông tin, xem tài liệu hướng dẫn .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.