RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao

В bài viết cuối cùng chúng tôi đã xem xét phân cụm RabbitMQ để tìm khả năng chịu lỗi và tính sẵn sàng cao. Bây giờ hãy tìm hiểu sâu về Apache Kafka.

Ở đây đơn vị sao chép là phân vùng. Mỗi chủ đề có một hoặc nhiều phần. Mỗi phần có một người lãnh đạo có hoặc không có người theo dõi. Khi tạo chủ đề, bạn chỉ định số lượng phân vùng và hệ số sao chép. Giá trị thông thường là 3, có nghĩa là ba bản sao: một người dẫn đầu và hai người theo sau.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 1. Bốn phần được phân phối giữa ba nhà môi giới

Tất cả các yêu cầu đọc và ghi đều được chuyển đến người lãnh đạo. Người theo dõi định kỳ gửi yêu cầu đến người lãnh đạo để nhận tin nhắn mới nhất. Người tiêu dùng không bao giờ hướng tới những người theo sau; những người theo sau chỉ tồn tại để dự phòng và chịu lỗi.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao

Lỗi phân vùng

Khi một nhà môi giới thất bại, lãnh đạo của một số bộ phận thường thất bại. Trong mỗi người trong số họ, một người theo dõi từ một nút khác sẽ trở thành người dẫn đầu. Trên thực tế, điều này không phải lúc nào cũng đúng, vì yếu tố đồng bộ hóa cũng ảnh hưởng: liệu có người theo dõi được đồng bộ hóa hay không và nếu không thì có được phép chuyển sang bản sao không đồng bộ hay không. Nhưng bây giờ chúng ta đừng phức tạp hóa mọi chuyện.

Nhà môi giới 3 rời khỏi mạng và một nhà lãnh đạo mới được bầu vào phần 2 tại nhà môi giới 2.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 2. Người môi giới 3 qua đời và người theo dõi anh ta ở người môi giới 2 được bầu làm lãnh đạo mới của phân khu 2

Sau đó, người môi giới 1 rời đi và phần 1 cũng mất đi người lãnh đạo, vai trò của người này được chuyển giao cho người môi giới 2.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 3. Còn lại một nhà môi giới. Tất cả các nhà lãnh đạo đều làm việc trên một nhà môi giới không có sự dư thừa

Khi nhà môi giới 1 trực tuyến trở lại, nó sẽ thêm bốn người theo dõi, cung cấp một số dự phòng cho mỗi phân vùng. Nhưng tất cả các nhà lãnh đạo vẫn ở lại môi giới 2.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 4. Lãnh đạo vẫn ở môi giới 2

Khi nhà môi giới 3 xuất hiện, chúng tôi quay lại ba bản sao cho mỗi phân vùng. Nhưng tất cả các nhà lãnh đạo vẫn ở môi giới 2.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 5. Vị trí lãnh đạo mất cân bằng sau khi khôi phục môi giới 1 và 3

Kafka có một công cụ giúp tái cân bằng lãnh đạo tốt hơn RabbitMQ. Ở đó, bạn phải sử dụng plugin hoặc tập lệnh của bên thứ ba để thay đổi chính sách di chuyển nút chính bằng cách giảm sự dư thừa trong quá trình di chuyển. Ngoài ra, đối với các hàng đợi lớn, chúng tôi phải chấp nhận tình trạng không sẵn sàng trong quá trình đồng bộ hóa.

Kafka có khái niệm “bản sao ưa thích” cho vai trò lãnh đạo. Khi phân vùng chủ đề được tạo, Kafka cố gắng phân bổ đồng đều các nhà lãnh đạo trên các nút và đánh dấu những nhà lãnh đạo đầu tiên đó là ưu tiên. Theo thời gian, do máy chủ khởi động lại, lỗi và sự cố kết nối, các nhà lãnh đạo có thể chuyển sang các nút khác, như trong trường hợp cực đoan được mô tả ở trên.

Để khắc phục điều này, Kafka đưa ra hai lựa chọn:

  • Lựa chọn auto.leader.rebalance.enable=true cho phép nút điều khiển tự động chỉ định lại các nhà lãnh đạo trở lại các bản sao ưa thích và từ đó khôi phục phân phối thống nhất.
  • Quản trị viên có thể chạy tập lệnh kafka-preferred-replica-election.sh để gán lại thủ công.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 6. Bản sao sau khi cân bằng lại

Đây là một phiên bản đơn giản hóa của sự cố, nhưng thực tế thì phức tạp hơn, mặc dù không có gì quá phức tạp ở đây. Tất cả đều thuộc về các bản sao được đồng bộ hóa (Bản sao đồng bộ hóa, ISR).

Bản sao được đồng bộ hóa (ISR)

ISR là một tập hợp các bản sao của một phân vùng được coi là “được đồng bộ hóa” (không đồng bộ). Có người dẫn đầu nhưng có thể không có người theo sau. Người theo dõi được coi là đã đồng bộ nếu nó đã tạo bản sao chính xác của tất cả thông điệp của người dẫn đầu trước khi hết khoảng thời gian bản sao.lag.time.max.ms.

Người theo dõi sẽ bị xóa khỏi bộ ISR nếu người đó:

  • đã không đưa ra yêu cầu chọn khoảng thời gian bản sao.lag.time.max.ms (được cho là đã chết)
  • không quản lý để cập nhật trong khoảng thời gian bản sao.lag.time.max.ms (được coi là chậm)

Người theo dõi đưa ra yêu cầu lấy mẫu trong khoảng thời gian bản sao.fetch.wait.max.ms, mặc định là 500ms.

Để giải thích rõ ràng mục đích của ISR, chúng ta cần xem xét các xác nhận từ nhà sản xuất và một số tình huống thất bại. Nhà sản xuất có thể chọn thời điểm người môi giới gửi xác nhận:

  • acks=0, xác nhận không được gửi
  • acks=1, xác nhận được gửi sau khi người lãnh đạo viết tin nhắn vào nhật ký cục bộ của mình
  • acks=all, xác nhận được gửi sau khi tất cả các bản sao trong ISR đã ghi thông báo vào nhật ký cục bộ

Theo thuật ngữ của Kafka, nếu ISR đã lưu một tin nhắn thì đó là “đã cam kết”. Acks=all là lựa chọn an toàn nhất nhưng cũng gây thêm độ trễ. Hãy xem xét hai ví dụ về sự thất bại và cách các tùy chọn 'ack' khác nhau tương tác với khái niệm ISR.

Acks=1 và ISR

Trong ví dụ này, chúng ta sẽ thấy rằng nếu người lãnh đạo không đợi mọi tin nhắn từ tất cả những người theo dõi được lưu thì có thể mất dữ liệu nếu người lãnh đạo thất bại. Có thể bật hoặc tắt tính năng điều hướng đến người theo dõi chưa được đồng bộ hóa bằng cách cài đặt ô uế.leader.election.enable.

Trong ví dụ này, nhà sản xuất có giá trị acks=1. Phần này được phân phối trên cả ba nhà môi giới. Nhà môi giới 3 ở phía sau, nó đã đồng bộ hóa với nhà lãnh đạo tám giây trước và hiện có 7456 tin nhắn ở phía sau. Nhà môi giới 1 chỉ chậm hơn một giây. Nhà sản xuất của chúng tôi gửi tin nhắn và nhanh chóng nhận được phản hồi mà không cần phải tốn thêm chi phí cho những người theo dõi chậm hoặc chết mà người lãnh đạo không chờ đợi.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 7. ISR với ba bản sao

Nhà môi giới 2 không thành công và nhà sản xuất nhận được lỗi kết nối. Sau khi quyền lãnh đạo được chuyển cho nhà môi giới 1, chúng tôi mất 123 tin nhắn. Người theo dõi trên nhà môi giới 1 là một phần của ISR, nhưng không được đồng bộ hóa hoàn toàn với người dẫn đầu khi nó sụp đổ.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 8. Tin nhắn bị mất khi bị treo

Trong cấu hình bootstrap.servers Nhà sản xuất có một số nhà môi giới được liệt kê và có thể yêu cầu một nhà môi giới khác làm trưởng bộ phận mới. Sau đó nó thiết lập kết nối với nhà môi giới 1 và tiếp tục gửi tin nhắn.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 9. Gửi tin nhắn tiếp tục sau một khoảng thời gian ngắn

Nhà môi giới 3 thậm chí còn bị tụt lại phía sau. Nó thực hiện các yêu cầu tìm nạp nhưng không thể đồng bộ hóa. Điều này có thể là do kết nối mạng chậm giữa các nhà môi giới, vấn đề lưu trữ, v.v. Nó bị xóa khỏi ISR. Bây giờ ISR bao gồm một bản sao - người dẫn đầu! Nhà sản xuất tiếp tục gửi tin nhắn và nhận xác nhận.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 10. Người theo dõi trên nhà môi giới 3 bị xóa khỏi ISR

Nhà môi giới 1 ngừng hoạt động và vai trò lãnh đạo thuộc về nhà môi giới 3 với 15286 tin nhắn bị mất! Nhà sản xuất nhận được thông báo lỗi kết nối. Việc chuyển đổi sang người lãnh đạo bên ngoài ISR ​​chỉ có thể thực hiện được do cài đặt ô uế.leader.election.enable=true. Nếu nó được cài đặt trong sai, thì quá trình chuyển đổi sẽ không xảy ra và tất cả các yêu cầu đọc và ghi sẽ bị từ chối. Trong trường hợp này, chúng tôi đợi nhà môi giới 1 quay lại với dữ liệu nguyên vẹn của anh ấy trong bản sao, bản sao này sẽ lại nắm quyền lãnh đạo.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 11. Người môi giới 1 ngã. Khi xảy ra lỗi, một lượng lớn tin nhắn sẽ bị mất

Nhà sản xuất thiết lập mối liên hệ với người môi giới cuối cùng và thấy rằng anh ta hiện là người đứng đầu bộ phận. Anh ta bắt đầu gửi tin nhắn cho người môi giới 3.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 12. Sau một thời gian nghỉ ngắn, tin nhắn lại được gửi đến phần 0

Chúng tôi thấy rằng, ngoài những khoảng thời gian gián đoạn ngắn ngủi để thiết lập các kết nối mới và tìm kiếm người lãnh đạo mới, nhà sản xuất còn liên tục gửi tin nhắn. Cấu hình này đảm bảo tính khả dụng nhưng phải trả giá bằng tính nhất quán (bảo mật dữ liệu). Kafka đã mất hàng nghìn tin nhắn nhưng vẫn tiếp tục nhận những bài viết mới.

Acks=tất cả và ISR

Hãy lặp lại kịch bản này một lần nữa, nhưng với acks = tất cả. Nhà môi giới 3 có độ trễ trung bình là bốn giây. Nhà sản xuất gửi tin nhắn với acks = tất cả, và bây giờ không nhận được phản hồi nhanh chóng. Người lãnh đạo đợi tin nhắn được lưu bởi tất cả các bản sao trong ISR.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 13. ISR với ba bản sao. Một là chậm, dẫn đến độ trễ ghi

Sau bốn giây trì hoãn bổ sung, nhà môi giới 2 gửi xác nhận. Tất cả các bản sao hiện đã được cập nhật đầy đủ.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 14. Tất cả các bản sao đều lưu tin nhắn và gửi xác nhận

Nhà môi giới 3 hiện tụt lại phía sau và bị loại khỏi ISR. Độ trễ giảm đáng kể vì không còn bản sao chậm nào trong ISR. Nhà môi giới 2 hiện chỉ đợi nhà môi giới 1 và anh ta có độ trễ trung bình là 500 ms.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 15. Bản sao trên nhà môi giới 3 bị xóa khỏi ISR

Sau đó, người môi giới 2 thất bại và quyền lãnh đạo được chuyển cho người môi giới 1 mà không mất tin nhắn.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 16. Người môi giới 2 ngã

Nhà sản xuất tìm thấy một nhà lãnh đạo mới và bắt đầu gửi tin nhắn cho anh ta. Độ trễ còn giảm hơn nữa vì ISR hiện bao gồm một bản sao! Do đó tùy chọn acks = tất cả không thêm phần dư thừa.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 17. Bản sao trên nhà môi giới 1 dẫn đầu mà không làm mất tin nhắn

Sau đó, nhà môi giới 1 gặp sự cố và khách hàng tiềm năng chuyển sang nhà môi giới 3 với 14238 tin nhắn bị mất!

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 18. Nhà môi giới 1 qua đời và quá trình chuyển đổi lãnh đạo với cài đặt không rõ ràng dẫn đến mất dữ liệu trên diện rộng

Chúng tôi không thể cài đặt tùy chọn ô uế.leader.election.enable thành ý nghĩa đúng. Mặc định là bằng sai. Cài đặt acks = tất cả с ô uế.leader.election.enable=true cung cấp khả năng truy cập với một số bảo mật dữ liệu bổ sung. Nhưng như bạn có thể thấy, chúng ta vẫn có thể mất tin nhắn.

Nhưng nếu chúng ta muốn tăng cường bảo mật dữ liệu thì sao? Bạn có thể đặt ô uế.leader.election.enable = false, nhưng điều này không nhất thiết sẽ bảo vệ chúng ta khỏi bị mất dữ liệu. Nếu người lãnh đạo gặp khó khăn và mang theo dữ liệu, thì tin nhắn vẫn bị mất, cộng với tính khả dụng sẽ bị mất cho đến khi quản trị viên khôi phục lại tình hình.

Tốt hơn là đảm bảo rằng tất cả các tin nhắn đều dư thừa và nếu không thì hãy loại bỏ bản ghi. Khi đó, ít nhất theo quan điểm của nhà môi giới, việc mất dữ liệu chỉ có thể xảy ra trong trường hợp có hai hoặc nhiều lỗi xảy ra đồng thời.

Acks=all, min.insync.replicas và ISR

Với cấu hình chủ đề min.insync.replicas Chúng tôi đang tăng mức độ bảo mật dữ liệu. Chúng ta hãy xem lại phần cuối của kịch bản trước, nhưng lần này với min.insync.replicas=2.

Vì vậy, nhà môi giới 2 có một nhà lãnh đạo bản sao và người theo dõi trên nhà môi giới 3 bị xóa khỏi ISR.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 19. ISR từ hai bản sao

Người môi giới 2 thất bại và quyền lãnh đạo được chuyển cho người môi giới 1 mà không bị mất tin nhắn. Nhưng bây giờ ISR chỉ bao gồm một bản sao. Điều này không đáp ứng số lượng tối thiểu để nhận bản ghi và do đó, nhà môi giới phản hồi lại nỗ lực ghi có lỗi Bản sao không đủ.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 20. Số lượng ISR thấp hơn một so với quy định trong min.insync.replicas

Cấu hình này hy sinh tính sẵn sàng để đảm bảo tính nhất quán. Trước khi xác nhận một tin nhắn, chúng tôi đảm bảo rằng nó được ghi vào ít nhất hai bản sao. Điều này mang lại cho nhà sản xuất sự tự tin hơn nhiều. Ở đây, việc mất tin nhắn chỉ có thể xảy ra nếu hai bản sao bị lỗi đồng thời trong một khoảng thời gian ngắn cho đến khi tin nhắn được sao chép sang một người theo dõi bổ sung, điều này khó xảy ra. Nhưng nếu bạn cực kỳ hoang tưởng, bạn có thể đặt hệ số sao chép thành 5 và min.insync.replicas bằng 3. Ở đây ba nhà môi giới phải rơi cùng một lúc để mất kỷ lục! Tất nhiên, bạn phải trả tiền cho độ tin cậy này với độ trễ bổ sung.

Khi khả năng truy cập là cần thiết để bảo mật dữ liệu

Như trong trường hợp với RabbitMQ, đôi khi khả năng truy cập là cần thiết để bảo mật dữ liệu. Đây là những gì bạn cần suy nghĩ:

  • Nhà xuất bản có thể trả lại lỗi và yêu cầu dịch vụ ngược dòng hoặc người dùng thử lại sau không?
  • Nhà xuất bản có thể lưu tin nhắn cục bộ hoặc trong cơ sở dữ liệu để thử lại sau không?

Nếu câu trả lời là không thì việc tối ưu hóa tính khả dụng sẽ cải thiện tính bảo mật dữ liệu. Bạn sẽ mất ít dữ liệu hơn nếu chọn tính khả dụng thay vì không ghi. Vì vậy, tất cả đều phụ thuộc vào việc tìm kiếm sự cân bằng và quyết định phụ thuộc vào tình huống cụ thể.

Ý nghĩa của ISR

Bộ ISR cho phép bạn chọn sự cân bằng tối ưu giữa bảo mật dữ liệu và độ trễ. Ví dụ: đảm bảo tính khả dụng trong trường hợp phần lớn các bản sao bị lỗi, giảm thiểu tác động của các bản sao chết hoặc chậm về mặt độ trễ.

Chúng ta tự mình chọn ý nghĩa bản sao.lag.time.max.ms theo nhu cầu của bạn. Về cơ bản, tham số này có nghĩa là chúng ta sẵn sàng chấp nhận độ trễ bao nhiêu khi acks = tất cả. Giá trị mặc định là mười giây. Nếu điều này quá dài đối với bạn, bạn có thể giảm nó. Khi đó, tần suất thay đổi ISR ​​sẽ tăng lên vì những người theo dõi sẽ bị xóa và được thêm vào thường xuyên hơn.

RabbitMQ chỉ đơn giản là một bộ gương cần được nhân rộng. Các máy nhân bản chậm tạo ra độ trễ bổ sung và các máy nhân bản chết có thể đợi cho đến khi các gói kiểm tra tính khả dụng của mỗi nút (tích tắc mạng) để phản hồi. ISR là một cách thú vị để tránh những vấn đề về độ trễ này. Nhưng chúng tôi có nguy cơ mất đi sự dư thừa vì ISR chỉ có thể thu hẹp lại ở vị trí dẫn đầu. Để tránh rủi ro này, hãy sử dụng cài đặt min.insync.replicas.

Đảm bảo kết nối khách hàng

Trong cài đặt bootstrap.servers nhà sản xuất và người tiêu dùng có thể chỉ định nhiều nhà môi giới để kết nối khách hàng. Ý tưởng là khi một nút ngừng hoạt động, vẫn còn một số nút dự phòng mà khách hàng có thể mở kết nối. Đây không nhất thiết phải là người dẫn đầu phần mà chỉ đơn giản là bàn đạp cho việc tải ban đầu. Máy khách có thể hỏi họ nút nào lưu trữ phần lãnh đạo phân vùng đọc/ghi.

Trong RabbitMQ, máy khách có thể kết nối với bất kỳ nút nào và định tuyến nội bộ sẽ gửi yêu cầu đến nơi cần đến. Điều này có nghĩa là bạn có thể cài đặt bộ cân bằng tải trước RabbitMQ. Kafka yêu cầu máy khách kết nối với nút lưu trữ chỉ huy phân vùng tương ứng. Trong tình huống như vậy, bạn không thể cài đặt bộ cân bằng tải. Danh sách bootstrap.servers Điều quan trọng là khách hàng có thể truy cập và tìm thấy các nút chính xác sau khi xảy ra lỗi.

Kiến trúc đồng thuận Kafka

Cho đến bây giờ, chúng tôi vẫn chưa xem xét cách cụm biết về sự sụp đổ của nhà môi giới và cách bầu ra một người lãnh đạo mới. Để hiểu cách Kafka hoạt động với các phân vùng mạng, trước tiên bạn cần hiểu kiến ​​trúc đồng thuận.

Mỗi cụm Kafka được triển khai cùng với cụm Zookeeper, đây là một dịch vụ đồng thuận phân tán cho phép hệ thống đạt được sự đồng thuận ở một số trạng thái nhất định, ưu tiên tính nhất quán hơn tính khả dụng. Cần có sự đồng ý của phần lớn các nút Zookeeper để phê duyệt các hoạt động đọc và ghi.

Zookeeper lưu trữ trạng thái của cụm:

  • Danh sách các chủ đề, phần, cấu hình, bản sao dẫn đầu hiện tại, bản sao ưa thích.
  • Các thành viên của cụm. Mỗi nhà môi giới ping cụm Zookeeper. Nếu nó không nhận được ping trong một khoảng thời gian nhất định thì Zookeeper sẽ ghi lại nhà môi giới là không có sẵn.
  • Lựa chọn các nút chính và phụ cho bộ điều khiển.

Nút điều khiển là một trong những nhà môi giới Kafka chịu trách nhiệm bầu ra các nhà lãnh đạo bản sao. Zookeeper gửi thông báo đến bộ điều khiển về tư cách thành viên cụm và các thay đổi chủ đề, đồng thời bộ điều khiển phải hành động theo những thay đổi này.

Ví dụ: hãy lấy một chủ đề mới với mười phân vùng và hệ số sao chép là 3. Người điều khiển phải bầu ra một người lãnh đạo cho mỗi phân vùng, cố gắng phân bổ những người lãnh đạo một cách tối ưu giữa các nhà môi giới.

Đối với mỗi bộ điều khiển phần:

  • cập nhật thông tin trong Zookeeper về ISR và người lãnh đạo;
  • Gửi LeaderAndISRCommand tới mỗi nhà môi giới lưu trữ bản sao của phân vùng này, thông báo cho các nhà môi giới về ISR và nhà lãnh đạo.

Khi một nhà môi giới có người lãnh đạo bị sa ngã, Zookeeper sẽ gửi thông báo đến bộ điều khiển và nó sẽ bầu ra một người lãnh đạo mới. Một lần nữa, bộ điều khiển trước tiên cập nhật Zookeeper rồi gửi lệnh đến từng nhà môi giới để thông báo cho họ về sự thay đổi lãnh đạo.

Mỗi nhà lãnh đạo chịu trách nhiệm tuyển dụng ISR. Cài đặt bản sao.lag.time.max.ms quyết định ai sẽ vào đó. Khi ISR ​​thay đổi, người lãnh đạo sẽ truyền thông tin mới đến Zookeeper.

Zookeeper luôn được thông báo về bất kỳ thay đổi nào để trong trường hợp thất bại, ban quản lý sẽ chuyển giao suôn sẻ cho người lãnh đạo mới.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 21. Sự đồng thuận của Kafka

Giao thức sao chép

Hiểu chi tiết về việc sao chép sẽ giúp bạn hiểu rõ hơn về các tình huống mất dữ liệu có thể xảy ra.

Truy vấn lấy mẫu, Offset cuối nhật ký (LEO) và Highwater Mark (HW)

Chúng tôi cho rằng những người theo dõi định kỳ gửi yêu cầu tìm nạp tới người lãnh đạo. Khoảng thời gian mặc định là 500ms. Điều này khác với RabbitMQ ở chỗ bản sao RabbitMQ không được khởi tạo bởi máy nhân bản hàng đợi mà bởi máy chủ. Bậc thầy đẩy các thay đổi vào gương.

Người lãnh đạo và tất cả những người theo dõi lưu nhãn Log End Offset (LEO) và Highwater (HW). Dấu LEO lưu trữ phần bù của thông báo cuối cùng trong bản sao cục bộ và HW giữ phần bù của lần xác nhận cuối cùng. Hãy nhớ rằng đối với trạng thái cam kết, thông báo phải được duy trì trên tất cả các bản sao ISR. Điều này có nghĩa là LEO thường đi trước HW một chút.

Khi người lãnh đạo nhận được một tin nhắn, nó sẽ lưu nó cục bộ. Người theo dõi thực hiện yêu cầu tìm nạp bằng cách truyền LEO của mình. Sau đó, người lãnh đạo sẽ gửi một loạt tin nhắn bắt đầu từ LEO này và cũng truyền tải CTNH hiện tại. Khi người lãnh đạo nhận được thông tin rằng tất cả các bản sao đã lưu trữ thông báo ở khoảng cách nhất định, nó sẽ di chuyển dấu CTNH. Chỉ người lãnh đạo mới có thể di chuyển CTNH và vì vậy tất cả những người theo dõi sẽ biết giá trị hiện tại trong các phản hồi cho yêu cầu của họ. Điều này có nghĩa là những người theo dõi có thể tụt hậu so với người dẫn đầu về cả thông điệp và kiến ​​thức CTNH. Người tiêu dùng chỉ nhận được tin nhắn tối đa CTNH hiện tại.

Lưu ý rằng "kiên trì" có nghĩa là được ghi vào bộ nhớ chứ không phải vào đĩa. Về hiệu suất, Kafka đồng bộ hóa vào đĩa theo một khoảng thời gian cụ thể. RabbitMQ cũng có một khoảng thời gian như vậy, nhưng nó sẽ chỉ gửi xác nhận cho nhà xuất bản sau khi máy chủ chính và tất cả các máy nhân bản đã ghi thông báo vào đĩa. Các nhà phát triển Kafka, vì lý do hiệu suất, đã quyết định gửi xác nhận ngay khi tin nhắn được ghi vào bộ nhớ. Kafka đặt cược rằng sự dư thừa sẽ bù đắp rủi ro chỉ lưu trữ các thông điệp đã được xác nhận trong thời gian ngắn trong bộ nhớ.

Lãnh đạo thất bại

Khi một người chỉ huy bị ngã, Zookeeper sẽ thông báo cho bộ điều khiển và nó sẽ chọn một bản sao của người chỉ huy mới. Người lãnh đạo mới đặt ra dấu ấn CTNH mới theo LEO của mình. Những người theo dõi sau đó sẽ nhận được thông tin về người lãnh đạo mới. Tùy thuộc vào phiên bản Kafka, người theo dõi sẽ chọn một trong hai kịch bản:

  1. Nó sẽ cắt bớt nhật ký cục bộ thành một CTNH đã biết và gửi yêu cầu đến người lãnh đạo mới về các tin nhắn sau dấu này.
  2. Sẽ gửi yêu cầu cho trưởng nhóm tìm hiểu CTNH tại thời điểm anh ta được bầu làm lãnh đạo, sau đó cắt bớt nhật ký để bù đắp này. Sau đó nó sẽ bắt đầu thực hiện các yêu cầu tìm nạp định kỳ bắt đầu từ khoảng chênh lệch này.

Người theo dõi có thể cần cắt bớt nhật ký vì những lý do sau:

  • Khi người dẫn đầu thất bại, người theo dõi đầu tiên trong nhóm ISR đã đăng ký với Zookeeper sẽ thắng cuộc bầu cử và trở thành người dẫn đầu. Tất cả những người theo dõi trên ISR, mặc dù được coi là “đồng bộ” nhưng có thể không nhận được bản sao của tất cả tin nhắn từ người đứng đầu cũ. Hoàn toàn có khả năng người theo dõi nổi bật không có bản sao cập nhật nhất. Kafka đảm bảo rằng không có sự khác biệt giữa các bản sao. Vì vậy, để tránh sự khác biệt, mỗi người theo dõi phải cắt bớt nhật ký của mình theo giá trị CTNH của người lãnh đạo mới tại thời điểm bầu cử. Đây là một lý do khác tại sao việc thiết lập acks = tất cả rất quan trọng cho sự nhất quán.
  • Tin nhắn được định kỳ ghi vào đĩa. Nếu tất cả các nút cụm bị lỗi cùng một lúc thì các bản sao có độ lệch khác nhau sẽ được lưu trữ trên đĩa. Có thể khi các nhà môi giới trực tuyến trở lại, người lãnh đạo mới được bầu sẽ đứng sau những người theo dõi mình vì anh ta đã được lưu vào đĩa trước những người khác.

Đoàn tụ với cụm

Khi tham gia lại cụm, các bản sao thực hiện tương tự như khi người lãnh đạo thất bại: họ kiểm tra bản sao của người lãnh đạo và cắt bớt nhật ký của họ thành CTNH của nó (tại thời điểm bầu cử). Để so sánh, RabbitMQ coi các nút được hợp nhất là hoàn toàn mới. Trong cả hai trường hợp, nhà môi giới loại bỏ mọi trạng thái hiện có. Nếu sử dụng đồng bộ hóa tự động thì máy chủ phải sao chép hoàn toàn tất cả nội dung hiện tại sang máy nhân bản mới theo phương pháp “để cả thế giới chờ đợi”. Bản gốc không chấp nhận bất kỳ thao tác đọc hoặc ghi nào trong thao tác này. Cách tiếp cận này tạo ra vấn đề trong hàng đợi lớn.

Kafka là một nhật ký phân tán và nói chung nó lưu trữ nhiều tin nhắn hơn hàng đợi RabbitMQ, nơi dữ liệu sẽ bị xóa khỏi hàng đợi sau khi được đọc. Hàng đợi hoạt động nên duy trì ở mức tương đối nhỏ. Nhưng Kafka là một nhật ký có chính sách lưu giữ riêng, có thể đặt khoảng thời gian theo ngày hoặc tuần. Cách tiếp cận chặn hàng đợi và đồng bộ hóa hoàn toàn là hoàn toàn không thể chấp nhận được đối với nhật ký phân tán. Thay vào đó, những người theo dõi Kafka chỉ cần cắt bớt nhật ký của họ theo CTNH của người lãnh đạo (tại thời điểm ông ấy được bầu) nếu bản sao của họ dẫn trước người lãnh đạo. Trong trường hợp có nhiều khả năng xảy ra hơn, khi người theo dõi ở phía sau, nó chỉ cần bắt đầu thực hiện các yêu cầu tìm nạp bắt đầu bằng LEO hiện tại của nó.

Những người theo dõi mới hoặc tham gia lại bắt đầu bên ngoài ISR ​​và không tham gia vào các cam kết. Họ chỉ đơn giản là làm việc cùng với nhóm, nhận tin nhắn nhanh nhất có thể cho đến khi bắt kịp người lãnh đạo và vào ISR. Không cần khóa và không cần phải vứt bỏ tất cả dữ liệu của bạn.

Mất kết nối

Kafka có nhiều thành phần hơn RabbitMQ, do đó, nó có tập hợp hành vi phức tạp hơn khi cụm bị ngắt kết nối. Nhưng Kafka ban đầu được thiết kế cho các cụm nên các giải pháp được tính toán rất kỹ lưỡng.

Dưới đây là một số tình huống lỗi kết nối:

  • Tình huống 1: Người đi theo không nhìn thấy người dẫn đầu nhưng vẫn nhìn thấy Người quản lý vườn thú.
  • Tình huống 2: Người lãnh đạo không nhìn thấy người theo dõi nào nhưng vẫn nhìn thấy Người quản lý vườn thú.
  • Tình huống 3: Người đi theo nhìn thấy người dẫn đầu nhưng không nhìn thấy Người quản lý vườn thú.
  • Tình huống 4: Người lãnh đạo nhìn thấy những người đi theo nhưng không nhìn thấy Người trông coi vườn thú.
  • Kịch bản 5: Người theo dõi hoàn toàn tách biệt với cả các nút Kafka và Zookeeper khác.
  • Kịch bản 6: Nút dẫn đầu hoàn toàn tách biệt với cả các nút Kafka và Zookeeper khác.
  • Kịch bản 7: Nút điều khiển Kafka không thể nhìn thấy nút Kafka khác.
  • Kịch bản 8: Bộ điều khiển Kafka không thấy Zookeeper.

Mỗi kịch bản có hành vi riêng của nó.

Tình huống 1: Người theo dõi không nhìn thấy người dẫn đầu nhưng vẫn nhìn thấy Người quản lý vườn thú

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 22. Kịch bản 1: ISR của ba bản sao

Lỗi kết nối tách nhà môi giới 3 khỏi nhà môi giới 1 và 2, nhưng không tách biệt khỏi Zookeeper. Nhà môi giới 3 không thể gửi yêu cầu tìm nạp nữa. Sau khi thời gian trôi qua bản sao.lag.time.max.ms nó bị xóa khỏi ISR ​​và không tham gia vào quá trình xác nhận thông báo. Sau khi kết nối được khôi phục, nó sẽ tiếp tục các yêu cầu tìm nạp và tham gia ISR khi bắt kịp người dẫn đầu. Người quản lý vườn thú sẽ tiếp tục nhận được ping và cho rằng người môi giới vẫn sống khỏe mạnh.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 23. Kịch bản 1: Nhà môi giới bị xóa khỏi ISR ​​nếu không nhận được yêu cầu tìm nạp nào từ nó trong khoảng thời gian replica.lag.time.max.ms

Không có hệ thống treo phân chia não hoặc nút như trong RabbitMQ. Thay vào đó, sự dư thừa được giảm bớt.

Tình huống 2: Leader không thấy người theo dõi nhưng vẫn thấy Zookeeper

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 24. Tình huống 2. Người lãnh đạo và hai người theo sau

Sự cố kết nối mạng sẽ ngăn cách người dẫn đầu với những người theo dõi, nhưng người môi giới vẫn có thể nhìn thấy Zookeeper. Như trong kịch bản đầu tiên, ISR thu hẹp lại, nhưng lần này chỉ dành cho người dẫn đầu vì tất cả những người theo dõi đều ngừng gửi yêu cầu tìm nạp. Một lần nữa, không có sự phân chia hợp lý. Thay vào đó, sẽ mất đi tính dư thừa đối với các tin nhắn mới cho đến khi kết nối được khôi phục. Người quản lý vườn thú tiếp tục nhận được ping và tin rằng người môi giới vẫn sống khỏe mạnh.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 25. Kịch bản 2. ISR chỉ thu hẹp lại ở vị trí dẫn đầu

Tình huống 3. Người theo dõi nhìn thấy người dẫn đầu nhưng không nhìn thấy Người quản lý vườn thú

Người theo dõi được tách khỏi Zookeeper, nhưng không tách khỏi người môi giới với người dẫn đầu. Kết quả là người theo dõi tiếp tục thực hiện các yêu cầu tìm nạp và là thành viên của ISR. Zookeeper không còn nhận được ping và đăng ký sự cố của nhà môi giới, nhưng vì nó chỉ là người theo dõi nên không có hậu quả gì sau khi khôi phục.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 26. Tình huống 3: Người theo dõi tiếp tục gửi yêu cầu tìm nạp đến người lãnh đạo

Tình huống 4. Người lãnh đạo nhìn thấy những người theo dõi nhưng không nhìn thấy Người quản lý vườn thú

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 27. Tình huống 4. Người lãnh đạo và hai người theo sau

Người lãnh đạo bị tách khỏi Zookeeper, nhưng không tách khỏi những người môi giới có người theo dõi.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 28. Kịch bản 4: Người lãnh đạo bị cô lập khỏi Zookeeper

Sau một thời gian, Zookeeper sẽ đăng ký lỗi môi giới và thông báo cho bộ điều khiển về lỗi đó. Anh ta sẽ chọn một nhà lãnh đạo mới trong số những người theo anh ta. Tuy nhiên, người đứng đầu ban đầu sẽ tiếp tục nghĩ rằng đó là người đứng đầu và sẽ tiếp tục chấp nhận các mục từ acks=1. Những người theo dõi không còn gửi cho anh ấy các yêu cầu tìm nạp nữa, vì vậy anh ấy sẽ coi họ đã chết và cố gắng thu nhỏ ISR về chính nó. Nhưng vì nó không có kết nối với Zookeeper nên nó sẽ không thể thực hiện việc này và tại thời điểm đó sẽ từ chối chấp nhận bất kỳ mục nhập nào khác.

Tin nhắn acks = tất cả sẽ không nhận được xác nhận vì ISR trước tiên bật tất cả các bản sao và tin nhắn không đến được với chúng. Khi người lãnh đạo ban đầu cố gắng xóa họ khỏi ISR, nó sẽ không thể thực hiện được và sẽ ngừng chấp nhận bất kỳ tin nhắn nào.

Khách hàng sẽ sớm nhận thấy sự thay đổi về người đứng đầu và bắt đầu gửi hồ sơ đến máy chủ mới. Sau khi mạng được khôi phục, đường dẫn đầu ban đầu sẽ thấy rằng nó không còn là đường dẫn đầu nữa và cắt bớt nhật ký của nó thành giá trị CTNH mà đường dẫn đầu mới có tại thời điểm không tránh được sự phân kỳ nhật ký. Sau đó nó sẽ bắt đầu gửi yêu cầu tìm nạp đến người lãnh đạo mới. Tất cả các bản ghi từ nhà lãnh đạo ban đầu không được sao chép sang nhà lãnh đạo mới sẽ bị mất. Nghĩa là, những tin nhắn không được người lãnh đạo ban đầu thừa nhận trong vài giây khi hai người lãnh đạo đang làm việc sẽ bị mất.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 29. Kịch bản 4. Người lãnh đạo ở nhà môi giới 1 trở thành người theo dõi sau khi mạng được khôi phục

Kịch bản 5: Người theo dõi hoàn toàn tách biệt với cả các nút Kafka và Zookeeper khác

Người theo dõi hoàn toàn bị cô lập với cả các nút Kafka và Zookeeper khác. Anh ta chỉ cần rời khỏi ISR ​​cho đến khi mạng được khôi phục và sau đó bắt kịp những người khác.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 30. Kịch bản 5: Người theo dõi bị cô lập bị xóa khỏi ISR

Kịch bản 6: Nút dẫn đầu hoàn toàn tách biệt với cả các nút Kafka và Zookeeper khác

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 31. Tình huống 6. Người lãnh đạo và hai người theo sau

Người lãnh đạo hoàn toàn bị cô lập với những người theo dõi mình, người kiểm soát và Người trông coi vườn thú. Trong một thời gian ngắn nó sẽ tiếp tục chấp nhận các mục từ acks=1.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 32. Kịch bản 6: Cô lập người lãnh đạo khỏi các nút Kafka và Zookeeper khác

Không nhận được yêu cầu sau khi hết hạn bản sao.lag.time.max.ms, nó sẽ cố gắng thu nhỏ ISR về chính nó, nhưng sẽ không thể làm được điều đó vì không có liên lạc với Zookeeper, khi đó nó sẽ ngừng nhận ghi.

Trong khi đó, Zookeeper sẽ đánh dấu người môi giới bị cô lập là đã chết và người kiểm soát sẽ bầu ra một người lãnh đạo mới.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 33. Kịch bản 6. Hai nhà lãnh đạo

Người lãnh đạo ban đầu có thể chấp nhận các mục trong vài giây nhưng sau đó ngừng chấp nhận bất kỳ tin nhắn nào. Khách hàng được cập nhật cứ sau 60 giây với siêu dữ liệu mới nhất. Họ sẽ được thông báo về sự thay đổi người lãnh đạo và sẽ bắt đầu gửi bài viết cho người lãnh đạo mới.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 34. Kịch bản 6: Nhà sản xuất chuyển sang người dẫn đầu mới

Tất cả các mục được xác nhận bởi người đứng đầu ban đầu kể từ khi mất kết nối sẽ bị mất. Sau khi mạng được khôi phục, người lãnh đạo ban đầu sẽ phát hiện ra thông qua Zookeeper rằng họ không còn là người lãnh đạo nữa. Sau đó, nó sẽ cắt bớt nhật ký của mình đối với CTNH của người lãnh đạo mới tại thời điểm bầu cử và bắt đầu gửi yêu cầu với tư cách là người theo dõi.

RabbitMQ vs Kafka: Khả năng chịu lỗi và tính sẵn sàng cao
Cơm. 35. Tình huống 6: Người lãnh đạo ban đầu trở thành người theo sau sau khi kết nối mạng được khôi phục

Trong trường hợp này, sự phân tách logic có thể xảy ra trong một khoảng thời gian ngắn, nhưng chỉ khi acks=1 и min.insync.replicas Ngoài ra 1. Sự phân tách logic sẽ tự động kết thúc sau khi mạng được khôi phục, khi người lãnh đạo ban đầu nhận ra rằng mình không còn là người lãnh đạo nữa hoặc khi tất cả khách hàng nhận ra rằng người lãnh đạo đã thay đổi và bắt đầu viết thư cho người lãnh đạo mới - tùy điều kiện nào xảy ra trước. Trong mọi trường hợp, một số tin nhắn sẽ bị mất, nhưng chỉ với acks=1.

Có một biến thể khác của tình huống này, ngay trước khi mạng bị chia tách, những người theo dõi đã bị tụt lại phía sau và người lãnh đạo đã nén ISR về chỉ mình mình. Sau đó nó bị cô lập do mất kết nối. Một người lãnh đạo mới được bầu, nhưng người lãnh đạo ban đầu vẫn tiếp tục chấp nhận các mục, thậm chí acks = tất cả, bởi vì không có ai khác ở ISR ngoại trừ anh ấy. Những bản ghi này sẽ bị mất sau khi mạng được khôi phục. Cách duy nhất để tránh tùy chọn này là min.insync.replicas = 2.

Kịch bản 7: Nút điều khiển Kafka không thể nhìn thấy nút Kafka khác

Nói chung, khi mất kết nối với nút Kafka, bộ điều khiển sẽ không thể truyền bất kỳ thông tin thay đổi người lãnh đạo nào tới nút đó. Trong trường hợp xấu nhất, điều này sẽ dẫn đến sự tách biệt logic ngắn hạn, như trong kịch bản 6. Thông thường, nhà môi giới sẽ không trở thành ứng cử viên cho vị trí lãnh đạo nếu người sau thất bại.

Kịch bản 8: Bộ điều khiển Kafka không thấy Zookeeper

Zookeeper sẽ không nhận được ping từ bộ điều khiển bị rơi và sẽ chọn nút Kafka mới làm bộ điều khiển. Bộ điều khiển ban đầu có thể tiếp tục hiển thị như vậy nhưng nó không nhận được thông báo từ Zookeeper nên sẽ không có bất kỳ nhiệm vụ nào để thực hiện. Sau khi mạng được khôi phục, anh ta sẽ nhận ra rằng mình không còn là người điều khiển nữa mà đã trở thành một nút Kafka thông thường.

Kết luận từ các tình huống

Chúng tôi thấy rằng việc mất kết nối của người theo dõi không dẫn đến mất tin nhắn mà chỉ tạm thời giảm mức độ dư thừa cho đến khi mạng được khôi phục. Tất nhiên, điều này có thể dẫn đến mất dữ liệu nếu một hoặc nhiều nút bị mất.

Nếu người lãnh đạo bị tách khỏi Zookeeper do mất kết nối, điều này có thể dẫn đến việc mất tin nhắn từ acks=1. Việc thiếu liên lạc với Zookeeper gây ra sự chia rẽ logic trong thời gian ngắn giữa hai nhà lãnh đạo. Vấn đề này được giải quyết bằng tham số acks = tất cả.

Thông số min.insync.replicas thành hai hoặc nhiều bản sao cung cấp sự đảm bảo bổ sung rằng các tình huống ngắn hạn như vậy sẽ không dẫn đến mất tin nhắn như trong Kịch bản 6.

Tổng hợp tin nhắn bị mất

Hãy liệt kê tất cả các cách bạn có thể mất dữ liệu trong Kafka:

  • Bất kỳ lỗi chỉ huy nào nếu thông báo được xác nhận bằng cách sử dụng acks=1
  • Bất kỳ sự chuyển đổi lãnh đạo không trong sạch nào, nghĩa là sang một người theo sau bên ngoài ISR, ngay cả với acks = tất cả
  • Cô lập người lãnh đạo khỏi Zookeeper nếu tin nhắn được xác nhận bằng cách sử dụng acks=1
  • Cô lập hoàn toàn người lãnh đạo đã thu nhỏ nhóm ISR xuống còn chính mình. Tất cả tin nhắn sẽ bị mất, thậm chí acks = tất cả. Điều này chỉ đúng nếu min.insync.replicas=1.
  • Lỗi đồng thời của tất cả các nút phân vùng. Vì các tin nhắn được xác nhận từ bộ nhớ nên một số tin nhắn có thể chưa được ghi vào đĩa. Sau khi khởi động lại máy chủ, một số tin nhắn có thể bị thiếu.

Có thể tránh được sự chuyển tiếp lãnh đạo không trong sạch bằng cách cấm chúng hoặc đảm bảo ít nhất hai sự dư thừa. Cấu hình bền nhất là sự kết hợp acks = tất cả и min.insync.replicas trên 1.

So sánh trực tiếp độ tin cậy của RabbitMQ và Kafka

Để đảm bảo độ tin cậy và tính sẵn sàng cao, cả hai nền tảng đều triển khai hệ thống sao chép chính và phụ. Tuy nhiên, RabbitMQ có gót chân Achilles. Khi kết nối lại sau khi bị lỗi, các nút sẽ loại bỏ dữ liệu của chúng và quá trình đồng bộ hóa bị chặn. Điều khó khăn gấp đôi này đặt ra câu hỏi về tuổi thọ của hàng đợi lớn trong RabbitMQ. Bạn sẽ phải chấp nhận giảm bớt sự dư thừa hoặc thời gian chặn dài. Giảm sự dư thừa làm tăng nguy cơ mất dữ liệu lớn. Nhưng nếu hàng đợi nhỏ thì để dự phòng, có thể xử lý các khoảng thời gian không sẵn sàng ngắn (vài giây) bằng cách thử kết nối lặp đi lặp lại.

Kafka không gặp phải vấn đề này. Nó chỉ loại bỏ dữ liệu từ điểm khác biệt giữa người dẫn đầu và người theo sau. Tất cả dữ liệu được chia sẻ sẽ được lưu. Ngoài ra, việc sao chép không chặn hệ thống. Người lãnh đạo tiếp tục chấp nhận các bài đăng trong khi người theo dõi mới bắt kịp, vì vậy đối với các nhà phát triển, việc tham gia hoặc tham gia lại cụm trở thành một nhiệm vụ tầm thường. Tất nhiên, vẫn còn những vấn đề như băng thông mạng trong quá trình sao chép. Nếu bạn thêm nhiều người theo dõi cùng lúc, bạn có thể gặp phải giới hạn băng thông.

RabbitMQ vượt trội hơn Kafka về độ tin cậy khi nhiều máy chủ trong một cụm bị lỗi cùng một lúc. Như chúng tôi đã nói, RabbitMQ chỉ gửi xác nhận cho nhà xuất bản sau khi thông báo được ghi vào đĩa bởi máy chủ và tất cả máy nhân bản. Nhưng điều này làm tăng thêm độ trễ vì hai lý do:

  • fsync cứ sau vài trăm mili giây
  • Lỗi của máy nhân bản chỉ có thể được nhận thấy sau khi thời gian tồn tại của các gói kiểm tra tính khả dụng của mỗi nút (tick mạng) đã hết hạn. Nếu gương chạy chậm lại hoặc rơi xuống, điều này sẽ tạo thêm độ trễ.

Kafka đặt cược rằng nếu một tin nhắn được lưu trữ trên nhiều nút, nó có thể xác nhận tin nhắn ngay khi chúng chạm vào bộ nhớ. Vì điều này, có nguy cơ mất bất kỳ loại tin nhắn nào (thậm chí acks = tất cả, min.insync.replicas=2) trong trường hợp xảy ra sự cố đồng thời.

Nhìn chung, Kafka thể hiện hiệu suất phần mềm tốt hơn và được thiết kế ngay từ đầu cho các cụm. Số lượng người theo dõi có thể tăng lên 11 nếu cần thiết để đảm bảo độ tin cậy. Hệ số sao chép 5 và số lượng bản sao tối thiểu trong đồng bộ hóa min.insync.replicas=3 sẽ làm cho việc mất tin nhắn trở thành một sự kiện rất hiếm gặp. Nếu cơ sở hạ tầng của bạn có thể hỗ trợ tỷ lệ sao chép và mức độ dự phòng này thì bạn có thể chọn tùy chọn này.

Phân cụm RabbitMQ phù hợp với các hàng đợi nhỏ. Nhưng ngay cả những hàng đợi nhỏ cũng có thể tăng lên nhanh chóng khi có lưu lượng giao thông đông đúc. Khi hàng đợi ngày càng lớn, bạn sẽ phải đưa ra những lựa chọn khó khăn giữa tính khả dụng và độ tin cậy. Phân cụm RabbitMQ phù hợp nhất cho các tình huống không điển hình trong đó lợi ích về tính linh hoạt của RabbitMQ lớn hơn bất kỳ nhược điểm nào của việc phân cụm.

Một giải pháp giải quyết lỗ hổng của RabbitMQ đối với hàng đợi lớn là chia chúng thành nhiều hàng đợi nhỏ hơn. Nếu bạn không yêu cầu sắp xếp thứ tự đầy đủ cho toàn bộ hàng đợi mà chỉ yêu cầu các tin nhắn có liên quan (ví dụ: tin nhắn từ một khách hàng cụ thể) hoặc không yêu cầu bất kỳ thứ gì, thì tùy chọn này có thể được chấp nhận: hãy xem dự án của tôi Bộ cân bằng lại để phân chia hàng đợi (dự án vẫn đang ở giai đoạn đầu).

Cuối cùng, đừng quên một số lỗi trong cơ chế phân cụm và sao chép của cả RabbitMQ và Kafka. Theo thời gian, các hệ thống đã trở nên hoàn thiện và ổn định hơn, nhưng sẽ không có tin nhắn nào an toàn 100% khỏi bị mất! Ngoài ra, tai nạn quy mô lớn còn xảy ra ở các trung tâm dữ liệu!

Nếu tôi bỏ sót điều gì đó, mắc lỗi hoặc bạn không đồng ý với bất kỳ điểm nào, vui lòng viết nhận xét hoặc liên hệ với tôi.

Tôi thường được hỏi: “Chọn gì, Kafka hay RabbitMQ?”, “Nền tảng nào tốt hơn?”. Sự thật là nó thực sự phụ thuộc vào tình huống, kinh nghiệm hiện tại của bạn, v.v. Tôi ngần ngại đưa ra ý kiến ​​của mình vì sẽ quá đơn giản hóa nếu đề xuất một nền tảng cho tất cả các trường hợp sử dụng và những hạn chế có thể xảy ra. Tôi viết loạt bài này để các bạn có thể đưa ra quan điểm của riêng mình.

Tôi muốn nói rằng cả hai hệ thống đều dẫn đầu trong lĩnh vực này. Tôi có thể hơi thiên vị vì theo kinh nghiệm của tôi với các dự án, tôi có xu hướng coi trọng những thứ như thứ tự tin nhắn được đảm bảo và độ tin cậy.

Tôi thấy các công nghệ khác thiếu độ tin cậy và trật tự được đảm bảo, sau đó tôi xem xét RabbitMQ và Kafka và nhận ra giá trị đáng kinh ngạc của cả hai hệ thống này.

Nguồn: www.habr.com

Thêm một lời nhận xét