1. 程式人生 > >Redis系列(三)—— Redis和訊息中介軟體

Redis系列(三)—— Redis和訊息中介軟體

轉載:

什麼是訊息中介軟體

先看百科:訊息中介軟體利用高效可靠的訊息傳遞機制進行平臺無關的資料交流,並基於資料通訊來進行分散式系統的整合。通過提供訊息傳遞和訊息排隊模型,它可以在分散式環境下擴充套件程序間的通訊。
我們來看幾個關鍵點:
訊息 訊息中介軟體定義了一個協議(模型),基於該協議可以傳遞訊息
分散式 訊息中介軟體的引入是為了解決分散式系統的問題,對於簡單的單應用系統用不著
舉例來說,一個常見的最簡單的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到佇列裡面。

關於

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