Message Queue 簡單介紹與比較

Larry Lai Lv1

Message Queue

Message Queue 訊息佇列,既然資料結構如其名是 Queue,那麼 FIFO 先進先出的概念就得先了解。存放於 Queue 中的即是 Message。

主要用途在於提供 不同Process不同Thread 或是在微服務中各個 Service 之間的訊息溝通

MQ_Process

Application Intergration

在一個系統中,一般不會只有一隻程式在運作,而是會有多隻程式同時負責各種不同的任務,而程式之間難免會有互相傳遞資料進行處理的需求,而這類的需求,以下都統稱為 applcation 的整合。

  • File Based Intergration

    Application 根據要處理的任務,產生檔案到特定的路徑。其中任務成功或失敗可以存放到不同 folder 中。而其他接收訊息的 application(或稱 process application) 則是不停監控該路徑有沒有新檔案產生,有則取出檔案進行處理。

  • Shared Database Intergration

    1. source application 收到新任務時,將資料寫入 db 中
    2. process application 監聽的對象從路徑中的檔案換成 database,若有新資料則進行處理
    3. process application 處理後將狀態寫回 db 中
  • Direct Connection Intergration

    1. source application 直接傳訊息給 process application
    2. 可能透過 TCP/IP 或是 named pipe connection 的方式傳遞資料
    3. 傳遞資訊的資料格式並沒有限制,由連線兩端的 application 自訂,可以是純文字、XML 或 JSON。
  • Asynchronous Message Broker (Message Queue)

    1. 不限傳遞資料格式
    2. 需要額外 message queue middleware 協助,也會被稱作 message broker 或 message bus
    3. message broker 收到來自 source application 的訊息後,會轉發給 process application,而在這方式中,source application 與 process application 通常又各自被稱為 producer 與 consumer。

特性 & 優勢

Message Queue 最重要的能力在於非同步的特性,因為 Producers 發送訊息時不需即刻得到 Response 便可繼續執行其他事情。

之於非同步的特性伴隨著的優勢便是解耦(Decouple),開發人員就可以專心負責在屬於自己的區塊進行工作。除此之外 Producer 無需清楚 Consumer 的實際位置(IP Address 等等),只需要將資料送往 Message Queue 就好,剩下的事情 Message Broker 會根據設定自行處理掉。

再來高可用性,例如叢集的高可用性,當 Master 處於異常狀態時,會轉由 Slave 進行代理繼續提供服務。以確保服務的運行來提供叢集的高可用性。另外則是資料的高可用性,當 Message 送至 Queue 但服務發生異常(如 Consumer 消失時),資料仍然可等到 Consumer 重新上線時再進行推送(Push)或是被拉取(Pull),直到 Message 被正確消耗後會發出 Ack (Acknowledgement) 確認通知之後 Message 則會消失。

最後則是 Scaling 擴展,如果突然遭遇大的流量,此時 queue 就提供了一個 buffer 的功能,能夠緩衝尖峰流量,在資源固定的情況下,能夠處理更多的任務,以時間換取資源! 但有時訊息可能真的太多,產生的速度快於消耗的速度,或是你無法接受太長的 latency,此時 consumer process 就可以隨時增加多個,不會有衝突的風險

另外,先進先出的佇列資料結構也直接確保了資料的有序性。

Use Case

  • 延遲問題不重要的工作

    寄送郵件這類工作,使用者可以接受信晚個幾秒,幾十秒甚至幾分鐘到時。意即資料不是由使用者寫入,使用者也不曉得資料何時應該要出現,延遲問題就不是那麼重要。

  • 大量運算的工作

    比如說 image resizing 或是 video encoding 這類 CPU intensive 的工作,一來是使用者上傳完圖片影片,可能不需要等到這類都做完了你才跟他說 ok,二來是你也不會想讓這類工作 block 住或拖垮你的 web server 的效能.

  • 無法控制的工作

    當你的工作需要協調許多資源才能完成時,有機會因為其中一個資源負載過重因而造成整個工作變得極度緩慢,尤其資源是外部的,所以你無法控制的時候。

Kafka 與 RabbitMQ 的抉擇

比較兩者之前應該先了解 Message Queue 分成兩種:

  1. Memory Based
  2. Log Based
  • Memory Based (RabbitMQ)

    • Message 是存放於 Memory
    • Consumer 發出 Ack(Acknowledgement) 確認 Message 取得後 Broker 則會直接刪除 Message
    • Message 傳送方式是推送(Push)
  • Log Based (Kafka)

    • Message 進入後會直接寫到硬碟上,Consumer 消耗訊息時則是讀取檔案,直到讀到檔案資料的盡頭,接著繼續等候下一次通知。
    • Message 傳送方式為拉取(Pull)

Log Based 的讀寫速度限制則可透過將 topic 的 log 進行分區來進行改善,每個分區(Partition)由一台機器負責,並可獨立讀寫。

了解了兩種基底的 MQ 差異後,接著了解他們兩者特性上的差異。

先以簡易的比較表概括:

特性 RabbitMQ Kafka
Load Balancing Yes Yes, but limited
Fan-out Yes, through exchange binding Yes
Persistence Yes, through configuration Yes
Inorder delivery Yes, conditionally yes, per partition
  • Load Balancing(負載平衡)

    • Memory based

      自然地 support 了 load balancing,當有 message 時, broker 輪流地向跟他有建立連結的 consumer 推送信息,就達成了 load balancing 的效果, 越多 consumer,就可以平行處理越多的工作。

    • Log based

      需透過方才提到的 Partition 方法來達成 load balancing。
      例如一個 topic,並且將此 topic 的 partition 分成三份,此時就可以 assign 三個 consumer 給他。感覺上像是一個 topic 的 message 被提供給三個 consumer 拉取。但實際上則是每個 partition 對應到一個 consumer,便實現了平行處理,意即達到負載平衡。

  • Fan-Out(扇形發送)

    • Memory based

      需要透過額外的設計才能達成,透過 AMQP 協議的 exchange binding 可以實現 pub-sub。

    • Log based

      本身即為 fan-out,每個 consumer 對 log 檔案想讀哪就讀哪,想重複讀幾次就讀幾次

  • Persistence(持續性)

    • Memory based

      可透過設置將 Message 寫入硬碟作為 Backup 時使用,但僅保存到 Consumer 成功消耗之前。

    • Log based

      每個 message 都會寫入硬碟,除非刪掉它,否則會一直存在。

  • Inorder delivery(有序發送)

    • Memory based

      無法保證 message 一個一個按照順序的被處理,除非每一個 topic 只有一個 consumer。

    • Log based

      每個 partition 上的 message,一定是被 consumer 有序讀取,但不同 partition 之間就沒有順序的保證,他們理論上是各自獨立的。

最終選擇誰

需考慮下列三點

  1. 資料是否需要被保存?

    • 需要保存鐵定是選擇 log based 的 MQ,也就是 Kafka。
  2. 資料有序性是否重要?

    • 針對系統開發的面向判斷是否需要維持資料的有序性,如果需要的話則需要選擇 Log Based。但這也僅限於同一個 Partition,若不同的話則無法保證順序。
  3. 工作耗損是否昂貴?

    • log based 受限於需要多個 partition 來實現負載平衡來提升讀寫速度,建設上較為昂貴。
    • 同個 Partition 只要 Message 過多容易消耗更多時間,最後造成堵塞。
  • 標題: Message Queue 簡單介紹與比較
  • 作者: Larry Lai
  • 撰寫于 : 2023-11-25 09:19:28
  • 更新于 : 2024-07-17 17:01:39
  • 連結: https://redefine.ohevan.com/2023/11/25/message-queue-introduce/
  • 版權宣告: 本作品采用 CC BY-NC-SA 4.0 进行许可。
 留言