Môi giới tin nhắn truyền thống và truyền dữ liệu


13

Theo trang web Kafka :

" Kakfa được sử dụng để xây dựng các đường ống dữ liệu thời gian thực và các ứng dụng phát trực tuyến. "

Tìm kiếm trên internet rất xa, tôi đã tìm thấy định nghĩa được chấp nhận chung sau đây về " dữ liệu truyền phát " là gì:

  • Luồng dữ liệu là dữ liệu chảy liên tục từ nguồn đến đích qua mạng; và
  • Luồng dữ liệu về bản chất không phải là nguyên tử, có nghĩa là bất kỳ phần nào của luồng dữ liệu đang chảy đều có ý nghĩa và có thể xử lý, trái ngược với tệp có byte không có nghĩa gì trừ khi bạn có tất cả chúng; và
  • Dữ liệu truyền phát có thể được bắt đầu / dừng bất cứ lúc nào; và
  • Người tiêu dùng có thể đính kèm và tách ra khỏi luồng dữ liệu theo ý muốn và chỉ xử lý các phần của dữ liệu mà họ muốn

Bây giờ, nếu bất cứ điều gì tôi nói ở trên là không chính xác, không đầy đủ hoặc hoàn toàn sai, hãy bắt đầu bằng cách sửa lỗi cho tôi! Giả sử tôi ít nhiều đi đúng hướng, thì ...

Bây giờ tôi đã hiểu "truyền dữ liệu" là gì, sau đó tôi hiểu Kafka và Kinesis có nghĩa là gì khi họ tự lập hóa đơn là phần mềm trung gian xử lý / môi giới cho các ứng dụng có dữ liệu truyền phát. Nhưng nó đã khơi gợi những sở thích của tôi: có thể / nên "truyền phát phần mềm trung gian" như Kafka hay Kinesis cho dữ liệu không phát trực tuyến, như các nhà môi giới tin nhắn truyền thống không? Và ngược lại: các MQ truyền thống như RabbitMQ, ActiveMQ, Apollo, v.v ... có thể được sử dụng để truyền dữ liệu không?

Chúng ta hãy lấy một ví dụ trong đó một ứng dụng sẽ gửi hàng loạt các thông điệp JSON cần được xử lý và quá trình xử lý khá phức tạp (xác thực, chuyển đổi dữ liệu, lọc, tổng hợp, v.v.):

  • Trường hợp # 1: Các thông điệp là mỗi khung hình của một bộ phim; đó là một hành lý JSON trên mỗi khung hình video chứa dữ liệu khung và một số siêu dữ liệu hỗ trợ
  • Trường hợp 2: Các tin nhắn là dữ liệu chuỗi thời gian, có lẽ nhịp tim của ai đó là một chức năng của thời gian. Vì vậy, Tin nhắn số 1 được gửi đại diện cho nhịp tim của tôi tại t = 1, Tin nhắn số 2 chứa nhịp tim của tôi tại t = 2, v.v.
  • Trường hợp # 3: Dữ liệu hoàn toàn khác nhau và không liên quan theo thời gian hoặc là một phần của bất kỳ "luồng dữ liệu" nào. Có lẽ các sự kiện kiểm toán / bảo mật được kích hoạt khi hàng trăm người dùng điều hướng các nút bấm của ứng dụng và thực hiện các hành động

Dựa trên cách Kafka / Kinesis được lập hóa đơn và theo hiểu biết của tôi về "dữ liệu phát trực tuyến" là gì, chúng dường như là ứng cử viên rõ ràng cho Trường hợp # 1 (dữ liệu video liền kề) và # 2 (dữ liệu chuỗi thời gian liền kề). Tuy nhiên tôi không thấy bất kỳ lý do nào khiến một nhà môi giới tin nhắn truyền thống như RabbitMQ không thể xử lý hiệu quả cả hai đầu vào này.

Và với Trường hợp # 3, chúng tôi chỉ được cung cấp một sự kiện đã xảy ra và chúng tôi cần xử lý phản ứng với sự kiện đó. Vì vậy, với tôi điều này nói lên việc cần một nhà môi giới truyền thống như RabbitMQ. Nhưng cũng không có lý do tại sao bạn không thể yêu cầu Kafka hoặc Kinesis xử lý dữ liệu sự kiện.

Về cơ bản, tôi đang tìm cách thiết lập một phiếu tự đánh giá: Tôi có dữ liệu X với các đặc điểm Y. Tôi nên sử dụng bộ xử lý luồng như Kafka / Kinesis để xử lý nó. Hoặc ngược lại, một thứ giúp tôi xác định: Tôi có dữ liệu W với các đặc điểm Z. Tôi nên sử dụng một nhà môi giới tin nhắn truyền thống để xử lý nó.

Vì vậy, tôi hỏi: Những yếu tố nào về dữ liệu (hoặc nói cách khác) giúp điều khiển quyết định giữa bộ xử lý luồng hoặc nhà môi giới tin nhắn, vì cả hai đều có thể xử lý dữ liệu truyền phát và cả hai có thể xử lý dữ liệu tin nhắn (không phát trực tuyến)?

Câu trả lời:


5

Kafka giao dịch trong các bản ghi nhật ký của các thông điệp nguyên tử. Bạn có thể xem nó giống như pub/subchế độ của các nhà môi giới tin nhắn, nhưng với thứ tự nghiêm ngặt và khả năng phát lại hoặc tìm kiếm xung quanh dòng tin nhắn tại bất kỳ thời điểm nào trong quá khứ vẫn được giữ lại trên đĩa (có thể là mãi mãi).

Hương vị phát trực tuyến của Kafka trái ngược với cuộc gọi thủ tục từ xa như Thrift hoặc HTTP và xử lý hàng loạt như trong hệ sinh thái Hadoop. Không giống như RPC, các thành phần giao tiếp không đồng bộ: giờ hoặc ngày có thể trôi qua giữa khi tin nhắn được gửi và khi người nhận thức dậy và hành động trên nó. Có thể có nhiều người nhận tại các thời điểm khác nhau, hoặc có thể không ai sẽ bận tâm để tiêu thụ một tin nhắn. Nhiều nhà sản xuất có thể sản xuất cùng một chủ đề mà không có kiến ​​thức của người tiêu dùng. Kafka không biết liệu bạn đã đăng ký hay chưa, hoặc một tin nhắn đã được sử dụng chưa. Một thông điệp chỉ đơn giản là cam kết với nhật ký, nơi mà bất kỳ bên quan tâm nào cũng có thể đọc nó.

Không giống như xử lý hàng loạt, bạn quan tâm đến các thư đơn lẻ, không chỉ các bộ sưu tập thư khổng lồ. (Mặc dù không có gì lạ khi lưu trữ các tin nhắn Kafka vào các tệp Parquet trên HDFS và truy vấn chúng dưới dạng bảng Hive).

Trường hợp 1 : Kafka không bảo tồn bất kỳ mối quan hệ tạm thời cụ thể nào giữa người sản xuất và người tiêu dùng. Đó là một sự phù hợp nghèo cho streaming video vì Kafka được phép làm chậm, tăng tốc độ, di chuyển trong phù hợp và bắt đầu, vv Đối với phương tiện truyền thông, chúng tôi muốn từ bỏ những tổng thông lượng để đổi lấy thấp và, quan trọng hơn, ổn định độ trễ (nếu không được gọi là jitter thấp). Kafka cũng rất đau đớn để không bao giờ mất tin nhắn. Với truyền phát video, chúng tôi thường sử dụng UDP và là nội dung để thả khung ở đây và ở đó để giữ cho video chạy. SLA trên quy trình được Kafka hỗ trợ thường là vài giây đến vài phút khi khỏe mạnh, hàng giờ đến vài ngày khi khỏe mạnh. SLA trên phương tiện truyền thông trực tuyến là trong hàng chục mili giây.

Netflix có thể sử dụng Kafka để di chuyển các khung hình trong một hệ thống nội bộ có thể chuyển mã terabyte video mỗi giờ và lưu nó vào đĩa, nhưng không gửi chúng đến màn hình của bạn.

Trường hợp 2 : Hoàn toàn. Chúng tôi sử dụng Kafka theo cách này tại chủ nhân của tôi.

Trường hợp 3 : Bạn có thể sử dụng Kafka cho loại điều này, và chúng tôi làm, nhưng bạn đang trả một số chi phí không cần thiết để duy trì việc đặt hàng. Vì bạn không quan tâm đến trật tự, có lẽ bạn có thể tạo ra một số hiệu suất cao hơn từ hệ thống khác. Tuy nhiên, nếu công ty của bạn đã duy trì một cụm Kafka, có lẽ tốt nhất là sử dụng lại nó thay vì chịu trách nhiệm bảo trì của một hệ thống nhắn tin khác.


1
Cảm ơn @closeparen (+1) - Tôi nhận được hầu hết những gì bạn nói, với một ngoại lệ lớn. Trong đoạn văn của bạn bắt đầu bằng câu " Hương vị phát trực tuyến của Kafka trái ngược ... ", tôi có xu hướng nghĩ rằng tôi có thể thay thế hầu hết các trường hợp của từ "Kafka" bằng "RabbitMQ", và câu này sẽ đúng. Đối với RabbitMQ: các nhà sản xuất có thể gửi tin nhắn và người tiêu dùng sẽ kéo nó xuống và xử lý nó hàng giờ / ngày sau đó. Người tiêu dùng có thể đính kèm vào hàng đợi bất cứ lúc nào họ thích và vì vậy đối với RabbitMQ, có thể có nhiều người nhận khác nhau tại các thời điểm khác nhau.
smeeb

1
Hãy nghĩ về Kafka giống như một công cụ cơ sở dữ liệu với cấu trúc hướng log đặc biệt. Nhà sản xuất nối, người tiêu dùng đọc. Đọc sách không ảnh hưởng đến trạng thái của Kafka theo bất kỳ cách nào. Một người tiêu dùng có thể duy trì một con trỏ tăng dần để tạo ra ngữ nghĩa giống hệt với pub / sub của RabbitMQ và đây là trường hợp sử dụng phổ biến, nhưng đó không phải là trường hợp sử dụng duy nhất.
closeparen

1
Hãy nghĩ về RabbitMQ giống như một phiên bản phân tán của cấu trúc dữ liệu hàng đợi trong bộ nhớ. Khi bạn bật một cái gì đó ra khỏi hàng đợi, nó không còn trên hàng đợi nữa. Chắc chắn, bạn có thể có một cấu trúc liên kết trong đó nó được sao chép sang các hàng đợi khác vì lợi ích của người tiêu dùng khác, nhưng bạn thường không thể nói "cho tôi tin nhắn tôi đã xử lý 500 tin nhắn trước đây" hoặc "bắt đầu xếp hàng B dưới dạng bản sao của Queue A từ nơi Queue A là ngày hôm qua. "
closeparen

2
Một hệ thống dựa trên Kafka đang tha thứ. Nếu bạn không thích cách chương trình của bạn hoạt động, bạn có thể đẩy một thay đổi mã và sau đó tua lại đầu vào của nó. Bạn có thể ngăn người tiêu dùng RabbitMQ mà không ảnh hưởng đến nhà sản xuất, nhưng bạn sẽ không thể xem lại quá khứ.
closeparen

1
Ahhh: bóng đèn: cảm ơn (+1 cho cả 3)! Vì vậy, đây chắc chắn là một trường hợp hấp dẫn cho Kafka: khả năng xem lại quá khứ. Tôi cho rằng phải có một số giới hạn trên hoặc cắt ngắn đang diễn ra phải không? Nếu không thì trí nhớ của Kafka sẽ luôn luôn trèo lên. Ngay cả khi dữ liệu tràn vào đĩa, các tệp nơi lưu trữ dữ liệu chủ đề sẽ lấp đầy đĩa rất nhanh, đúng không?
smeeb

5

Kafka / Kinesis được mô hình hóa như một luồng. Một luồng có các thuộc tính khác với tin nhắn.

  • Các luồng có bối cảnh cho họ. Họ có trật tự. Bạn có thể áp dụng các chức năng cửa sổ trên các luồng. Mặc dù mỗi mục trong một luồng đều có ý nghĩa, nhưng nó có thể có ý nghĩa hơn với bối cảnh xung quanh nó
  • Vì các luồng có thứ tự, bạn có thể sử dụng điều đó để đưa ra các tuyên bố nhất định về ngữ nghĩa của xử lý. Ví dụ, Apache Trident được cho là có ngữ nghĩa chính xác một lần khi tiêu thụ từ luồng Kafka.
  • Bạn có thể áp dụng các chức năng cho các luồng. Bạn có thể chuyển đổi một luồng mà không thực sự tiêu thụ nó. Bạn có thể lười biếng tiêu thụ một luồng. Bạn có thể bỏ qua các phần của một luồng.
  • Bạn vốn có thể phát lại các luồng trong Kafka, nhưng bạn không thể (không có phần mềm bổ sung) phát lại hàng đợi tin nhắn. Điều này hữu ích khi bạn thậm chí không biết bạn muốn làm gì với dữ liệu. Nó cũng hữu ích cho việc đào tạo AI.

Nói chung, sử dụng Kafka để xử lý luồng ngoại tuyến, sử dụng hàng đợi tin nhắn cho tin nhắn máy chủ-máy khách thời gian thực.

Các trường hợp sử dụng ví dụ từ pivotal :

Kafka: Theo dõi hoạt động của trang web, Số liệu, Tổng hợp nhật ký, Xử lý luồng, Tìm nguồn cung cấp sự kiện và Nhật ký cam kết

RabbitMQ: nhắn tin cho mục đích chung ..., thường được sử dụng để cho phép các máy chủ web phản hồi nhanh chóng các yêu cầu thay vì bị buộc phải thực hiện các thủ tục nặng về tài nguyên trong khi người dùng chờ kết quả. Sử dụng khi bạn cần sử dụng các giao thức hiện có như AMQP 0-9-1, STOMP, MQTT, AMQP 1.0

Đôi khi nó có thể hữu ích để sử dụng cả hai! Ví dụ, trong Trường hợp sử dụng số 2, nếu đây là luồng dữ liệu từ người tạo tốc độ, tôi sẽ có người tạo tốc độ truyền dữ liệu nhịp tim đến hàng đợi tin nhắn RabbitMQ (sử dụng giao thức tuyệt vời như MQTT), nơi nó được xử lý ngay lập tức xem nếu trái tim của nguồn vẫn đang đập. Điều này có thể cung cấp năng lượng cho bảng điều khiển và hệ thống phản ứng khẩn cấp. Hàng đợi tin nhắn cũng sẽ gửi dữ liệu chuỗi thời gian vào Kafka để chúng tôi có thể phân tích dữ liệu nhịp tim theo thời gian. Ví dụ, chúng tôi có thể thực hiện một thuật toán để phát hiện bệnh tim bằng cách nhận thấy các xu hướng trong luồng nhịp tim.


1
Cảm ơn @Samuel (+1) - đây là một câu trả lời tuyệt vời và giúp đưa mọi thứ vào bối cảnh tốt hơn một chút. Tôi thực sự có một vài câu hỏi tiếp theo cho bạn (nếu bạn không phiền), nhưng tất cả chúng đều có bản lề / phụ thuộc vào một sự làm rõ ban đầu mà tôi cần: khi bạn nói " Bạn có thể áp dụng các chức năng cho các luồng. Bạn có thể chuyển đổi một luồng mà không thực sự tiêu thụ nó ... ", những chức năng / biến đổi đó có được thực thi trên Kafka hay chúng cần được tiêu thụ trước khi luồng được xử lý thông qua chức năng / biến đổi?
smeeb

1
Có nghĩa là, bạn có KafkaProducer, KafkaKafkaConsumer. Giả sử KafkaProducercuộc sống bên trong một ứng dụng Java và nó KafkaConsumerđang chạy trên một số ứng dụng / phụ trợ Ruby. KafkaProducergửi Message1đến Kafka cần được chuyển đổi qua Function1. Nơi nào Function1của mã sống? Trên Kafka (thích hợp) hoặc bên trong KafkaConsumer(ứng dụng Ruby)?
smeeb

2
Bạn không thể thực thi các chức năng hoặc thực hiện bất kỳ xử lý nào trong chính Kafka. Apache Spark Streaming và Apache Storm là hai khung xử lý luồng phân tán có thể tiêu thụ từ Kafka. Họ chạy bên ngoài Kafka và kết nối với nó như thể đó là một cơ sở dữ liệu. Các khung công tác hiển thị các chức năng hữu ích như chia tách, tổng hợp, cửa sổ, v.v. Bạn có thể triển khai các chức năng cơ bản trong người tiêu dùng Ruby của mình, nhưng tôi rất khuyến nghị một trong các khung. spark.apache.org/flowing bão.apache.org/release/ 2.0.0
Samuel

1
OK, cảm ơn và +1 lần nữa - điều đó sẽ rất tuyệt vời nếu Kafka có thể tự xử lý các luồng! Vì vậy, để chơi người ủng hộ quỷ dữ, bạn không thể có một người tiêu dùng RabbitMQ kéo các tin nhắn ra khỏi hàng đợi, tổng hợp chúng dựa trên dấu thời gian (hoặc thực sự là bất kỳ tiêu chí / thuộc tính nào khác) và thực hiện cùng một cửa sổ và chuyển đổi các chức năng thành dữ liệu Spark Truyền phát hay Storm cung cấp?
smeeb

1
Có, tôi nghĩ rằng bạn có thể làm điều đó với RabbitMQ vì RabbitMQ đảm bảo về thứ tự tin nhắn. Bạn có thể không làm được với mỗi hàng đợi tin nhắn. Và nó sẽ phức tạp để xây dựng. Ví dụ: nếu người tiêu dùng RabbitMQ của bạn đang gặp sự cố thì sao? Với Kafka, bạn có thể theo dõi nơi bạn đã xử lý luồng, vì vậy bạn có thể bắt đầu người tiêu dùng của mình tại điểm bạn rời đi
Samuel
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.