MQ對比之RabbitMQ & Redis

消息隊列選擇:RabbitMQ & Redisgit

RabbitMQ

RabbitMQ是一個由erlang開發的AMQP(Advanced Message Queue )的開源實現的產品,RabbitMQ是一個消息代理,從「生產者」接收消息並傳遞消息至「消費者」,期間可根據規則路由、緩存、持久化消息。「生產者」也即message發送者如下簡稱P,相對應的「消費者」乃message接收者如下簡稱C,message經過queue由P到C,queue存在於RabbitMQ,可存儲儘量多的message,多個P可向同一queue發送message,多個C可從同一個queue接收message

RabbitMQ架構:github

img

組件:golang

  • Message (消息):RabbitMQ 轉發的二進制對象,包括Headers(頭)、Properties (屬性)和 Data (數據),其中數據部分不是必要的;
  • Producer(生產者): 消息的生產者,負責產生消息並把消息發到交換機Exhange的應用;
  • Consumer (消費者):使用隊列 Queue 從 Exchange 中獲取消息的應用;
  • Exchange (交換機):負責接收生產者的消息並把它轉到到合適的隊列;
  • Queue (隊列):一個存儲Exchange 發來的消息的緩衝,並將消息主動發送給Consumer,或者 Consumer 主動來獲取消息。
  • Binding (綁定):隊列 和 交換機 之間的關係。Exchange 根據消息的屬性和 Binding 的屬性來轉發消息。綁定的一個重要屬性是 binding_key。
  • Connection (鏈接)和 Channel (通道):生產者和消費者須要和 RabbitMQ 創建 TCP 鏈接。一些應用須要多個connection,爲了節省TCP 鏈接,可使用 Channel,它能夠被認爲是一種輕型的共享 TCP 鏈接的鏈接。鏈接須要用戶認證,而且支持 TLS (SSL)。鏈接須要顯式關閉。

Redis

Redis 是徹底開源免費的,遵照BSD協議,是一個高性能的key-value數據庫。數據庫

Redis 與其餘 key - value 緩存產品有如下三個特色:ubuntu

  • Redis支持數據的持久化,能夠將內存中的數據保存在磁盤中,重啓的時候能夠再次加載進行使用。
  • Redis不只僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
  • Redis支持數據的備份,即master-slave模式的數據備份。

Redis 優點

  • 性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
  • 豐富的數據類型 – Redis支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操做。
  • 原子 – Redis的全部操做都是原子性的,意思就是要麼成功執行要麼失敗徹底不執行。單個操做是原子性的。多個操做也支持事務,即原子性,經過MULTI和EXEC指令包起來。
  • 豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過時等等特性。

首先Redis的設計是用來作緩存的,可是因爲它自身的某種特性使得他能夠用來作消息隊列(Redis的List數據結構比較適合作MQ)。它有幾個阻塞式的API可使用,正是這些阻塞式的API讓他有作消息隊列的能力。 另外作消息隊列的其餘特性,例如FIFO也很容易實現,只須要一個list對象從頭取數據,從尾部塞數據便可實現。 Redis能作消息隊列得益於它的list對象blpop brpop接口以及Pub/Sub(發佈/訂閱)的某些接口。他們都是阻塞版的,因此能夠用來作消息隊列。緩存

RabbitMQ和Redis的簡單對比

RabbitMQ和Redis均可以作隊列,可是他們仍是有區別的。好比,Redis的消息隊列,若是在從隊列pop出去的時候,worker處理失敗的話,數據不會回到隊列中,須要從業務中手動把失敗的處理數據push到隊列中;而RabbitMQ能夠自動處理失敗的worker使數據不丟失;RabbitMQ還能夠保證數據在傳輸過程當中持久化,在通道和隊列中的數據能夠設置爲持久化。首先Redis嚴格來講並非消息隊列,它是一個內存數據庫,不過由於其某些特性適合用來充當隊列,因此也多被用於作簡單的mq, Redis之父卻是開發了個真正的消息隊列disque,有興趣能夠看看。數據結構

相比起Redis,RabbitMQ有更加完善的MQ機制,這裏咱們僅討論消息的durable(持久性),後續一系列其餘機制有時間再交流。架構

RabbitMQ有一個消息確認機制來保證消息的不丟失:客戶端從隊列中取出消息以後,可能須要一段時間才能處理完成,若是在這個過程當中,客戶端出錯了,異常退出了,而數據尚未處理完成,那麼很是不幸,這段數據就丟失了,由於RabbitMQ默認會把此消息標記爲已完成,而後從隊列中移除,消息確認是客戶端從RabbitMQ中取出消息,並處理完成以後,會發送一個ack告訴RabbitMQ,消息處理完成,當RabbitMQ收到客戶端的獲取消息請求以後,或標記爲處理中,當再次收到ack以後,纔會標記爲已完成,而後從隊列中刪除。當RabbitMQ檢測到客戶端和本身斷開連接以後,還沒收到ack,則會從新將消息放回消息隊列,交給下一個客戶端處理,保證消息不丟失,也就是說,RabbitMQ給了客戶端足夠長的時間來作數據處理。性能

RabbitMQ demo之生產者消費者

生產者

img

消費者(不發送ack,模擬程序中斷)

imgno-ack = False,若是消費者遇到狀況(its channel is closed, connection is closed, or TCP connection is lost)掛掉了,那麼,RabbitMQ會從新將該任務添加到隊列中。spa

正常發送ack的消費者:

img發送ack則被認爲是正常消費message的consumer,則RabbitMQ會把message從隊列中移除,此時再看隊列中已經沒有消息。

關於RabbitMQ的其餘features,如 Publish/Subscribe、Routing、Topics和RPC等,有興趣能夠Google。除了RabbitMQ除了Python的實踐外,也可考慮其餘語言的實踐,這裏提供另一個語言golang的選擇,可參考Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳實踐,這個文章講的很是詳盡,實踐意義比較具備參考價值,有興趣能夠閱覽一番。

相關文章
相關標籤/搜索