Trong môi trường phân tán thất bại là kịch bản rất phổ biến có thể xảy ra bất cứ lúc nào. Trong môi trường Kafka, nhà môi giới có thể gặp sự cố, lỗi mạng, thất bại trong xử lý, thất bại trong khi xuất bản tin nhắn hoặc không sử dụng tin nhắn, vv Các kịch bản khác nhau này đã đưa ra loại mất dữ liệu và trùng lặp khác nhau.
Kịch bản thất bại
A (Ack Thất bại): Nhà sản xuất đã xuất bản tin nhắn thành công với thử lại> 1 nhưng không thể nhận được xác nhận do thất bại. Trong trường hợp đó, Nhà sản xuất sẽ thử lại cùng một thông điệp có thể giới thiệu trùng lặp.
B (Quá trình sản xuất không thành công trong các tin nhắn theo đợt): Nhà sản xuất gửi hàng loạt tin nhắn thất bại với một vài thành công được công bố. Trong trường hợp đó và một khi nhà sản xuất sẽ khởi động lại, nó sẽ lại xuất bản lại tất cả các tin nhắn từ đợt sẽ giới thiệu trùng lặp trong Kafka.
C (Fire & Forget Thất bại) Nhà sản xuất đã xuất bản tin nhắn với retry = 0 (cháy và quên). Trong trường hợp thất bại được công bố sẽ không nhận thức được và gửi tin nhắn tiếp theo, điều này sẽ khiến tin nhắn bị mất.
D (Người tiêu dùng thất bại trong tin nhắn theo đợt) Một người tiêu dùng nhận được một loạt tin nhắn từ Kafka và tự cam kết bù đắp (enable.auto.commit = false). Nếu người tiêu dùng thất bại trước khi cam kết với Kafka, lần tới Người tiêu dùng sẽ sử dụng lại các bản ghi tương tự để sao chép lại về phía người tiêu dùng.
Chính xác-Một lần ngữ nghĩa
Trong trường hợp này, ngay cả khi nhà sản xuất cố gắng gửi lại tin nhắn, nó sẽ dẫn đến tin nhắn sẽ được xuất bản và tiêu thụ bởi người tiêu dùng chính xác một lần.
Để đạt được chính xác một lần ngữ nghĩa trong Kafka, nó sử dụng dưới 3 thuộc tính
- enable.idempotence = true (địa chỉ a, b & c)
- MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION = 5 (Nhà sản xuất sẽ luôn có một yêu cầu trên chuyến bay cho mỗi kết nối)
- cô lập.level = read_commned (địa chỉ d)
Kích hoạt Idempotent (enable.idempotence = true)
Phân phối tạm thời cho phép nhà sản xuất viết tin nhắn cho Kafka chính xác một lần đến một phân vùng cụ thể của một chủ đề trong suốt vòng đời của một nhà sản xuất mà không mất dữ liệu và đặt hàng trên mỗi phân vùng.
"Lưu ý rằng việc kích hoạt tính không cần thiết phải yêu cầu MAX_IN_FLIGHT_REQUESTS_PER_CONNMENT nhỏ hơn hoặc bằng 5, RETRIES_CONFIG phải lớn hơn 0 và ACKS_CONFIG sẽ là 'tất cả'. được đặt, một ConfigException sẽ bị ném "
Để đạt được idempotence, Kafka sử dụng id duy nhất được gọi là id sản phẩm hoặc PID và số thứ tự trong khi tạo thông điệp. Nhà sản xuất tiếp tục tăng số thứ tự trên mỗi thông báo được xuất bản trên bản đồ với PID duy nhất. Nhà môi giới luôn so sánh số thứ tự hiện tại với số trước đó và nó từ chối nếu số mới không lớn hơn +1 trước đó để tránh trùng lặp và đồng thời nếu mất nhiều hơn hiển thị trong tin nhắn
Trong trường hợp thất bại, nhà môi giới sẽ so sánh số thứ tự với số trước đó và nếu chuỗi không tăng +1 sẽ từ chối thông báo.
Giao dịch (cô lập.level)
Giao dịch cung cấp cho chúng tôi khả năng cập nhật dữ liệu nguyên tử trong nhiều phân vùng chủ đề. Tất cả các hồ sơ được bao gồm trong một giao dịch sẽ được lưu thành công hoặc không có hồ sơ nào trong số đó. Nó cho phép bạn cam kết giảm giá cho người tiêu dùng trong cùng một giao dịch cùng với dữ liệu bạn đã xử lý, từ đó cho phép kết thúc chính xác một lần ngữ nghĩa .
Nhà sản xuất không chờ đợi để viết tin nhắn cho kafka trong đó Nhà sản xuất sử dụng BeginTransaction, commitTransaction và abortTransaction (trong trường hợp thất bại) Người tiêu dùng sử dụng cách ly.level hoặc read_commned hoặc read_uncommned
- read_commned: Người tiêu dùng sẽ luôn chỉ đọc dữ liệu đã cam kết.
- read_uncommned: Đọc tất cả các tin nhắn theo thứ tự bù mà không cần chờ giao dịch được thực hiện
Nếu người tiêu dùng có cách ly.level = read_commned đạt được thông báo kiểm soát cho giao dịch chưa hoàn thành, nó sẽ không gửi thêm bất kỳ tin nhắn nào từ phân vùng này cho đến khi nhà sản xuất cam kết hoặc hủy bỏ giao dịch hoặc hết thời gian giao dịch. Thời gian chờ giao dịch được xác định bởi nhà sản xuất bằng cách sử dụng cấu hình giao dịch.timeout.ms (mặc định 1 phút).
Chính xác-Một lần trong Nhà sản xuất & Người tiêu dùng
Trong điều kiện bình thường, nơi chúng tôi có nhà sản xuất và người tiêu dùng riêng biệt. Nhà sản xuất phải tạm thời và quản lý giao dịch đồng thời để người tiêu dùng có thể sử dụng cách ly.level để chỉ đọc read_commned để thực hiện toàn bộ quá trình dưới dạng hoạt động nguyên tử. Điều này đảm bảo rằng nhà sản xuất sẽ luôn đồng bộ hóa với hệ thống nguồn. Ngay cả sự cố nhà sản xuất hoặc giao dịch bị hủy bỏ, nó luôn luôn nhất quán và xuất bản tin nhắn hoặc lô tin nhắn dưới dạng đơn vị một lần.
Cùng một người tiêu dùng sẽ nhận được tin nhắn hoặc lô tin nhắn như một đơn vị một lần.
Trong Nhà sản xuất ngữ nghĩa chính xác một lần cùng với Người tiêu dùng sẽ xuất hiện dưới dạng hoạt động nguyên tử sẽ hoạt động như một đơn vị. Hoặc xuất bản và được tiêu thụ một lần ở tất cả hoặc bị hủy bỏ.
Chính xác một lần trong Kafka Stream
Kafka Stream tiêu thụ các tin nhắn từ chủ đề A, xử lý và xuất bản tin nhắn đến Chủ đề B và một khi xuất bản sử dụng cam kết (chủ yếu là chạy dưới vỏ bọc) để xóa tất cả dữ liệu lưu trữ trạng thái vào đĩa.
Chính xác một lần trong Kafka Stream là mẫu đọc-process-write, đảm bảo rằng các hoạt động này sẽ được coi là hoạt động nguyên tử. Vì Kafka Stream phục vụ nhà sản xuất, người tiêu dùng và giao dịch cùng nhau, Kafka Stream đi kèm với tham số đặc biệt process.guarantee có thể chính xác_once hoặc at_least_once giúp dễ dàng không xử lý tất cả các tham số riêng biệt.
Kafka Streams cập nhật về mặt nguyên tắc cho người tiêu dùng, cửa hàng nhà nước địa phương, chủ đề thay đổi cửa hàng nhà nước và sản xuất cho tất cả các chủ đề cùng nhau. Nếu bất kỳ một trong các bước này không thành công, tất cả các thay đổi sẽ được khôi phục.
process.guarantee: precision_once tự động cung cấp các tham số bên dưới mà bạn không cần phải thiết lập một cách rõ ràng
- cô lập.level = read_commned
- enable.idempotence = true
- MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION = 5