成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

RocketMQ在存儲架構(gòu)上的極致追求

存儲 存儲架構(gòu)
MQ作為一款中間件,就需要承載全公司所有業(yè)務(wù)系統(tǒng)使用需求,并高效穩(wěn)定運(yùn)行。因此,MQ對本身運(yùn)行效率有著非??量痰脑V求。本文就RocketMQ為了實(shí)現(xiàn)高效的讀寫速率在存儲架構(gòu)上所做的努力,進(jìn)行下闡述。

Part one / 存儲結(jié)構(gòu)選型對比

為了更方便的進(jìn)行數(shù)據(jù)讀寫,消息在磁盤底層的文件目錄設(shè)計(jì),都需要關(guān)注和解決什么問題呢:

  • 首先,最基本的,消息原始記錄的寫入和存儲,且速率要快。
  • 其次,要可以區(qū)分topic ,特別是允許消費(fèi)者按topic進(jìn)行接收。
  • 再次,分布式集群下的多消費(fèi)者負(fù)載均衡。

那么問題來了,消息文件該怎么設(shè)計(jì)呢?如果按topic來拆分文件進(jìn)行存儲,是否可以?

  • 缺點(diǎn):生產(chǎn)者寫入時(shí)選擇對應(yīng)的文件來寫入。當(dāng)數(shù)據(jù)量逐漸增大之后,定位查詢文件地址,對磁盤的尋址所帶來的性能損耗,將不再可以忽略。
  • 優(yōu)點(diǎn):在消費(fèi)時(shí),可以直接加載相關(guān)文件進(jìn)行讀取,不會產(chǎn)生隨機(jī)尋址。

如果用一整個(gè)文件來存消息呢?

  • 優(yōu)點(diǎn):所有的topic都被寫入一個(gè)文件中,這樣,寫入時(shí),只要將消息按到達(dá)順序序追加到文件尾部即可,很容易實(shí)現(xiàn)順序?qū)懭搿?/li>
  • 缺點(diǎn):消費(fèi)時(shí),需要根據(jù)輔助信息來在文件中定位消息,會產(chǎn)生隨機(jī)讀,損耗性能。

因此,不管是按topic拆開多文件存儲,還是一整個(gè)文件存儲做有利有弊,需要按實(shí)際需要進(jìn)行權(quán)衡。

Part two / RocketMQ的存儲方案選擇

RocketMQ存儲原始消息選擇的是寫同一個(gè)文件。

生產(chǎn)者將消息順序?qū)懭隿ommitLog文件究其原因,是由于RocketMQ一般都是普通業(yè)務(wù)場景使用居多,生產(chǎn)者和topic眾多,如果都獨(dú)立開各自存儲,每次消息生產(chǎn)的磁盤尋址對性能損耗是非常巨大的。

旁證側(cè)引:

kafka的文件存儲方式,是按topic拆分成partation來進(jìn)行的。是什么樣的原因,讓kafka做出了和RocketMQ相反的選擇呢?

個(gè)人認(rèn)為,主要還是使用場景的區(qū)別,kafka被優(yōu)先選擇用來進(jìn)行大數(shù)據(jù)處理,相對于業(yè)務(wù)場景,數(shù)據(jù)維度的topic要少很多,并且kafka的生產(chǎn)者(spark flume binlog等)機(jī)器會更加集中,這使得kafka選擇按topic拆分文件的缺陷不那么突出,而大數(shù)據(jù)處理更重要的是消息讀取,順序讀的優(yōu)勢得以被充分利用。

"單partation,單cunsumer的kafka,性能異常的優(yōu)秀" 是經(jīng)常被提及的一個(gè)觀點(diǎn),其原因,相信有了上面的分析應(yīng)該也差不多有結(jié)論了。

Part three / RocketMQ怎樣平衡讀性能

從第一部分的存儲方案對比可以知道,RocketMQ為了保證消息寫入效率,在存儲結(jié)構(gòu)上選擇了順序?qū)?,勢必會對消息的讀取和消費(fèi)帶來不便。那么,它是怎么來平衡消費(fèi)時(shí)的讀取速率的呢?關(guān)鍵問題是,找到一種途徑,可以快速的在commitLog中定位到所需消息的位置。從一堆數(shù)據(jù)中,快速定位想要的數(shù)據(jù),這不是索引最擅長的事情么?所以,RocketMQ也為commitLog創(chuàng)建了索引文件,并且是區(qū)分topic的結(jié)構(gòu)。

存儲架構(gòu)和存儲構(gòu)建鏈路示意圖

RocketMQ 的消息體構(gòu)成

消息體元素構(gòu)成

  • topic 是業(yè)務(wù)場景的唯一標(biāo)識,不可缺少;
  • queueId 在申請topic的時(shí)候確定,關(guān)聯(lián)著消費(fèi)索引consumerQueue中的隊(duì)列ID;
  • tags 是消息特殊標(biāo)簽,用于業(yè)務(wù)系統(tǒng)訂閱時(shí)提前過濾(這個(gè)功能真的是太重要了,吃過苦的同學(xué)都清楚);
  • keys 是消息的關(guān)鍵字,構(gòu)建index索引,用于關(guān)鍵字查詢用;
  • msgBody 是真實(shí)消息體;

消息由發(fā)布者發(fā)布,并依次的、順序的寫到commitLog里,消息一旦被寫入,是不可以更改順序和內(nèi)容的。commitLog規(guī)定最大1個(gè)G,達(dá)到規(guī)定大小則寫新的一個(gè)文件。

索引結(jié)構(gòu)和構(gòu)建過程

consumerQueue結(jié)構(gòu)和創(chuàng)建過程

consumerQueue 是一種機(jī)制,可以讓消費(fèi)端通過queue和commitLog之間的檢索關(guān)系,快速定位到commitLog里邊的具體消息內(nèi)容,然后拉取進(jìn)行消費(fèi)。consumerQueue 按 topic的不同,被分為不同的queue,根據(jù)queueId來被消費(fèi)者訂閱和消費(fèi);其中每個(gè)索引項(xiàng)是一個(gè)固定大小為20bytes的記錄,由消息在commitLog中的起始偏移量、消息體占用大小、type的hash碼三部分構(gòu)成??梢酝ㄟ^這三個(gè)部分快速定位到所需消息位置和類型。而上述索引的構(gòu)建過程,是在消息被寫入commitLog時(shí),專門的后臺服務(wù)--putMessageService,將索引信息分發(fā)到 consumerQueue 和index文件里,來構(gòu)建索引項(xiàng)。建索引的過程,實(shí)際上是一種分而治之思維的落地,除了索引,還有redis中的各種指標(biāo)維護(hù),核心是 分散壓力到每次請求,避免了大規(guī)模集中計(jì)算。

消息的消費(fèi)

消費(fèi)者對應(yīng)consumerQueue不一定是一對一的,因此,怎么來讓每個(gè)新的消費(fèi)者來了不會重復(fù)消費(fèi)呢?

offset消費(fèi)位點(diǎn)記錄在消息成功被拉取并消費(fèi)時(shí),后臺任務(wù)CommitOffsetManager 會將當(dāng)前消費(fèi)者,針對topic的消費(fèi)位點(diǎn)進(jìn)行記錄,目的是讓下一個(gè)或者重新啟動單餓消費(fèi)者記住這個(gè)消費(fèi)位點(diǎn),不至于重復(fù)消費(fèi)。因此,整個(gè)文件目錄就一目了然了:

Part four / 讀效率的追求

雖然通過上述文件存儲結(jié)構(gòu)的分析,我們知道,消費(fèi)者可以根據(jù)索引文件中的索引項(xiàng)來快速定位, 但事實(shí)上,消息的發(fā)布和消費(fèi),不可能直接針對磁盤進(jìn)行讀寫操作的,這樣效率會非常非常低。

實(shí)際上,我們的操作基本是針對一塊內(nèi)存進(jìn)行操作的 。

利用NIO的內(nèi)存映射機(jī)制,我們將commitLog的一部分文件交換到對外內(nèi)存。然后利用操作系統(tǒng)的pageCache技術(shù),在運(yùn)行過程中把內(nèi)存里的信息,與磁盤里的文件信息進(jìn)行同步,或者交換:

  • 消息發(fā)布者,在發(fā)布消息的時(shí)候,首先把消息添加到內(nèi)存里,然后根據(jù)刷盤的配置可以來指定是同步刷盤還是異步刷盤,來將內(nèi)存中的數(shù)據(jù)同步到磁盤上。
  • 消息的消費(fèi)者,在消費(fèi)消息的時(shí)候,大多數(shù)情況下,會直接命中到內(nèi)存上,不會進(jìn)行磁盤讀,但極個(gè)別的情況下,需要消費(fèi)的消息,在內(nèi)存中沒法找到,這時(shí)候,就需要用換頁技術(shù),將相關(guān)的信息,拉取到內(nèi)存中。為什么是相關(guān)信息,而不是需要什么拉取什么?這是有一個(gè)機(jī)制,來保證潛在的即將被消費(fèi)的信息直接換入內(nèi)存,來提交效率。

摘自:Qcon大會 RocketMQ分享資料

Part five / 總結(jié)

整體一套處理流程看下來,其實(shí)我們可以看到很多熟悉的身影,比如Mysql的索引,redis的統(tǒng)計(jì)信息記錄等等,都非常相似。其實(shí),我們可以這么認(rèn)為:對于信息存儲和查詢的處理方案大都如出一轍,只要把握住最核心的部分,然后根據(jù)實(shí)際業(yè)務(wù)訴求進(jìn)行適配優(yōu)化,基本都是可以達(dá)到期望的結(jié)果的。


責(zé)任編輯:武曉燕 來源: Coder的技術(shù)之路
相關(guān)推薦

2025-04-10 06:00:00

2013-07-31 09:25:47

用戶體驗(yàn)產(chǎn)品經(jīng)理

2023-05-04 10:43:42

Qwik前端框架

2019-07-23 09:20:15

Kafka批量處理客戶端

2018-10-29 15:41:16

二手硬件處理器

2012-03-05 16:28:24

華碩筆記本

2015-06-02 11:24:06

容聯(lián)云通訊

2020-08-28 11:20:01

CentOS7RocketMQ 4.運(yùn)維

2012-04-11 13:42:53

ibmdw

2021-09-02 16:10:57

系統(tǒng)數(shù)據(jù)存儲

2018-01-29 09:42:27

創(chuàng)業(yè)技術(shù)團(tuán)隊(duì)

2019-07-12 14:41:31

微服務(wù)Kubernetes容器

2012-09-29 13:33:16

Squid圖片存儲存儲架構(gòu)

2012-06-26 10:35:40

Squid架構(gòu)

2021-07-09 07:15:48

RocketMQ數(shù)據(jù)結(jié)構(gòu)kafka

2022-12-31 08:17:02

2013-12-18 13:15:36

算法

2010-10-12 16:46:18

交換

2022-02-23 15:08:18

開發(fā)分布式Java

2012-02-13 10:02:20

虛擬化vmware ESXilinux
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 亚洲天堂精品一区 | 欧美日韩在线一区二区 | 欧美区在线观看 | 国产精品69毛片高清亚洲 | 超碰日本| 午夜在线精品 | 国产激情在线 | 国产精品永久免费视频 | 国产91久久久久久久免费 | 欧美多人在线 | 婷婷久久精品一区二区 | 成人午夜免费视频 | 自拍偷拍第一页 | 干干干日日日 | 精品视频一区二区三区在线观看 | 亚洲一区二区黄 | 国产中文字幕在线观看 | 视频1区2区 | 欧美精品1区2区3区 精品国产欧美一区二区 | 亚洲 欧美 综合 | 欧美精品三区 | 亚洲精品乱码久久久久久按摩观 | 国产成年人视频 | 久久91精品国产一区二区 | 综合久久亚洲 | 亚洲精品无 | 精品一区二区三区在线观看国产 | 中文字幕在线观看 | 免费福利视频一区二区三区 | 国产区精品 | 国产成人精品av | 欧美大片一区二区 | 久久亚洲经典 | 伊人伊人 | 国产高清视频在线播放 | 国产精品成av人在线视午夜片 | 久久激情五月丁香伊人 | 亚洲视频观看 | 国产中文视频 | 成人一区二 | 成人国产免费观看 |