RocketMQ
本文內(nèi)容:描述RocketMQ的概念與術(shù)語(yǔ),最下方解釋各種MQ之間的區(qū)別與選型
RcoketMQ 是一款低延遲贞谓、高可靠斤富、可伸縮、易于使用的消息中間件罐柳。具有以下特性:
- 支持發(fā)布/訂閱(Pub/Sub)和點(diǎn)對(duì)點(diǎn)(P2P)消息模型
- 在一個(gè)隊(duì)列中可靠的先進(jìn)先出(FIFO)和嚴(yán)格的順序傳遞
- 支持拉(pull)和推(push)兩種消息模式
- 單一隊(duì)列百萬(wàn)消息的堆積能力
- 支持多種消息協(xié)議掌腰,如 JMS、MQTT 等
- 分布式高可用的部署架構(gòu),滿足至少一次消息傳遞語(yǔ)義
- 提供 docker 鏡像用于隔離測(cè)試和云集群部署
- 提供配置张吉、指標(biāo)和監(jiān)控等功能豐富的 Dashboard
架構(gòu)
系統(tǒng)架構(gòu)組成:
系統(tǒng)啟動(dòng)流程:
概念模型
專(zhuān)業(yè)術(shù)語(yǔ)及其關(guān)聯(lián)
1. Name Server
Name Server 為 producer 和 consumer 提供路由信息齿梁。
相對(duì)來(lái)說(shuō),nameserver的穩(wěn)定性非常高肮蛹。原因有二:
1. nameserver互相獨(dú)立勺择,彼此沒(méi)有通信關(guān)系,單臺(tái)nameserver掛掉伦忠,不影響其他nameserver省核,即使全部掛掉,也不影響業(yè)務(wù)系統(tǒng)使用缓苛。無(wú)狀態(tài)
2. nameserver不會(huì)有頻繁的讀寫(xiě)芳撒,所以性能開(kāi)銷(xiāo)非常小邓深,穩(wěn)定性很高未桥。
2. Broker
Broker 是 RocketMQ 系統(tǒng)的主要角色,其實(shí)就是MQ芥备?冬耿?topic管理?
Broker 接收來(lái)自生產(chǎn)者的消息萌壳,儲(chǔ)存以及為消費(fèi)者拉取消息的請(qǐng)求做好準(zhǔn)備亦镶。
2.1. 與NameServer關(guān)系
- 連接
- 單個(gè)broker和所有nameserver保持長(zhǎng)連接
- 心跳
- 心跳間隔:每隔30秒(此時(shí)間無(wú)法更改)向所有nameserver發(fā)送心跳日月,心跳包含了自身的topic配置信息。
- 心跳超時(shí):nameserver每隔10秒鐘(此時(shí)間無(wú)法更改)缤骨,掃描所有還存活的broker連接爱咬,若某個(gè)連接2分鐘內(nèi)(當(dāng)前時(shí)間與最后更新時(shí)間差值超過(guò)2分鐘,此時(shí)間無(wú)法更改)沒(méi)有發(fā)送心跳數(shù)據(jù)绊起,則斷開(kāi)連接精拟。
- 斷開(kāi)
- 時(shí)機(jī):broker掛掉;心跳超時(shí)導(dǎo)致nameserver主動(dòng)關(guān)閉連接
- 動(dòng)作:一旦連接斷開(kāi)虱歪,nameserver會(huì)立即感知蜂绎,更新topic與隊(duì)列的對(duì)應(yīng)關(guān)系,但不會(huì)通知生產(chǎn)者和消費(fèi)者
2.2. 負(fù)載均衡
- 一個(gè)topic分布在多個(gè)broker上笋鄙,一個(gè)broker可以配置多個(gè)topic师枣,它們是多對(duì)多的關(guān)系。
- 如果某個(gè)topic消息量很大萧落,應(yīng)該給它多配置幾個(gè)隊(duì)列践美?這什么意思,并且盡量多分布在不同broker上找岖,減輕某個(gè)broker的壓力拨脉。
- topic消息量都比較均勻的情況下,如果某個(gè)broker上的隊(duì)列越多宣增,則該broker壓力越大玫膀。
2.3. 可用性
由于消息分布在各個(gè)broker上,一旦某個(gè)broker宕機(jī)爹脾,則該broker上的消息讀寫(xiě)都會(huì)受到影響帖旨。所以rocketmq提供了master/slave的結(jié)構(gòu),salve定時(shí)從master同步數(shù)據(jù)灵妨,如果master宕機(jī)解阅,則slave提供消費(fèi)服務(wù),但是不能寫(xiě)入消息泌霍,此過(guò)程對(duì)應(yīng)用透明货抄,由rocketmq內(nèi)部解決。
這里有兩個(gè)關(guān)鍵點(diǎn):
- 一旦某個(gè)broker master宕機(jī)朱转,生產(chǎn)者和消費(fèi)者多久才能發(fā)現(xiàn)蟹地?受限于rocketmq的網(wǎng)絡(luò)連接機(jī)制,默認(rèn)情況下藤为,最多需要30秒怪与,但這個(gè)時(shí)間可由應(yīng)用設(shè)定參數(shù)來(lái)縮短時(shí)間。這個(gè)時(shí)間段內(nèi)缅疟,發(fā)往該broker的消息都是失敗的分别,而且該broker的消息無(wú)法消費(fèi)遍愿,因?yàn)榇藭r(shí)消費(fèi)者不知道該broker已經(jīng)掛掉。
- 消費(fèi)者得到master宕機(jī)通知后耘斩,轉(zhuǎn)向slave消費(fèi)(重定向沼填,對(duì)于2次開(kāi)發(fā)者透明),但是slave不能保證master的消息100%都同步過(guò)來(lái)了括授,因此會(huì)有少量的消息丟失倾哺。但是消息最終不會(huì)丟的,一旦master恢復(fù)刽脖,未同步過(guò)去的消息會(huì)被消費(fèi)掉羞海。
2.4. 可靠性
- 所有發(fā)往broker的消息,有同步刷盤(pán)和異步刷盤(pán)機(jī)制曲管,總的來(lái)說(shuō)却邓,可靠性非常高
- 同步刷盤(pán)時(shí),消息寫(xiě)入物理文件才會(huì)返回成功院水,因此非忱搬悖可靠
- 異步刷盤(pán)時(shí),只有機(jī)器宕機(jī)檬某,才會(huì)產(chǎn)生消息丟失撬腾,broker掛掉可能會(huì)發(fā)生,但是機(jī)器宕機(jī)崩潰是很少發(fā)生的恢恼,除非突然斷電民傻。
2.5. 消息清理
- 掃描間隔
- 默認(rèn)10秒,由broker配置參數(shù)cleanResourceInterval決定
- 空間閾值
- 物理文件不能無(wú)限制的一直存儲(chǔ)在磁盤(pán)场斑,當(dāng)磁盤(pán)空間達(dá)到閾值時(shí)漓踢,不再接受消息,broker打印出日志漏隐,消息發(fā)送失敗喧半,閾值為固定值85%
- 清理時(shí)機(jī)
- 默認(rèn)每天凌晨4點(diǎn),由broker配置參數(shù)deleteWhen決定青责;或者磁盤(pán)空間達(dá)到閾值
- 文件保留時(shí)長(zhǎng)
- 默認(rèn)72小時(shí)挺据,由broker配置參數(shù)fileReservedTime決定
2.6. 讀寫(xiě)性能
- 文件內(nèi)存映射方式操作文件,避免read/write系統(tǒng)調(diào)用和實(shí)時(shí)文件讀寫(xiě)脖隶,性能非常高
- 永遠(yuǎn)一個(gè)文件在寫(xiě)扁耐,其他文件在讀
- 順序?qū)懀S機(jī)讀
- 利用linux的sendfile浩村?做葵??mmap+write吧機(jī)制心墅,將消息內(nèi)容直接輸出到sokect管道酿矢,避免系統(tǒng)調(diào)用
2.7. 系統(tǒng)特性要求
- 大內(nèi)存,內(nèi)存越大性能越高怎燥,否則系統(tǒng)swap會(huì)成為性能瓶頸
- IO密集
- cpu load高瘫筐,使用率低,因?yàn)閏pu占用后铐姚,大部分時(shí)間在IO WAIT
- 磁盤(pán)可靠性要求高策肝,為了兼顧安全和性能,采用RAID10陣列
- 磁盤(pán)讀取速度要求快隐绵,要求高轉(zhuǎn)速大容量磁盤(pán)
3. Producer
消息生產(chǎn)者之众,生產(chǎn)者的作用就是將消息發(fā)送到 MQ,生產(chǎn)者本身既可以產(chǎn)生消息依许,如讀取文本信息等棺禾。
也可以對(duì)外提供接口,由外部應(yīng)用來(lái)調(diào)用接口峭跳,再由生產(chǎn)者將收到的消息發(fā)送到 MQ膘婶。
3.1. 與NameServer關(guān)系
- 連接
- 單個(gè)生產(chǎn)者者和一臺(tái)NameServer保持長(zhǎng)連接,定時(shí)查詢topic配置信息蛀醉,如果該NameServer掛掉悬襟,生產(chǎn)者會(huì)自動(dòng)連接下一個(gè)NameServer,直到有可用連接為止拯刁,并能自動(dòng)重連脊岳。
- 心跳
- 無(wú)心跳連接
- 輪詢時(shí)間
- 默認(rèn)情況下,生產(chǎn)者每隔30秒從NameServer獲取所有topic的最新隊(duì)列情況垛玻,這意味著某個(gè)broker如果宕機(jī)逸绎,生產(chǎn)者最多要30秒才能感知,在此期間夭谤,發(fā)往該broker的消息發(fā)送失敗棺牧。該時(shí)間由DefaultMQProducer的pollNameServerInteval參數(shù)決定,可手動(dòng)配置朗儒。
3.2. 與Borker關(guān)系
- 連接
- 單個(gè)生產(chǎn)者和該生產(chǎn)者關(guān)聯(lián)的所有broker保持長(zhǎng)連接颊乘。
- 心跳
- 默認(rèn)情況下,生產(chǎn)者每隔30秒向所有broker發(fā)送心跳醉锄,該時(shí)間由DefaultMQProducer的heartbeatBrokerInterval參數(shù)決定乏悄,可手動(dòng)配置。broker每隔10秒鐘(此時(shí)間無(wú)法更改)恳不,掃描所有還存活的連接檩小,若某個(gè)連接2分鐘內(nèi)(當(dāng)前時(shí)間與最后更新時(shí)間差值超過(guò)2分鐘,此時(shí)間無(wú)法更改)沒(méi)有發(fā)送心跳數(shù)據(jù)烟勋,則關(guān)閉連接规求。
- 斷開(kāi)
- 移除broker上的生產(chǎn)者信息
3.3. 負(fù)載均衡
- 莫得均衡
4. Producer Group
生產(chǎn)者組筐付,簡(jiǎn)單來(lái)說(shuō)就是多個(gè)發(fā)送同一類(lèi)消息的生產(chǎn)者稱(chēng)之為一個(gè)生產(chǎn)者組。在這里可以不用關(guān)心阻肿,只要知道有這么一個(gè)概念即可瓦戚。
5. Consumer
消息消費(fèi)者,簡(jiǎn)單來(lái)說(shuō)丛塌,消費(fèi) MQ 上的消息的應(yīng)用程序就是消費(fèi)者较解,至于消息是否進(jìn)行邏輯處理,還是直接存儲(chǔ)到數(shù)據(jù)庫(kù)等取決于業(yè)務(wù)需要赴邻。
5.1. 與NameServer關(guān)系
- 連接
- 單個(gè)消費(fèi)者和一臺(tái)nameserver保持長(zhǎng)連接印衔,定時(shí)查詢topic配置信息,如果該nameserver掛掉姥敛,消費(fèi)者會(huì)自動(dòng)連接下一個(gè)nameserver奸焙,直到有可用連接為止,并能自動(dòng)重連徒溪。
- 心跳
- 不心跳關(guān)聯(lián)
- 輪詢時(shí)間
- 默認(rèn)情況下忿偷,消費(fèi)者每隔30秒從nameserver獲取所有topic的最新隊(duì)列情況,這意味著某個(gè)broker如果宕機(jī)臊泌,客戶端最多要30秒才能感知鲤桥。該時(shí)間由DefaultMQPushConsumer的pollNameServerInteval參數(shù)決定,可手動(dòng)配置渠概。
5.2. 與Borker關(guān)系
- 連接
- 單個(gè)消費(fèi)者和該消費(fèi)者關(guān)聯(lián)的所有broker保持長(zhǎng)連接茶凳。
- 心跳
- 默認(rèn)情況下,消費(fèi)者每隔30秒向所有broker發(fā)送心跳播揪,該時(shí)間由DefaultMQPushConsumer的heartbeatBrokerInterval參數(shù)決定贮喧,可手動(dòng)配置。broker每隔10秒鐘(此時(shí)間無(wú)法更改)猪狈,掃描所有還存活的連接箱沦,若某個(gè)連接2分鐘內(nèi)(當(dāng)前時(shí)間與最后更新時(shí)間差值超過(guò)2分鐘,此時(shí)間無(wú)法更改)沒(méi)有發(fā)送心跳數(shù)據(jù)雇庙,則關(guān)閉連接谓形,并向該消費(fèi)者分組的所有消費(fèi)者發(fā)出通知,分組內(nèi)消費(fèi)者重新分配隊(duì)列繼續(xù)消費(fèi)疆前。
- 斷開(kāi)
- 時(shí)機(jī):消費(fèi)者掛掉寒跳;心跳超時(shí)導(dǎo)致broker主動(dòng)關(guān)閉連接
- 動(dòng)作:一旦連接斷開(kāi),broker會(huì)立即感知到竹椒,并向該消費(fèi)者分組的所有消費(fèi)者發(fā)出通知童太,分組內(nèi)消費(fèi)者重新分配隊(duì)列繼續(xù)消費(fèi)
5.3. 負(fù)載均衡
- 集群消費(fèi)模式下,一個(gè)消費(fèi)者集群多臺(tái)機(jī)器共同消費(fèi)一個(gè)topic的多個(gè)隊(duì)列,一個(gè)隊(duì)列只會(huì)被一個(gè)消費(fèi)者消費(fèi)书释。
- 如果某個(gè)消費(fèi)者掛掉翘贮,分組內(nèi)其它消費(fèi)者會(huì)接替掛掉的消費(fèi)者繼續(xù)消費(fèi)。
5.4. 消費(fèi)機(jī)制
- 本地隊(duì)列
- 消費(fèi)者不間斷的從broker拉取消息征冷,消息拉取到本地隊(duì)列择膝,然后本地消費(fèi)線程消費(fèi)本地消息隊(duì)列誓琼,只是一個(gè)異步過(guò)程检激,拉取線程不會(huì)等待本地消費(fèi)線程,這種模式實(shí)時(shí)性非常高腹侣。對(duì)消費(fèi)者對(duì)本地隊(duì)列有一個(gè)保護(hù)叔收,因此本地消息隊(duì)列不能無(wú)限大,否則可能會(huì)占用大量?jī)?nèi)存傲隶,本地隊(duì)列大小由DefaultMQPushConsumer的pullThresholdForQueue屬性控制饺律,默認(rèn)1000,可手動(dòng)設(shè)置跺株。
- 輪詢間隔
- 消息拉取線程每隔多久拉取一次复濒?間隔時(shí)間由DefaultMQPushConsumer的pullInterval屬性控制,默認(rèn)為0乒省,可手動(dòng)設(shè)置巧颈。
- 消息消費(fèi)數(shù)量
- 監(jiān)聽(tīng)器每次接受本地隊(duì)列的消息是多少條?這個(gè)參數(shù)由DefaultMQPushConsumer的consumeMessageBatchMaxSize屬性控制袖扛,默認(rèn)為1砸泛,可手動(dòng)設(shè)置。
5.5. 消費(fèi)進(jìn)度存儲(chǔ)
- 每隔一段時(shí)間將各個(gè)隊(duì)列的消費(fèi)進(jìn)度存儲(chǔ)到對(duì)應(yīng)的broker上蛆封,該時(shí)間由DefaultMQPushConsumer的persistConsumerOffsetInterval屬性控制唇礁,默認(rèn)為5秒,可手動(dòng)設(shè)置惨篱。
5.6. 連接數(shù)
- 如果一個(gè)topic在某broker上有3個(gè)隊(duì)列盏筐,一個(gè)消費(fèi)者消費(fèi)這3個(gè)隊(duì)列,那么該消費(fèi)者和這個(gè)broker有幾個(gè)連接砸讳?
- 一個(gè)連接琢融,消費(fèi)單位與隊(duì)列相關(guān),消費(fèi)連接只跟broker相關(guān)绣夺,事實(shí)上吏奸,消費(fèi)者將所有隊(duì)列的消息拉取任務(wù)放到本地的隊(duì)列,挨個(gè)拉取陶耍,拉取完畢后奋蔚,又將拉取任務(wù)放到隊(duì)尾,然后執(zhí)行下一個(gè)拉取任務(wù)
6. Consumer Group
消費(fèi)者組,和生產(chǎn)者類(lèi)似泊碑,消費(fèi)同一類(lèi)消息的多個(gè) consumer 實(shí)例組成一個(gè)消費(fèi)者組(集群)坤按。
- 標(biāo)識(shí)一類(lèi)Consumer的集合名稱(chēng),這類(lèi)Consumer通常消費(fèi)一類(lèi)消息馒过,且消費(fèi)邏輯一致臭脓。同一個(gè)Consumer Group下的各個(gè)實(shí)例將共同消費(fèi)topic的消息,起到負(fù)載均衡的作用腹忽。
- 消費(fèi)進(jìn)度以Consumer Group為粒度管理来累,不同Consumer Group之間消費(fèi)進(jìn)度彼此不受影響,即消息A被Consumer Group1消費(fèi)過(guò)窘奏,也會(huì)再給Consumer Group2消費(fèi)嘹锁。
- 注: RocketMQ要求同一個(gè)Consumer Group的消費(fèi)者必須要擁有相同的注冊(cè)信息,即必須要聽(tīng)一樣的topic(并且tag也一樣)着裹。
7. Filter Server(可選)
RocketMQ可以允許消費(fèi)者上傳一個(gè)Java類(lèi)給Filter Server進(jìn)行過(guò)濾领猾。暫不使用
8. Topic
Topic是一種消息的邏輯分類(lèi),比如說(shuō)你有訂單類(lèi)的消息骇扇,也有庫(kù)存類(lèi)的消息摔竿,那么就需要進(jìn)行分類(lèi),一個(gè)是訂單 Topic 存放訂單相關(guān)的消息少孝,一個(gè)是庫(kù)存 Topic 存儲(chǔ)庫(kù)存相關(guān)的消息继低。
9. Tag
標(biāo)簽可以被認(rèn)為是對(duì)Topic進(jìn)一步細(xì)化。一般在相同業(yè)務(wù)模塊中通過(guò)引入標(biāo)簽來(lái)標(biāo)記不同用途的消息韭山。
RocketMQ支持給在發(fā)送的時(shí)候給topic打tag郁季,同一個(gè)topic的消息雖然邏輯管理是一樣的。但是消費(fèi)topic1的時(shí)候钱磅,如果你訂閱的時(shí)候指定的是tagA梦裂,那么tagB的消息將不會(huì)投遞。
10. Message
Message 是消息的載體盖淡。一個(gè) Message 必須指定 topic年柠,相當(dāng)于寄信的地址。
Message 還有一個(gè)可選的 tag 設(shè)置褪迟,以便消費(fèi)端可以基于 tag 進(jìn)行過(guò)濾消息冗恨。
也可以添加額外的鍵值對(duì),例如你需要一個(gè)業(yè)務(wù) key 來(lái)查找 broker 上的消息味赃,方便在開(kāi)發(fā)過(guò)程中診斷問(wèn)題掀抹。
11. Message Queue
簡(jiǎn)稱(chēng)queue或Q,消息物理管理單位心俗。一個(gè)Topic將有若干個(gè)Q傲武。若Topic同時(shí)創(chuàng)建在不同的Broker蓉驹,則不同的broker上都有若干Q,消息將物理地存儲(chǔ)落在不同Broker結(jié)點(diǎn)上揪利,具有水平擴(kuò)展的能力态兴。
- 無(wú)論生產(chǎn)者還是消費(fèi)者,實(shí)際的生產(chǎn)和消費(fèi)都是針對(duì)Q級(jí)別疟位。例如Producer發(fā)送消息的時(shí)候瞻润,會(huì)預(yù)先選擇(默認(rèn)輪詢)好該Topic下面的某一條Q地發(fā)送;Consumer消費(fèi)的時(shí)候也會(huì)負(fù)載均衡地分配若干個(gè)Q甜刻,只拉取對(duì)應(yīng)Q的消息绍撞。
- 每一條message queue均對(duì)應(yīng)一個(gè)文件,這個(gè)文件存儲(chǔ)了實(shí)際消息的索引信息罢吃。并且即使文件被刪除楚午,也能通過(guò)實(shí)際純粹的消息文件(commit log)恢復(fù)回來(lái)昭齐。
是不是可以這樣理解:這個(gè)隊(duì)列的存在是為了可以讓一個(gè)topic通過(guò)不同路徑發(fā)布出去尿招,
consumer指定topic實(shí)際上就是關(guān)注所有的Q,
也就是說(shuō)阱驾,這樣操作的意義就在于可以吧Q放到不同Borker啟動(dòng)負(fù)載均衡的作用唄就谜。
所以,如果要順序消費(fèi)里覆,就讓topic只有Q就可以了唄丧荐,是不是這樣得存疑?
12. Offset
RocketMQ中喧枷,有很多offset的概念虹统。但通常我們只關(guān)心暴露到客戶端的offset。一般我們不特指的話隧甚,就是指邏輯Message Queue下面的offset车荔。
- 可以認(rèn)為一條邏輯的message queue是無(wú)限長(zhǎng)的數(shù)組。一條消息進(jìn)來(lái)下標(biāo)就會(huì)漲1戚扳。下標(biāo)就是offset忧便。
- 一條message queue中的max offset表示消息的最大offset。注:這里從源碼上看帽借,max_offset并不是最新的那條消息的offset珠增,而是表示最新消息的offset+1。
- 而min offset則標(biāo)識(shí)現(xiàn)存在的最小offset砍艾。
- 由于消息存儲(chǔ)一段時(shí)間后蒂教,消費(fèi)會(huì)被物理地從磁盤(pán)刪除,message queue的min offset也就對(duì)應(yīng)增長(zhǎng)脆荷。這意味著比min offset要小的那些消息已經(jīng)不在broker上了凝垛,無(wú)法被消費(fèi)。
13. Consumer Offset
用于標(biāo)記Consumer Group在一條邏輯Message Queue上,消息消費(fèi)到哪里了苔严。注:從源碼上看定枷,這個(gè)數(shù)值是最新消費(fèi)的那條消息的offset+1,所以實(shí)際上這個(gè)值存儲(chǔ)的是【下次拉取的話届氢,從哪里開(kāi)始拉取的offset】欠窒。
- 消費(fèi)者拉取消息的時(shí)候需要指定offset,broker不主動(dòng)推送消息退子,而是接受到請(qǐng)求的時(shí)候把存儲(chǔ)的對(duì)應(yīng)offset的消息返回給客戶端岖妄。這個(gè)offset在成功消費(fèi)后會(huì)更新到內(nèi)存,并定時(shí)持久化寂祥。在集群消費(fèi)模式下荐虐,會(huì)同步持久化到broker。在廣播模式下丸凭,會(huì)持久化到本地文件福扬。
- 實(shí)例重啟的時(shí)候會(huì)獲取持久化的consumer offset,用以決定從哪里開(kāi)始消費(fèi)惜犀。
其他術(shù)語(yǔ)
1. 集群消費(fèi)
消費(fèi)者的一種消費(fèi)模式铛碑。一個(gè)Consumer Group中的各個(gè)Consumer實(shí)例分?jǐn)側(cè)ハM(fèi)消息,即一條消息只會(huì)投遞到一個(gè)Consumer Group下面的一個(gè)實(shí)例虽界。
實(shí)際上汽烦,每個(gè)Consumer是平均分?jǐn)侻essage Queue的去做拉取消費(fèi)。例如某個(gè)Topic有3條Q莉御,其中一個(gè)Consumer Group 有 3 個(gè)實(shí)例(可能是 3 個(gè)進(jìn)程撇吞,或者 3 臺(tái)機(jī)器),那么每個(gè)實(shí)例只消費(fèi)其中的1條Q礁叔。
而由Producer發(fā)送消息的時(shí)候是輪詢所有的Q,所以消息會(huì)平均散落在不同的Q上牍颈,可以認(rèn)為Q上的消息是平均的。那么實(shí)例也就平均地消費(fèi)消息了晴圾。
這種模式下颂砸,消費(fèi)進(jìn)度的存儲(chǔ)會(huì)持久化到Broker。
2. 廣播消費(fèi)
消費(fèi)者的一種消費(fèi)模式死姚。消息將對(duì)一個(gè)Consumer Group下的各個(gè)Consumer實(shí)例都投遞一遍人乓。即即使這些 Consumer 屬于同一個(gè)Consumer Group,消息也會(huì)被Consumer Group 中的每個(gè)Consumer都消費(fèi)一次都毒。
實(shí)際上色罚,是一個(gè)消費(fèi)組下的每個(gè)消費(fèi)者實(shí)例都獲取到了topic下面的每個(gè)Message Queue去拉取消費(fèi)。所以消息會(huì)投遞到每個(gè)消費(fèi)者實(shí)例账劲。
這種模式下戳护,消費(fèi)進(jìn)度會(huì)存儲(chǔ)持久化到實(shí)例本地金抡。
3. 順序消息
消費(fèi)消息的順序要同發(fā)送消息的順序一致。
- 由于Consumer消費(fèi)消息的時(shí)候是針對(duì)Message Queue順序拉取并開(kāi)始消費(fèi)腌且,且一條Message Queue只會(huì)給一個(gè)消費(fèi)者(集群模式下)梗肝,所以能夠保證同一個(gè)消費(fèi)者實(shí)例對(duì)于Q上消息的消費(fèi)是順序地開(kāi)始消費(fèi)(不一定順序消費(fèi)完成,因?yàn)橄M(fèi)可能并行)铺董。
- 在RocketMQ中巫击,順序消費(fèi)主要指的是都是Queue級(jí)別的局部順序。
- 這一類(lèi)消息為滿足順序性精续,必須Producer單線程順序發(fā)送坝锰,且發(fā)送到同一個(gè)隊(duì)列,這樣Consumer就可以按照Producer發(fā)送的順序去消費(fèi)消息
生產(chǎn)者發(fā)送的時(shí)候可以用MessageQueueSelector為某一批消息(通常是有相同的唯一標(biāo)示id)選擇同一個(gè)Queue
或者M(jìn)essage Queue的數(shù)量只有1重付,但這樣消費(fèi)的實(shí)例也會(huì)只有一個(gè)顷级,多出來(lái)的實(shí)例都會(huì)空跑。(集群模式)
4. 普通順序消息
順序消息的一種确垫,正常情況下可以保證完全的順序消息弓颈。
這種是一旦發(fā)生異常,Broker宕機(jī)或重啟森爽,由于隊(duì)列總數(shù)發(fā)生發(fā)化恨豁,消費(fèi)者會(huì)觸發(fā)負(fù)載均衡,而默認(rèn)地負(fù)載均衡算法采取哈希取模平均爬迟,這樣負(fù)載均衡分配到定位的隊(duì)列會(huì)發(fā)化,使得隊(duì)列可能分配到別的實(shí)例上菊匿,則會(huì)短暫地出現(xiàn)消息順序不一致付呕。
如果業(yè)務(wù)能容忍在集群異常情況(如某個(gè) Broker 宕機(jī)或者重啟)下,消息短暫的亂序跌捆,使用普通順序方式比較合適徽职。
5. 嚴(yán)格順序消息
順序消息的一種,無(wú)論正常異常情況都能保證順序佩厚。
犧牲了分布式 Failover 特性姆钉,即 Broker集群中只要有一臺(tái)機(jī)器不可用,則整個(gè)集群都不可用抄瓦,服務(wù)可用性大大降低
如果服務(wù)器部署為同步雙寫(xiě)模式潮瓶,此缺陷可通過(guò)備機(jī)自動(dòng)切換為主避免,不過(guò)仍然會(huì)存在幾分鐘的服務(wù)不可用钙姊。(依賴(lài)同步雙寫(xiě)毯辅,主備自動(dòng)切換,自動(dòng)切換功能目前并未實(shí)現(xiàn)).
RocketMQ 架構(gòu)
由這張圖可以看到有四個(gè)集群煞额,分別是 NameServer 集群思恐、Broker 集群沾谜、Producer 集群和 Consumer 集群:
- NameServer:提供輕量級(jí)的服務(wù)發(fā)現(xiàn)和路由。 每個(gè) NameServer 記錄完整的路由信息胀莹,提供等效的讀寫(xiě)服務(wù)基跑,并支持快速存儲(chǔ)擴(kuò)展。
- Broker:通過(guò)提供輕量級(jí)的 Topic 和 Queue 機(jī)制來(lái)處理消息存儲(chǔ),同時(shí)支持推(push)和拉(pull)模式以及主從結(jié)構(gòu)的容錯(cuò)機(jī)制描焰。
- Producer:生產(chǎn)者涩僻,產(chǎn)生消息的實(shí)例,擁有相同 Producer Group 的 Producer 組成一個(gè)集群栈顷。
- Consumer:消費(fèi)者逆日,接收消息進(jìn)行消費(fèi)的實(shí)例,擁有相同 Consumer Group 的Consumer 組成一個(gè)集群萄凤。
簡(jiǎn)單說(shuō)明一下圖中箭頭含義室抽,從 Broker 開(kāi)始,
Broker Master1 和 Broker Slave1 是主從結(jié)構(gòu)靡努,它們之間會(huì)進(jìn)行數(shù)據(jù)同步坪圾,即 Date Sync。
同時(shí)每個(gè) Broker 與 NameServer 集群中的所有節(jié)點(diǎn)建立長(zhǎng)連接惑朦,定時(shí)注冊(cè) Topic 信息到所有 NameServer 中兽泄。
Producer 與 NameServer 集群中的其中一個(gè)節(jié)點(diǎn)(隨機(jī)選擇)建立長(zhǎng)連接,
定期從 NameServer 獲取 Topic 路由信息漾月,并向提供 Topic 服務(wù)的 Broker Master 建立長(zhǎng)連接病梢,
且定時(shí)向 Broker 發(fā)送心跳。Producer 只能將消息發(fā)送到 Broker master梁肿,
但是 Consumer 則不一樣蜓陌,它同時(shí)和提供 Topic 服務(wù)的 Master 和 Slave
建立長(zhǎng)連接,既可以從 Broker Master 訂閱消息吩蔑,也可以從 Broker Slave 訂閱消息钮热。
RocketMQ 集群部署模式
1.單master模式
也就是只有一個(gè) master 節(jié)點(diǎn),稱(chēng)不上是集群烛芬,
一旦這個(gè) master 節(jié)點(diǎn)宕機(jī)隧期,那么整個(gè)服務(wù)就不可用,適合個(gè)人學(xué)習(xí)使用赘娄。
2.多 master 模式
多個(gè) master 節(jié)點(diǎn)組成集群仆潮,單個(gè) master 節(jié)點(diǎn)宕機(jī)或者重啟對(duì)應(yīng)用沒(méi)有影響。
優(yōu)點(diǎn):所有模式中性能最高
缺點(diǎn):?jiǎn)蝹€(gè) master 節(jié)點(diǎn)宕機(jī)期間擅憔,未被消費(fèi)的消息在節(jié)點(diǎn)恢復(fù)之前不可用鸵闪,消息的實(shí)時(shí)性就受到影響。
*注意*:使用同步刷盤(pán)可以保證消息不丟失暑诸,同時(shí) Topic 相對(duì)應(yīng)的 queue 應(yīng)該分布在集群中各個(gè)節(jié)點(diǎn)蚌讼,而不是只在某各節(jié)點(diǎn)上辟灰,否則,該節(jié)點(diǎn)宕機(jī)會(huì)對(duì)訂閱該 topic 的應(yīng)用造成影響篡石。
3.多 master 多 slave 異步復(fù)制模式
在多 master 模式的基礎(chǔ)上芥喇,每個(gè) master 節(jié)點(diǎn)都有至少一個(gè)對(duì)應(yīng)的 slave。
master節(jié)點(diǎn)可讀可寫(xiě)凰萨,但是slave只能讀不能寫(xiě)继控,類(lèi)似于 mysql 的主備模式。
優(yōu)點(diǎn): 在 master 宕機(jī)時(shí)胖眷,消費(fèi)者可以從 slave 讀取消息武通,消息的實(shí)時(shí)性不會(huì)受影響,性能幾乎和多 master 一樣珊搀。
缺點(diǎn):使用異步復(fù)制的同步方式有可能會(huì)有消息丟失的問(wèn)題冶忱。
4.多 master 多 slave 同步雙寫(xiě)模式
同多 master 多 slave 異步復(fù)制模式類(lèi)似,區(qū)別在于 master 和 slave 之間的數(shù)據(jù)同步方式境析。
優(yōu)點(diǎn):同步雙寫(xiě)的同步模式能保證數(shù)據(jù)不丟失囚枪。
缺點(diǎn):發(fā)送單個(gè)消息 RT 會(huì)略長(zhǎng),性能相比異步復(fù)制低10%左右劳淆。
刷盤(pán)策略:同步刷盤(pán)和異步刷盤(pán)(指的是節(jié)點(diǎn)自身數(shù)據(jù)是同步還是異步存儲(chǔ))
同步方式:同步雙寫(xiě)和異步復(fù)制(指的一組 master 和 slave 之間數(shù)據(jù)的同步)
*注意*:要保證數(shù)據(jù)可靠链沼,需采用同步刷盤(pán)和同步雙寫(xiě)的方式,但性能會(huì)較其他方式低沛鸵。
對(duì)MQ產(chǎn)品的總結(jié)
特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
---|---|---|---|---|
設(shè)計(jì)定位 | 小型項(xiàng)目常規(guī)成員 | 非日志可靠信息傳輸 | 非日志可靠信息傳輸 | 系統(tǒng)間數(shù)據(jù)流管道括勺,實(shí)時(shí)數(shù)據(jù)處理 |
單機(jī)吞吐量 | 萬(wàn)級(jí) | 萬(wàn)級(jí) | 10萬(wàn)級(jí) | 10萬(wàn)級(jí)(Kafka目的) |
topic數(shù)量對(duì)性能的影響 | topic可以達(dá)到幾百,幾千個(gè)的級(jí)別谒臼,吞吐量會(huì)有較小幅度的下降朝刊;這是RocketMQ的一大優(yōu)勢(shì),在同等機(jī)器下蜈缤,可以支撐大量的topic | Kopic從幾十個(gè)到幾百個(gè)的時(shí)候,吞吐量會(huì)大幅度下降冯挎;所以在同等機(jī)器下底哥,kafka盡量保證topic數(shù)量不要過(guò)多。如果要支撐大規(guī)模topic房官,需要增加更多的機(jī)器資源 | ||
時(shí)效性 | ms級(jí) | us級(jí) | ms級(jí) | ms級(jí)以內(nèi) |
Available | 中 主從 | 中 主從 | 高 分布式 | 高 分布式 |
Reliability | 較低的概率丟失數(shù)據(jù) | 極低或可為0 | 極低或可為0 | |
功能&擴(kuò)展 | 功能完善&擴(kuò)展一般 | 功能完善&很難擴(kuò)展(erlang) | 功能完善&擴(kuò)展良好 | 功能簡(jiǎn)單&為了不同環(huán)境 |
社區(qū)活躍度 | 低 | 高 | 中 | 高 |
** 以上基本排除ActiveMQ **
** 以下是其他三種精細(xì)對(duì)比 **