Sự khác biệt giữa tính không thay đổi và chính xác một lần trong Kafka Stream


8

Tôi đã xem qua tài liệu những gì tôi hiểu rằng chúng ta có thể đạt được giao dịch chính xác một lần với việc kích hoạt idempotence=true

idempotence: Nhà sản xuất Idempotent cho phép chính xác một lần cho nhà sản xuất đối với một chủ đề duy nhất. Về cơ bản, mỗi tin nhắn gửi đơn đều có bảo đảm chắc chắn hơn và sẽ không bị trùng lặp trong trường hợp có lỗi

Vậy nếu chúng ta đã có sự bình tĩnh thì tại sao chúng ta cần một tài sản khác chính xác - một lần trong Kafka Stream? Điều gì khác biệt chính xác giữa idempotence so với chính xác một lần

Tại sao tài sản chính xác một lần không có sẵn trong Nhà sản xuất Kafka bình thường?


2
Bài đăng trên blog này cũng là một nguồn tốt để biết thêm thông tin: Medium.com/@andy.bryant/ Kẻ
Matthias J. Sax

Câu trả lời:


6

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.

nhập mô tả hình ảnh ở đây

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. nhập mô tả hình ảnh ở đây

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. nhập mô tả hình ảnh ở đây

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.

nhập mô tả hình ảnh ở đây

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

  1. enable.idempotence = true (địa chỉ a, b & c)
  2. 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)
  3. 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 nhập mô tả hình ảnh ở đây

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. nhập mô tả hình ảnh ở đây

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

  1. cô lập.level = read_commned
  2. enable.idempotence = true
  3. MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION = 5

12

Luồng Kafka cung cấp ngữ nghĩa chính xác một lần từ quan điểm từ đầu đến cuối (tiêu thụ từ một chủ đề, xử lý thông điệp đó, sau đó tạo ra chủ đề khác). Tuy nhiên, bạn chỉ đề cập đến thuộc tính idempotent của nhà sản xuất . Đó chỉ là một phần nhỏ của bức tranh đầy đủ.

Hãy để tôi viết lại câu hỏi:

Tại sao chúng ta cần ngữ nghĩa phân phối chính xác một lần ở phía người tiêu dùng trong khi chúng ta đã đảm bảo ngữ nghĩa phân phối chính xác một lần ở phía nhà sản xuất?

Trả lời: Vì ngữ nghĩa phân phối chính xác một lần không chỉ ở bước sản xuất mà là toàn bộ quy trình xử lý. Để đạt được giao hàng chính xác một lần về mặt ngữ nghĩa, có một số điều kiện phải được thỏa mãn với việc sản xuất và tiêu thụ.

Đây là kịch bản chung: Quá trình A tạo thông điệp cho chủ đề T. Đồng thời, quy trình B cố gắng tiêu thụ thư từ chủ đề T. Chúng tôi muốn đảm bảo quy trình B không bao giờ xử lý một tin nhắn hai lần.

Phần nhà sản xuất: Chúng tôi phải đảm bảo rằng các nhà sản xuất không bao giờ tạo ra một thông điệp hai lần. Chúng tôi có thể sử dụng Kafka Idempotent Producer

Phần người tiêu dùng: Đây là quy trình làm việc cơ bản cho người tiêu dùng:

  • Bước 1: Người tiêu dùng lấy thông điệp M thành công từ chủ đề của Kafka.
  • Bước 2: Người tiêu dùng cố gắng thực hiện công việc và công việc trở lại thành công.
  • Bước 3: Người tiêu dùng cam kết bù đắp thông điệp cho các nhà môi giới Kafka.

Các bước trên chỉ là một con đường hạnh phúc. Có nhiều vấn đề phát sinh trong thực tế.

  • Kịch bản 1: Công việc ở bước 2 thực hiện thành công nhưng sau đó người tiêu dùng bị sập. Vì tình huống bất ngờ này, người tiêu dùng chưa cam kết bù đắp thông điệp. Khi người tiêu dùng khởi động lại, tin nhắn sẽ được tiêu thụ hai lần.
  • Kịch bản 2: Mặc dù người tiêu dùng cam kết bù ở bước 3, nhưng nó gặp sự cố do lỗi phần cứng (ví dụ: CPU, vi phạm bộ nhớ, ...) Khi khởi động lại, người tiêu dùng không biết cách nào để cam kết bù đắp thành công hay không.

Bởi vì có nhiều vấn đề có thể xảy ra, việc thực thi công việc và phần bù cam kết phải là nguyên tử để đảm bảo chính xác - một lần ngữ nghĩa giao hàng ở phía người tiêu dùng. Điều đó không có nghĩa là chúng tôi không thể nhưng phải mất rất nhiều nỗ lực để đảm bảo ngữ nghĩa phân phối chính xác một lần. Kafka Stream duy trì công việc cho các kỹ sư.

Lưu ý rằng: Kafka Stream cung cấp "xử lý luồng chính xác một lần". Nó đề cập đến việc tiêu thụ từ một chủ đề, cụ thể hóa trạng thái trung gian trong một chủ đề Kafka và sản xuất thành một chủ đề. Nếu ứng dụng của chúng tôi phụ thuộc vào một số dịch vụ bên ngoài khác (cơ sở dữ liệu, dịch vụ ...), chúng tôi phải đảm bảo các phụ thuộc bên ngoài của chúng tôi có thể đảm bảo chính xác - một lần trong các trường hợp đó.

TL, DR: chính xác - một lần cho toàn bộ dòng chảy cần sự hợp tác giữa người sản xuất và người tiêu dùng.

Người giới thiệu:


Tôi sẽ không gọi đó là chuyển phát , bởi vì việc chuyển phát thường ngụ ý tần suất đọc / gửi tin nhắn và chính xác - một lần trong Kafka rõ ràng rút lui trong nội bộ vì lý do thất bại. Chính xác-once cung cấp (ví dụ, mức độ thường xuyên nhắn thực sự được gửi qua mạng) là provably không thể (cf en.wikipedia.org/wiki/Byzantine_faulten.wikipedia.org/wiki/Two_Generals%27_Problem )
Matthias J. Sax

Đúng. Như đã đề cập trong câu trả lời, đúng là Kafka Stream không cung cấp giao hàng chính xác một lần trong thuật ngữ chung. Về hai vấn đề chung, chúng ta không thể có chính xác chung một lần trong hệ thống phân tán nhưng có thể thực hiện được khi chúng ta mất một số điều kiện hoặc thêm một số điều kiện vào hệ thống. ví dụ: thời gian chờ. Tuy nhiên, đây là câu chuyện khác nhau.
hqt

Vâng, tôi sẽ không sử dụng thuật ngữ giao hàng , nhưng gắn bó với ngữ nghĩa .
Matthias J. Sax
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.