Group và tránh trùng lặp message khi sử dụng Kafka

Hệ thống hiện tại mình đang dùng để broadcast messages cho các client sử dụng Kafka như sau
image

Vấn đề hiện tại là khi Request update entities nhận được nhiều thì sẽ dẫn tới messages kafka nhận / truyền cũng nhiều và có thể bị lặp lại (mỗi lần update 1 entity), không tiết kiệm băng thông.

Ý tưởng mình đang đưa ra là hold messages (vd 3s) và group messages lại để

  • check record trùng lặp => chỉ lấy entities với được update mới nhất
  • Mỗi lần gửi đến Kafka 1 batch các records (gom lại ở 3s đó)

Solutions

  1. Lưu messages vào redis, dùng interval lấy dữ liệu trong đó gửi đến Kafka rồi clear redis cache.
  2. Mình check thấy Kafka có Log compacted có thể bỏ đi các records mà có nhiều bản update gần đây với cùng một primary key nhưng mỗi lần mình gửi messages đến thì kafka sẽ gửi đến các consumer luôn nên cách này chưa biết có khả thi không.

Nhờ các cao nhân cho ý kiến / góp ý :smile:

lý do này là do bạn tự đặt ra hay là căn cứ vào đâu?
bạn nói rõ một trường hợp bạn đã nghĩ tới xem, bằng thông lớn thì bao nhiêu, sau khi áp dụng thì bao nhiêu? hoặc bạn đã tưởng tượng hệ thống của bạn khi peaking thì bầm bao nhiêu tps (transaction per second)?

  1. giả sử như áp dụng như thế, thì A0 -> A1 -> A2, các bên khác chỉ thấy được A0 -> A2? vậy là tracking/audit không được toàn vẹn?

  2. message nhiều tới mức phải để ý tới băng thông, mà bạn còn “để dành” đến 3s mới cho đi 1 phần, vậy đám client nhận nhiều message một cách đột ngột như thế liệu có ổn không? rồi đang xử lý thì 3s sau nữa lại có một mớ message nữa tới đến

tóm lại là dùng kafka nghe cho nó hoành tráng mà mấy cái cơ bản, mấy cái cốt lõi thì lại muốn bỏ qua

1 Like

Tiết kiệm băng thông ở đây là cho client dùng 3G/4G sử dụng.

  1. nếu đúng là có bên thứ 3 sử dụng API thì sẽ không tracking được tất cả status, nhưng phần mềm ở đây chỉ sử dụng nội bộ nên chỉ cần hiển thị status mới nhất.
  2. messages gửi đến rất nhiều. Do chỉ cần hiển thị status mới nhất nên hold / delay 3s có thể chấp nhận được (cái này là configurable). Hiện tại client xử lý lượng data đó vẫn ok :slight_smile:

Ohm, cậu đang để client (end user) connect trực tiếp tới kafka? @@ Tớ không nghĩ đó là lựa chọn tốt đâu @@

Về các solution cậu đưa:

  • Cậu không nên hold message ở server side (publisher side) để dedup, vì hẳn nhiên nó thêm tải cho publisher side, và nó cũng không phải là nhiệm vụ của server side. Nếu cậu cần dedup, cậu nên làm nó ở consumer side, tốt nhất là giới thiệu 1 service mới để dedup (dedup và đưa sang 1 queue khác cho consumer).
    Cách này giúp cậu scale được, nếu như cậu cần dedup nhanh hơn, cậu chỉ cần thêm worker ở service mới.
  • Log compact có thể được (tớ chưa test, cơ mà có thể ý tưởng đó được), nhưng đòi hỏi cậu có thể phải sửa design cho message, và làm configuration bên Kafka phức tạp hơn cần thiết. Cậu cũng thêm tải cho Kafka nữa (thường thì nó ko là vấn đề, cơ mà cá nhân tớ thường hay giữ cho message broker chỉ làm đúng việc của nó, và chuyển task/logic sang application để tiện cho việc manage và scale).
    Nếu những vấn đề đó không phải thứ cậu quá bận tâm, cậu nên thử phương án này.

Thực ra, cậu nên dùng Kafka như một nơi chứa các event (log event - event source - bất cứ thuật ngữ nào tương tự). Đó là thứ mà Kafka được thiết kế để làm, và như @kisuluoibieng đề cập ở ví dụ của cậu ấy, cậu có thể tận dụng log event đó cho rất nhiều mục đích.
Nếu cậu cần làm bất cứ thứ gì, để consumer tự do làm điều đó tốt hơn là để publisher, hay chính message broker như Kafka.

Hope it helps!

2 Likes

bạn đã nói như thế này thì chắc chắn “làm gì cũng đúng” rồi, nên khỏi phân vân làm chi, cứ làm thôi

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?