Pialang Pesan Tradisional dan Data Streaming

13

Menurut situs Kafka :

" Kakfa digunakan untuk membangun pipa data real-time dan aplikasi streaming. "

Menelusuri internet jauh dan luas, saya telah menemukan definisi " aliran data " yang diterima secara umum sebagai berikut :

  • Data aliran adalah data yang mengalir secara berdekatan dari sumber ke tujuan melalui jaringan; dan
  • Data stream tidak bersifat atomik, artinya setiap bagian dari aliran data yang mengalir adalah bermakna dan dapat diproses, sebagai lawan dari file yang byte-nya tidak berarti apa-apa kecuali Anda memiliki semuanya; dan
  • Data aliran dapat dimulai / dihentikan kapan saja; dan
  • Konsumen dapat melampirkan dan melepaskan dari aliran data sesuka hati, dan memproses hanya bagian-bagiannya yang mereka inginkan

Nah, jika apa pun yang saya katakan di atas salah, tidak lengkap, atau sepenuhnya salah, silakan mulai dengan mengoreksi saya! Dengan asumsi saya kurang lebih di jalur, maka ...

Sekarang saya mengerti apa itu "streaming data", kemudian saya mengerti apa yang dimaksud Kafka dan Kinesis ketika mereka menagih diri mereka sebagai pemrosesan / perantara middleware untuk aplikasi dengan streaming data. Tapi itu menggelitik minat saya: bisakah / haruskah "streaming middleware" seperti Kafka atau Kinesis digunakan untuk data non-streaming, seperti pialang pesan tradisional? Dan sebaliknya: dapat / haruskah MQ tradisional seperti RabbitMQ, ActiveMQ, Apollo, dll digunakan untuk streaming data?

Mari kita ambil contoh di mana aplikasi akan mengirimkan rentetan pesan JSON backend konstan yang perlu diproses, dan pemrosesannya cukup kompleks (validasi, transformasi data, pemfilteran, agregasi, dll.):

  • Kasus # 1: Pesannya adalah setiap bingkai film; itu adalah satu pesan JSON per bingkai video yang berisi data bingkai dan beberapa metadata pendukung
  • Kasus # 2: Pesannya adalah data deret waktu, mungkin detak jantung seseorang sebagai fungsi waktu. Jadi Pesan # 1 dikirim mewakili detak jantung saya di t = 1, Pesan # 2 berisi detak jantung saya di t = 2, dll.
  • Kasus # 3: Data sepenuhnya berlainan dan tidak terkait oleh waktu atau sebagai bagian dari "aliran data" apa pun. Mungkin mengaudit / peristiwa keamanan yang dipecat ketika ratusan pengguna menavigasi tombol mengklik aplikasi dan mengambil tindakan

Berdasarkan bagaimana Kafka / Kinesis ditagih dan pada pemahaman saya tentang apa "streaming data" itu, mereka tampaknya menjadi kandidat yang jelas untuk Kasus # 1 (data video yang berdekatan) dan # 2 (data seri waktu yang berdekatan). Namun saya tidak melihat alasan mengapa broker pesan tradisional seperti RabbitMQ tidak bisa secara efisien menangani kedua input ini juga.

Dan dengan Kasus # 3, kami hanya disediakan dengan peristiwa yang telah terjadi dan kami perlu memproses reaksi terhadap peristiwa itu. Jadi bagi saya ini berbicara dengan membutuhkan broker tradisional seperti RabbitMQ. Tetapi juga tidak ada alasan mengapa Anda tidak bisa meminta Kafka atau Kinesis menangani pemrosesan data acara.

Jadi pada dasarnya, saya ingin membuat rubrik yang mengatakan: Saya memiliki data X dengan karakteristik Y. Saya harus menggunakan prosesor aliran seperti Kafka / Kinesis untuk menanganinya. Atau, sebaliknya, yang membantu saya menentukan: Saya memiliki data W dengan karakteristik Z. Saya harus menggunakan broker pesan tradisional untuk menanganinya.

Jadi saya bertanya: Faktor-faktor apa tentang data (atau sebaliknya) yang membantu mengarahkan keputusan antara stream processor atau broker pesan, karena keduanya dapat menangani data streaming, dan keduanya dapat menangani data pesan (non-streaming)?

smeeb
sumber

Jawaban:

5

Penawaran Kafka dalam log pesan atom yang dipesan. Anda dapat melihatnya seperti pub/submode pialang pesan, tetapi dengan pemesanan yang ketat dan kemampuan untuk memutar ulang atau mencari di sekitar aliran pesan di setiap titik di masa lalu yang masih disimpan di disk (yang bisa selamanya).

Rasa streaming Kafka bertentangan dengan panggilan prosedur jarak jauh seperti Thrift atau HTTP, dan untuk pemrosesan batch seperti di ekosistem Hadoop. Tidak seperti RPC, komponen berkomunikasi secara tidak sinkron: berjam-jam atau berhari-hari dapat berlalu antara saat pesan dikirim dan ketika penerima bangun dan bertindak di atasnya. Mungkin ada banyak penerima pada waktu yang berbeda, atau mungkin tidak ada yang mau repot-repot mengonsumsi pesan. Beberapa produsen dapat menghasilkan topik yang sama tanpa sepengetahuan konsumen. Kafka tidak tahu apakah Anda berlangganan, atau apakah pesan telah dikonsumsi. Sebuah pesan hanya dikomit ke log, di mana pihak yang berkepentingan dapat membacanya.

Tidak seperti pemrosesan batch, Anda tertarik pada satu pesan, bukan hanya koleksi besar pesan. (Meskipun tidak jarang mengarsipkan pesan Kafka ke file Parket di HDFS dan meminta mereka sebagai tabel Hive).

Kasus 1 : Kafka tidak mempertahankan hubungan temporal tertentu antara produsen dan konsumen. Ini kurang pas untuk streaming video karena Kafka dibiarkan melambat, mempercepat, bergerak pas dan mulai, dll. Untuk streaming media, kami ingin menukar throughput keseluruhan dengan imbalan rendah, dan yang lebih penting, latensi stabil (jika tidak dikenal sebagai jitter rendah). Kafka juga bersusah payah untuk tidak pernah kehilangan pesan. Dengan streaming video, kami biasanya menggunakan UDP dan konten untuk menjatuhkan bingkai di sana-sini agar video tetap berjalan. SLA pada proses yang didukung Kafka biasanya detik hingga menit saat sehat, jam ke hari saat sehat. SLA pada media streaming dalam puluhan milidetik.

Netflix dapat menggunakan Kafka untuk memindahkan bingkai di dalam sistem internal yang mentranskode terabyte video per jam dan menyimpannya ke disk, tetapi tidak untuk mengirimnya ke layar Anda.

Kasus 2 : Tentu saja. Kami menggunakan Kafka dengan cara ini di majikan saya.

Kasus 3 : Anda dapat menggunakan Kafka untuk hal semacam ini, dan kami melakukannya, tetapi Anda membayar beberapa biaya tidak perlu untuk menjaga pemesanan. Karena Anda tidak peduli tentang pesanan, Anda mungkin bisa memeras kinerja lebih banyak dari sistem lain. Namun, jika perusahaan Anda sudah memiliki cluster Kafka, mungkin lebih baik menggunakannya kembali daripada menanggung beban pemeliharaan sistem pesan lain.

closeparen
sumber
1
Terima kasih @closeparen (+1) - Saya mendapatkan sebagian besar dari apa yang Anda katakan, dengan satu pengecualian besar. Dalam paragraf Anda yang diawali dengan kalimat " Citarasa streaming Kafka bertentangan ... ", saya cenderung berpikir saya bisa mengganti sebagian besar kata "Kafka" dengan "RabbitMQ", dan kalimat itu akan tetap berlaku. Untuk RabbitMQ: produsen dapat mengirim pesan dan konsumen akan menariknya dan memprosesnya berjam-jam / hari sesudahnya. Konsumen dapat melampirkan antrian kapan saja mereka mau, dan untuk RabbitMQ, ada banyak penerima yang berbeda pada titik waktu yang berbeda.
smeeb
1
Pikirkan Kafka seperti mesin basis data dengan struktur berorientasi log yang aneh. Produsen menambahkan, konsumen membaca. Membaca tidak mempengaruhi keadaan Kafka dengan cara apa pun. Seorang konsumen dapat mempertahankan kursor yang meningkat untuk membuat semantik yang identik dengan RabbitMQ pub / sub, dan ini adalah kasus penggunaan umum, tetapi itu bukan satu-satunya kasus penggunaan.
closeparen
1
Pikirkan RabbitMQ seperti versi terdistribusi dari struktur data antrian dalam memori. Setelah Anda menghapus sesuatu dari antrian, itu tidak lagi berada di antrian. Tentu, Anda mungkin memiliki topologi di mana ia direplikasi ke antrian lain untuk kepentingan konsumen lain, tetapi Anda biasanya tidak akan bisa mengatakan "beri saya pesan yang saya tangani 500 pesan yang lalu" atau "mulai Antrian B sebagai salinan dari Antrian A dari tempat Antrian A kemarin. "
closeparen
2
Sistem berbasis Kafka memaafkan. Jika Anda tidak suka dengan perilaku program Anda, Anda bisa mendorong perubahan kode dan kemudian memundurkan inputnya. Anda dapat menghentikan konsumen RabbitMQ tanpa mempengaruhi produsen, tetapi Anda tidak akan dapat mengunjungi kembali masa lalu.
closeparen
1
Ahhh: bola lampu: terima kasih (+1 untuk semua 3)! Jadi ini jelas merupakan kasus yang menarik bagi Kafka: kemampuan untuk meninjau kembali masa lalu. Saya berasumsi harus ada batas atas atau pemotongan yang terjadi kan? Kalau tidak, ingatan Kafka akan selalu naik. Bahkan jika data tumpah ke disk, file di mana data topik disimpan akan mengisi disk dengan sangat cepat, ya?
smeeb
5

Kafka / Kinesis dimodelkan sebagai aliran. Aliran memiliki properti yang berbeda dari pesan.

  • Streaming memiliki konteks untuk mereka. Mereka punya pesanan. Anda dapat menerapkan fungsi jendela pada streaming. Meskipun setiap item dalam aliran bermakna, mungkin lebih bermakna dengan konteks di sekitarnya
  • Karena stream memiliki urutan, Anda dapat menggunakannya untuk membuat pernyataan tertentu tentang semantik pemrosesan. Misalnya Apache Trident seharusnya memiliki semantik yang persis sekali ketika mengkonsumsi dari aliran Kafka.
  • Anda dapat menerapkan fungsi ke streaming. Anda dapat mengubah aliran tanpa benar-benar mengonsumsinya. Anda dapat dengan malas mengonsumsi aliran. Anda dapat melewati bagian dari aliran.
  • Secara inheren Anda dapat memutar ulang streaming di Kafka, tetapi Anda tidak dapat (tanpa perangkat lunak tambahan) antrean pesan ulangan. Ini berguna ketika Anda bahkan belum tahu apa yang ingin Anda lakukan dengan data tersebut. Ini juga berguna untuk melatih AI.

Secara umum, gunakan Kafka untuk pemrosesan aliran offline, gunakan antrian pesan untuk pesan klien-server real-time.

Contoh penggunaan case dari pivotal :

Kafka: Pelacakan Aktivitas Situs Web, Metrik, Agregasi Log, Pemrosesan Streaming, Pengadaan Acara, dan Log Komit

RabbitMQ: pesan keperluan umum ..., sering digunakan untuk memungkinkan server web menanggapi permintaan dengan cepat alih-alih dipaksa untuk melakukan prosedur sumber daya yang berat sementara pengguna menunggu hasilnya. Gunakan saat Anda perlu menggunakan protokol yang ada seperti AMQP 0-9-1, STOMP, MQTT, AMQP 1.0

Terkadang mungkin bermanfaat untuk menggunakan keduanya! Misalnya dalam Use Case # 2, jika ini adalah aliran data dari pembuat kecepatan katakan, saya akan meminta pembuat kecepatan mengirimkan data detak jantung ke antrian pesan RabbitMQ (menggunakan protokol keren seperti MQTT) di mana ia segera diproses untuk lihat apakah sumber jantungnya masih berdetak. Ini bisa memberi daya pada dashboard dan sistem respons darurat. Antrian pesan juga akan menyimpan data deret waktu ke Kafka sehingga kami dapat menganalisis data detak jantung seiring waktu. Sebagai contoh, kita mungkin menerapkan algoritma untuk mendeteksi penyakit jantung dengan memperhatikan tren dalam aliran detak jantung.

Samuel
sumber
1
Terima kasih @Samuel (+1) - ini adalah jawaban yang bagus dan membantu menempatkan segala sesuatu ke dalam konteks sedikit lebih baik. Saya sebenarnya memiliki beberapa pertanyaan lanjutan untuk Anda (jika Anda tidak keberatan), tetapi mereka semua bergantung / bergantung pada satu klarifikasi awal yang saya butuhkan: ketika Anda mengatakan " Anda dapat menerapkan fungsi ke stream. Anda dapat mengubah aliran tanpa benar-benar mengonsumsinya ... ", apakah fungsi / transformasi tersebut dijalankan pada Kafka , atau apakah mereka perlu dikonsumsi terlebih dahulu sebelum stream diproses melalui fungsi / transformasi?
smeeb
1
Artinya, sudah KafkaProducer, Kafkadan KafkaConsumer. Katakanlah KafkaProducertinggal di dalam aplikasi Java, dan itu KafkaConsumerberjalan di beberapa aplikasi / backend Ruby. KafkaProducermengirim Message1ke Kafka yang perlu diubah melalui Function1. Di mana Function1kode hidup? Di Kafka (benar) atau di dalam KafkaConsumer(aplikasi Ruby)?
smeeb
2
Anda tidak dapat menjalankan fungsi atau melakukan pemrosesan apa pun di Kafka sendiri. Apache Spark Streaming dan Apache Storm adalah dua kerangka kerja pemrosesan aliran terdistribusi yang dapat mengkonsumsi dari Kafka. Mereka menjalankan di luar Kafka dan menyambungkannya seolah-olah itu adalah database. Kerangka kerja mengekspos fungsi-fungsi yang berguna seperti pemisahan, agregasi, windowing, dll. Anda bisa mengimplementasikan fungsi dasar di konsumen Ruby Anda, tetapi saya akan sangat merekomendasikan salah satu kerangka kerja. spark.apache.org/streaming storm.apache.org/releases/2.0.0-SNAPSHOT/Trident-tutorial.html
Samuel
1
OK, terima kasih dan +1 lagi - itu akan sangat luar biasa, meskipun jika Kafka dapat melakukan pemrosesan pada stream itu sendiri! Jadi untuk berperan sebagai advokat iblis, tidak bisakah Anda meminta konsumen RabbitMQ menarik pesan dari antrian, mengumpulkannya berdasarkan stempel waktu (atau benar-benar kriteria / atribut lainnya), dan melakukan jendela yang sama dan mentransformasikan fungsi ke data yang memicu Streaming atau Storm menyediakan?
smeeb
1
Ya saya pikir Anda bisa melakukannya dengan RabbitMQ karena RabbitMQ memiliki jaminan tentang pesanan pesan. Anda mungkin tidak dapat melakukannya dengan setiap antrian pesan. Dan itu akan rumit untuk dibangun. Misalnya bagaimana jika konsumen RabbitMQ Anda yang melakukan agregasi mengalami gangguan? Dengan Kafka, Anda dapat melacak di mana dalam aliran yang telah Anda proses hingga, sehingga Anda dapat memulai konsumen Anda pada titik yang Anda tinggalkan
Samuel