分布式訊息系統作為實現分布式系統可擴充套件,可伸縮性的關鍵元件,需要具有高吞吐量,高可用等特定,而談到訊息系統的設計,就迴避不了兩個問題:
1 訊息的順序問題
2 訊息的重複問題
rocketmq作為阿里開源的一款高效能、高吞吐量的訊息中介軟體,它是怎樣來解決這兩個問題的?rocketmq 有哪些關鍵特性?其實現原理是怎樣的?
一、順序訊息
訊息有序指的是可以按照訊息的傳送順序來消費。例如:一筆訂單產生了 3 條訊息,分別是訂單建立、訂單付款、訂單完成。消費時,要按照順序依次消費才有意義。與此同時多筆訂單之間又是可以並行消費的。首先來看如下示例:
假如生產者產生了2條訊息:m1、m2,要保證這兩條訊息的順序,應該怎樣做?你腦中想到的可能是這樣:
假定m1傳送到s1,m2傳送到s2,如果要保證m1先於m2被消費,那麼需要m1到達消費端被消費後,通知s2,然後s2再將m2傳送到消費端。
這個模型存在的問題是,如果m1和m2分別傳送到兩台server上,就不能保證m1先達到mq集群,也不能保證m1被先消費。換個角度看,如果m2先於m1達到mq集群,甚至m2被消費後,m1才達到消費端,這時訊息也就亂序了,說明以上模型是不能保證訊息的順序的。如何才能在mq集群保證訊息的順序?一種簡單的方式就是將m1、m2傳送到同乙個server上:
這樣可以保證m1先於m2到達mqserver(生產者等待m1傳送成功後再傳送m2),根據先達到先被消費的原則,m1會先於m2被消費,這樣就保證了訊息的順序。
這個模型也僅僅是理論上可以保證訊息的順序,在實際場景中可能會遇到下面的問題:
只要將訊息從一台伺服器發往另一台伺服器,就會存在網路延遲問題。如上圖所示,如果傳送m1耗時大於傳送m2的耗時,那麼m2就仍將被先消費,仍然不能保證訊息的順序。即使m1和m2同時到達消費端,由於不清楚消費端1和消費端2的負載情況,仍然有可能出現m2先於m1被消費的情況。
那如何解決這個問題?將m1和m2發往同乙個消費者,且傳送m1後,需要消費端響應成功後才能傳送m2。
聰明的你可能已經想到另外的問題:如果m1被傳送到消費端後,消費端1沒有響應,那是繼續傳送m2呢,還是重新傳送m1?一般為了保證訊息一定被消費,肯定會選擇重發m1到另外乙個消費端2,就如下圖所示。
這樣的模型就嚴格保證訊息的順序,細心的你仍然會發現問題,消費端1沒有響應server時有兩種情況,一種是m1確實沒有到達(資料在網路傳送中丟失),另外一種消費端已經消費m1且已經傳送響應訊息,只是mq server端沒有收到。如果是第二種情況,重發m1,就會造成m1被重複消費。也就引入了我們要說的第二個問題,訊息重複問題,這個後文會詳細講解
回過頭來看訊息順序問題,嚴格的順序訊息非常容易理解,也可以通過文中所描述的方式來簡單處理。總結起來,要實現嚴格的順序訊息,簡單且可行的辦法就是:
保證有些問題,看起來很重要,但實際上我們可以通過合理的設計或者將問題分解來規避。如果硬要把時間花在解決問題本身,實際上不僅效率低下,而且也是一種浪費。從這個角度來看訊息的順序問題,我們可以得出兩個結論:生產者 - mqserver - 消費者
是一對一對一的關係這樣的設計雖然簡單易行,但也會存在一些很嚴重的問題,比如:
並行度就會成為訊息系統的瓶頸(吞吐量不夠)
不關注亂序的應用實際大量存在rocketmq不保證訊息不重複,如果你的業務需要保證嚴格的不重複訊息,需要你自己在業務端去重。佇列無序並不意味著訊息無序
Kafka分布式訊息系統
什麼是apache kafka?系統應用 使用者的活動資料 請求 資料 互動資料 執行維護資料如效能 監測 伺服器cpu 指標這些大量的資料都在無時無刻的產生,kafka 便是有著一套成熟的訊息處理方案的訊息系統,支援 高吞吐量的 分布式發布訂閱訊息 模式,它可以處理消費者規模的 中的所有動作流資料...
分布式訊息系統Kafka初步
在我們大量使用分布式資料庫 分布式計算集群的時候,是否會遇到這樣的一些問題 l 我想分析一下使用者行為 pageviews 以便我能設計出更好的廣告位 l 有些資料,我覺得存資料庫浪費,直接存硬碟又怕到時候操作效率低。這個時候,我們就可以用到分布式訊息系統了。雖然上面的描述更偏向於乙個日誌系統,但確...
分布式訊息系統Kafka初步
在我們大量使用分布式資料庫 分布式計算集群的時候,是否會遇到這樣的一些問題 l 我想分析一下使用者行為 pageviews 以便我能設計出更好的廣告位 l 有些資料,我覺得存資料庫浪費,直接存硬碟又怕到時候操作效率低。這個時候,我們就可以用到分布式訊息系統了。雖然上面的描述更偏向於乙個日誌系統,但確...