客戶端管理Channel
因為客戶端要主動發(fā)起請求免都,以consumer為例绽诚,在對topic進行消費時件甥,不同的topic可能在不同的broker上藏研,因此consumer端需要對連接的多個server的Channel進行管理
流程如下:consumer和nameserver通信,獲取broker地址咐汞,根據(jù)地址查詢是否存在Channel盖呼,若不存在就創(chuàng)建Channel,并在本地緩存化撕,下次通信時從緩存中獲取Channel几晤。通過Channel和broker進行通信。
關于自動創(chuàng)建topic的邏輯
發(fā)送消息時植阴,如果是新的topic锌仅,producer會先使用默認的topicKey(TBW102)去nameserver請求一個默認的TopicRoute章钾,這個topicRoute會包含broker等信息墙贱,然后根據(jù)這個topicRoute再構建一個新的topic對應的TopicPublishInfo热芹,將這個TopicPublishInfo放入producerImpl的緩存即topicPublishInfoTable中。這樣做是為了后期發(fā)送消息的統(tǒng)一性(發(fā)送消息需要按照topic和broker的對應關系來做)惨撇,這樣在發(fā)送消息時就直接選擇一個broker進行發(fā)送即可伊脓,broker端對于不存在的topic再進行創(chuàng)建。
nameserver返回的TopicRouteInfo中存有topic對應的所有broker的信息魁衙,以及broker中所有的master和slave报腔,客戶端會將其轉化為自己使用的,例如producer會將其轉換為TopicPublishInfo剖淀。
發(fā)送消息時根據(jù)brokerName找到brokerAddress
rocket集群相關
客戶端做負載均衡纯蛾,會在客戶端選擇broker進行通信,是在客戶端將消息發(fā)送到broker纵隔,因此相當于在客戶端將topic進行了分片處理翻诉,高可用場景下可以使用異步復制或者同步雙寫保證數(shù)據(jù)一致性
目前高可用模式是多master多slave,一個master對應一個slave捌刮,master負責讀寫碰煌,slave可以幫助讀。在master掛掉后slave并不能升級成為master绅作,但是可以繼續(xù)從slave讀芦圾。后期寫時只會寫到其他的master。
不同的master broker的brokerName不同俄认,master和對應slave的brokerName相同个少,brokerId不同,brokerId為0為master眯杏,brokerId不為0的為slave夜焦。
一個master可以對應多個slave,但是只有brokerId為1的才參與讀消息役拴,別的slave還是可以幫忙存儲消息的糊探。。河闰。
參考文檔中這段話
注意:當前RocketMQ版本在部署架構上支持一Master多Slave科平,但只有BrokerId=1的從服務器才會參與消息的讀負載。
高可用實現(xiàn)
master和slave兩種同步模式
同步雙寫
異步復制
如果當前broker為slave姜性,在將自己注冊到nameserver時瞪慧,若nameserver的注冊列表中存在對應的master,將會返回master的信息部念,包括master的地址和ha地址弃酌。ha地址就是master配置的brokerIP2氨菇。隨后slave會啟動一個線程(是在HAService中的HAClient),不停的將當前broker的消息位置的最大物理偏移量發(fā)送給master妓湘,master接收后會返回這個位置之后的消息查蓉,slave接收后寫入commitlog,達到異步復制的功能榜贴。
ConsumerGroup相關邏輯
如果兩個consumer的group相同豌研,在cluster模式下,會平均的消費消息唬党。
如果兩個consumer的group不同鹃共,一條消息會在兩個consumer處各消費一次。
Consumer端負載均衡的核心設計理念:一個消息消費隊列在同一時間只允許被同一消費組內(nèi)的一個消費者消費驶拱,一個消息消費者能同時消費多個消息隊列霜浴。
consumer端負載均衡的邏輯在RebalanceService。
cluster模式下
從broker獲取同一個group下的consumer列表蓝纲,按照平均分配的分頁算法伦腐,找到當前consumer對應的MessageQueue列表读处,將該MessageQueue列表和當前的processQueueTable做比對,將不在processQueueTable中的MessageQueue構造PullRequest,發(fā)送給PullService钧舌。
此處的分頁算法挟伙,是先將consumer和MessqgeQueueList排序办铡,用consumer作為頁碼钥飞,將MessageQueueList分為記錄,根據(jù)頁碼劃分記錄露懒,并求出每一頁的size和每一頁的范圍range闯冷。最后根據(jù)consumerId找到對應的MessageQueue。
消息存儲
幾個重要的類
- CommitLog
- MappedFile
- MappedFileQueue
主要用到的jdk中的類
- RandomAccessFile
- MappedByteBuffer
- FileChannel
主要用到的技術懈词,內(nèi)存映射
消息落盤之后蛇耀,ReputMessageService線程會更新ConsumeQueue和Index文件。