Redis和消息中間件


轉載:

http://www.jianshu.com/p/477618203a97

什么是消息中間件

先看百科:消息中間件利用高效可靠的消息傳遞機制進行平台無關的數據交流,並基於數據通信來進行分布式系統的集成。通過提供消息傳遞和消息排隊模型,它可以在分布式環境下擴展進程間的通信。
我們來看幾個關鍵點:
消息 消息中間件定義了一個協議(模型),基於該協議可以傳遞消息
分布式 消息中間件的引入是為了解決分布式系統的問題,對於簡單的單應用系統用不着
舉例來說,一個常見的最簡單的UGC應用,至少包括后端、APP、審核后台、統計平台)。UGC應用的生命力在於用戶產生內容的質量,所以需要審核用戶提交的內容;另一方面,需要統計用戶產生內容的數據。用戶A產生的內容C在系統間的流動路徑是這樣的,APP -> 后端 -> 審核 -> 統計,其中審核和統計可以同時進行,這就遇到了各系統間的數據通信問題。簡單的解決方案是所有的系統公用一套數據庫(單庫或者集群,總之數據庫結構一樣)。這樣的好處是實現簡單,可靠;壞處是沒有關注平台間的差異性,不同平台需要的數據結構不一樣,通用的數據庫容易造成各個平台都達不到最好的性能,比如統計需要對所有數據進行計算;另外各個系統之間在數據庫發生了耦合,在統計和審核過程中產生的垃圾SQL可能影響在線的業務。引入消息中間件作為各個系統間通信大使可以有效的解決上述問題:數據在后端產生后,可以扔到消息中間件,其余需要這個數據的系統訂閱改消息中間件就可以拿到這條數據並進行自己業務內的操作。這樣做的最大好處是系統隔離,系統之間不互相影響,縮小問題的影響范圍,避免問題的連鎖反應——把三個容易出問題的系統綁在一起,出問題的概率不止提升了三倍!
消息中間件就像是快遞員,把東西給我,告訴我送給誰,你忙你的去吧。

消息中間件的衡量標准

消息中間件的三大要素:生產者(Producer)、消息(Message)、消費者(Consumer)。衡量標准基本圍繞這三者的交互,這里只說我在選擇消息中間件的時候常用的。

消息路由 消息如何經過消息中間件到達消費者,在一定程度上決定了消息中間件的靈活性。簡單的命名隊列,TOPIC訂閱能滿足大部分的場景,對於復雜的業務可能需要比如基於PATTERN的路由(RabbitMQ),消息復制,消息生命周期管理(beanstalk)。

消息可靠性 大部分場景下消息是容忍丟失的,或者說對性能的渴求大於可靠性,比如異步發短信,異步發郵件,概數數據統計,日志等。另外有的場景是不允許消息丟失的,消息的丟失會帶來數據的不一致,不一致的數據很多時候是災難的開始,比如異步寫數據,下單后減庫存,轉賬等。可靠性基本都依賴於持久化。

消息重放 不常用但是很有用。這個說的是即使是消費過的消息也能設定offset(一般是時間點)重新消費。這個功能在消息下游數據丟失,新系統導入舊數據的時候非常有用,不用再去理繁雜的數據對應關系,按照正常的業務邏輯處理消息就OK了,非常好用!非常好用!非常好用!

消息堆積 抗流量神技。像雙十一這種超高峰流量都會用到這個功能,這時候一方面會把消息中間件下游業務(Consumer端)的機器挪到核心業務,另一方面消息中間件在高並發投遞消息的時候可能出問題,所以把消息暫存在中間件,等流量高峰過去了再投遞到下游業務。
分布式集群支持 高可用的需求,解決單點問題。

ACK 消息確認,在下游業務確認后才將消息標記為已消費,處理超時則重新投遞消息,這里要求下游業務自己做可重入(冪等)

消息順序 有的業務要求消息投遞順序和消費順序一致,或者至少要求對於單個用戶順序一致,比如用戶的贊/取消操作,順序反了數據就會錯亂

性能和擴展 這里指的擴展是能否通過增加Consumer來提高消息的消費速率以及消息中間件的容量是否有理論的上線;性能主要指tps、qps以及並發連接數。

消息協議 優先考慮標准協議或者使用廣泛的協議,有利於后期的維護和擴展

Redis作為消息中間件

Redis自帶的PUB/SUB機制,即發布-訂閱模式。這種模式生產者(producer)和消費者(consumer)是1-M的關系,即一條消息會被多個消費者消費,當只有一個消費者時即可以看做一個1-1的消息隊列,但這種方式並不適合題主的場景。首先,數據可靠性的無法保障,題主的數據最終需要落庫,如果消息丟失、Redis宕機部分數據沒有持久化甚至突然的網絡抖動都可能帶來數據的丟失,應該是無法忍受的。其次,擴展不靈活,沒法通過多加consumer來加快消費的進度,如果前端寫入數據太多,同步會比較慢,數據不同步的狀態越久,風險越大,可以通過channel拆分的方式來解決,雖然不靈活,但可以規避。這種方案更適合於對數據可靠性要求不高,比如一些統計日志打點。
Redis的PUSH/POP機制,利用的Redis的列表(lists)數據結構。比較好的使用模式是,生產者lpush消息,消費者brpop消息,並設定超時時間,可以減少redis的壓力。這種方案相對於第一種方案是數據可靠性提高了,只有在Redis宕機且數據沒有持久化的情況下丟失數據,可以根據業務通過AOF和縮短持久化間隔來保證很高的可靠性,而且也可以通過多個client來提高消費速度。但相對於專業的消息隊列來說,該方案消息的狀態過於簡單(沒有狀態),且沒有ack機制,消息取出后消費失敗依賴於client記錄日志或者重新push到隊列里面。

關於

本文首發自 架構小站,轉載請注明,歡迎關注。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM