Rocketmq源码分析(一)整体架构
1 系列
- 整體架構(gòu)圖
- producer端發(fā)送消息
- broker端接收消息
- broker端消息的存儲
- consumer消費(fèi)消息
- 分布式事務(wù)的實現(xiàn)
- 定時消息的實現(xiàn)
- 關(guān)于順序消費(fèi)
- 關(guān)于重復(fù)消息
- 關(guān)于高可用
2 整體架構(gòu)圖
先來看下官方給出的整體架構(gòu)圖
- Producer集群:擁有相同的producerGroup,一般來講,Producer不必要有集群的概念,這里的集群僅僅在RocketMQ的分布式事務(wù)中有用到
- Name Server集群:提供topic的路由信息,路由信息數(shù)據(jù)存儲在內(nèi)存中,broker會定時的發(fā)送路由信息到nameserver中的每一個機(jī)器,來進(jìn)行更新,所以name server集群可以簡單理解為無狀態(tài)(實際情況下可能存在每個nameserver機(jī)器上的數(shù)據(jù)有短暫的不一致現(xiàn)象,但是通過定時更新,大部分情況下都是一致的)
- broker集群:一個集群有一個統(tǒng)一的名字,即brokerClusterName,默認(rèn)是DefaultCluster。一個集群下有多個master,每個master下有多個slave。master和slave算是一組,擁有相同的brokerName,不同的brokerId,master的brokerId是0,而slave則是大于0的值。master和slave之間可以進(jìn)行同步復(fù)制或者是異步復(fù)制。
- consumer集群:擁有相同的consumerGroup。
下面來說說他們之間的通信關(guān)系
- Producer和Name Server:每一個Producer會與Name Server集群中的一臺機(jī)器建立TCP連接,會從這臺Name Server上拉取路由信息。
- Producer和broker:Producer會和它要發(fā)送的topic相關(guān)的master類型的broker建立TCP連接,用于發(fā)送消息以及定時的心跳信息。broker中會記錄該P(yáng)roducer的信息,供查詢使用
- broker與Name Server:broker(不管是master還是slave)會和每一臺Name Server機(jī)器來建立TCP連接。broker在啟動的時候會注冊自己配置的topic信息到Name Server集群的每一臺機(jī)器中。即每一臺Name Server都有該broker的topic的配置信息。master與master之間無連接,master與slave之間有連接
- Consumer和Name Server:每一個Consumer會和Name Server集群中的一臺機(jī)器建立TCP連接,會從這臺Name Server上拉取路由信息,進(jìn)行負(fù)載均衡
- Consumer和broker:Consumer可以與master或者slave的broker建立TCP連接來進(jìn)行消費(fèi)消息,Consumer也會向它所消費(fèi)的broker發(fā)送心跳信息,供broker記錄。
3 kafka的架構(gòu)圖
來看下kafka的整體架構(gòu)圖
來看看他們之間的連接關(guān)系
- Producer和broker:Producer會和它所要發(fā)送的topic相關(guān)的broker建立TCP連接,并通過broker進(jìn)行其他broker的發(fā)現(xiàn)(這個沒有依賴ZooKeeper進(jìn)行服務(wù)發(fā)現(xiàn))
- broker和ZooKeeper:broker會將自己注冊在ZooKeeper上,同時依賴ZooKeeper做一些分布式協(xié)調(diào)
- Consumer和ZooKeeper:Consumer會將自己注冊在ZooKeeper上,同時依賴ZooKeeper進(jìn)行broker發(fā)現(xiàn)以及將消費(fèi)offset記錄在ZooKeeper上
- Consumer和Broker:Consumer連接topic相關(guān)的broker進(jìn)行消息的消費(fèi)
4 RocketMQ和kafka的對比
4.1 消息的存儲
我們知道topic是一類消息的統(tǒng)稱,為了提高消息的寫入和讀取并發(fā)能力,將一個topic的消息進(jìn)行拆分,可以分散到多個broker中。kafka上稱為分區(qū),而RocketMQ稱為隊列。
對于kafka:為了防止一個分區(qū)的消息文件過大,會拆分成一個個固定大小的文件,所以一個分區(qū)就對應(yīng)了一個目錄。分區(qū)與分區(qū)之間是相互隔離的。
對于RocketMQ:則是所有topic的數(shù)據(jù)混在一起進(jìn)行存儲,默認(rèn)超過1G的話,則重新創(chuàng)建一個新的文件。消息的寫入過程即寫入該混雜的文件中,然后又有一個線程服務(wù),在不斷的讀取分析該混雜文件,將消息進(jìn)行分揀,然后存儲在對應(yīng)隊列目錄中(存儲的是簡要信息,如消息在混雜文件中的offset,消息大小等)
所以RocketMQ需要2次尋找,第一次先找隊列中的消息概要信息,拿到概要信息中的offset,根據(jù)這個offset再到混雜文件中找到想要的消息。而kafka則只需要直接讀取分區(qū)中的文件即可得到想要的消息。
看下這里給出的RocketMQ的日志文件圖片分布式開放消息系統(tǒng)(RocketMQ)的原理與實踐
這里我自己認(rèn)為RocketMQ的做法還是值得商榷的,這樣的做法在同步刷盤、異步刷盤時效率相對高些(由于量大所以效率相對高些),但是全部的topic往一個文件里面寫,每次寫入要進(jìn)行加鎖控制,本來不相干的topic卻相互影響,就降低的寫入的效率。這個鎖的粒度有點(diǎn)大了,我自己認(rèn)為應(yīng)該一個隊列對應(yīng)一個CommitLog,這樣做就是減少鎖的粒度問題。
4.1 Prdocuer端的服務(wù)發(fā)現(xiàn)
就是Producer端如何來發(fā)現(xiàn)新的broker地址。
對于kafka來說:Producer端需要配置broker的列表地址,Producer也從一個broker中來更新broker列表地址(從中發(fā)現(xiàn)新加入的broker)。
對于RocketMQ來說:Producer端需要Name Server的列表地址,同時還可以定時從一個HTTP地址中來獲取最新的Name Server的列表地址,然后從其中的一臺Name Server來獲取全部的路由信息,從中發(fā)現(xiàn)新的broker。
4.1 消費(fèi)offset的存儲
對于kafka:Consumer將消費(fèi)的offset定時存儲到ZooKeeper上,利用ZooKeeper保障了offset的高可用問題。
對于RocketMQ:Consumer將消費(fèi)的offset定時存儲到broker所在的機(jī)器上,這個broker優(yōu)先是master,如果master掛了的話,則會選擇slave來存儲,broker也是將這些offset定時刷新到本地磁盤上,同時slave會定時的訪問master來獲取這些offset。
4.2 consumer負(fù)載均衡
對于負(fù)載均衡,在出現(xiàn)分區(qū)或者隊列增加或者減少的時候、Consumer增加或者減少的時候都會進(jìn)行reblance操作。
對于RocketMQ:客戶端自己會定時對所有的topic的進(jìn)行reblance操作,對于每個topic,會從broker獲取所有Consumer列表,從broker獲取隊列列表,按照負(fù)載均衡策略,計算各自負(fù)責(zé)哪些隊列。這種就要求進(jìn)行負(fù)載均衡的時候,各個Consumer獲取的數(shù)據(jù)是一致的,不然不同的Consumer的reblance結(jié)果就不同。
對于kafka:kafka之前也是客戶端自己進(jìn)行reblance,依靠ZooKeeper的監(jiān)聽,來監(jiān)聽上述2種情況的出現(xiàn),一旦出現(xiàn)則進(jìn)行reblance。現(xiàn)在的版本則將這個reblance操作轉(zhuǎn)移到了broker端來做,不但解決了RocketMQ上述的問題,同時減輕了客戶端的操作,是的客戶端更加輕量級,減少了和其他語言集成的工作量。詳細(xì)見這篇文章Kafka設(shè)計解析(四):Kafka Consumer解析
4.3 Name Server和ZooKeeper
Name Server和ZooKeeper的作用大致是相同的,從宏觀上來看,Name Server做的東西很少,就是保存一些運(yùn)行數(shù)據(jù),Name Server之間不互連,這就需要broker端連接所有的Name Server,運(yùn)行數(shù)據(jù)的改動要發(fā)送到每一個Name Server來保證運(yùn)行數(shù)據(jù)的一致性(這個一致性確實有點(diǎn)弱),這樣就變成了Name Server很輕量級,但是broker端就要做更多的東西了。
而ZooKeeper呢,broker只需要連接其中的一臺機(jī)器,運(yùn)行數(shù)據(jù)分發(fā)、一致性都交給了ZooKeeper來完成。
目前先就這幾個大的組件進(jìn)行簡單的對比,后續(xù)會對某些細(xì)節(jié)進(jìn)行詳細(xì)說明。
總結(jié)
以上是生活随笔為你收集整理的Rocketmq源码分析(一)整体架构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cidaemon.exe是什么
- 下一篇: 队列的其本应用_迷官问题