新聞中心
Kafka、RocketMQ、Pulsar全方位對(duì)比!
作者:文小飛 2021-08-24 07:57:26
開(kāi)發(fā)
架構(gòu)
開(kāi)發(fā)工具
Kafka 消息隊(duì)列也通常稱為消息中間件,提到消息隊(duì)列,大部分互聯(lián)網(wǎng)人或多或少都聽(tīng)過(guò)該名詞。對(duì)于后端工程師而言,更是日常開(kāi)發(fā)中必備的一項(xiàng)技能。

我們提供的服務(wù)有:成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、澄海ssl等。為千余家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的澄海網(wǎng)站制作公司
圖片來(lái)自 包圖網(wǎng)
隨著大數(shù)據(jù)時(shí)代的到來(lái),Apache 旗下的 Kafka 一度成為消息隊(duì)列的代名詞,提起消息隊(duì)列大家自然而然就想到了 Kafka。
然而消息隊(duì)列本身是工程領(lǐng)域內(nèi)一種解決問(wèn)題的通用方案。它的背后有著一些通用的設(shè)計(jì)思想和經(jīng)典模型,這些是消息隊(duì)列的精髓和靈魂。
它們獨(dú)立于任何一種消息隊(duì)列的具體實(shí)現(xiàn)(例如 Kafka),但每種消息隊(duì)列(除了 Kafka 外,還有 RocketMQ、Pulsar 等)的實(shí)現(xiàn)中到處體現(xiàn)著這些設(shè)計(jì)思想。
本文主要從抽象層面來(lái)簡(jiǎn)單談?wù)勏㈥?duì)列背后的一些設(shè)計(jì)思想,輔助理解消息隊(duì)列這一類組件。
主要解決三個(gè)問(wèn)題:
- 消息隊(duì)列適合什么場(chǎng)景?
- 消息隊(duì)列有哪些主流產(chǎn)品、各自的優(yōu)缺點(diǎn)?
- 消息隊(duì)列背后的設(shè)計(jì)思想(整體核心模型、數(shù)據(jù)存儲(chǔ)考量、數(shù)據(jù)獲取方案對(duì)比、消費(fèi)者消費(fèi)模型)
消息隊(duì)列適合哪些場(chǎng)景
消息隊(duì)列:它主要用來(lái)暫存生產(chǎn)者生產(chǎn)的消息,供后續(xù)其他消費(fèi)者來(lái)消費(fèi)。
它的功能主要有兩個(gè):
- 暫存(存儲(chǔ))
- 隊(duì)列(有序:先進(jìn)先出)
其他大部分場(chǎng)景對(duì)數(shù)據(jù)的消費(fèi)沒(méi)有順序要求,主要用它的暫存能力 。
從目前互聯(lián)網(wǎng)應(yīng)用中使用消息隊(duì)列的場(chǎng)景來(lái)看,主要有以下三個(gè):
- 異步處理數(shù)據(jù)
- 系統(tǒng)應(yīng)用解耦
- 業(yè)務(wù)流量削峰
下面對(duì)上述每一種場(chǎng)景進(jìn)行簡(jiǎn)單描述。
①異步處理數(shù)據(jù)
第一個(gè)例子我們以現(xiàn)實(shí)生活中送快遞來(lái)類比,在該例子中我們把暫存快遞的快遞柜比作暫存數(shù)據(jù)的消息隊(duì)列。
我們來(lái)看一下在現(xiàn)實(shí)生活中,沒(méi)有快遞柜時(shí),快遞員把快遞送到目的地后,一般需要聯(lián)系收貨人來(lái)簽收快遞,如果收貨人此時(shí)有空,那一切都很順利。但如果收貨人此時(shí)不方便(開(kāi)會(huì)、正在吃午飯、外出出差……)。
那對(duì)于快遞員而言,就很尷尬,需要一直等待(開(kāi)會(huì) or 吃午飯)或者將快遞拿回去(外出出差),導(dǎo)致白跑一趟。這對(duì)于快遞員而言簡(jiǎn)直太不友好。
從這兒可以看出,當(dāng)快遞員送貨時(shí),是一個(gè)同步狀態(tài),即需要等待收貨人簽收后才能去送下一趟單子,對(duì)快遞員而言效率太低。上述例子雖然有點(diǎn)牽強(qiáng),大家湊合理解,意思能大概理解到位就 ok。
接著我們?cè)賮?lái)看一下,當(dāng)有了快遞柜后,對(duì)于快遞員而言,每次需要送快遞時(shí),只需要將快遞投擲到快遞柜,然后再通過(guò)短信或者電話通知收貨人具體的快遞信息即可。
他就可以繼續(xù)去派送下一單。而對(duì)于收獲人而言,也可以根據(jù)具體方便的時(shí)間來(lái)取件。這樣一來(lái),二者完全異步了,不用相互等待了。
在這個(gè)例子中,如果把快遞員比作生產(chǎn)者,收貨人比作是消費(fèi)者,則快遞柜就類似于消息隊(duì)列。我們可以通過(guò)采用消息隊(duì)列來(lái)實(shí)現(xiàn)異步數(shù)據(jù)的處理。
②系統(tǒng)應(yīng)用解耦
案例二,我們以目前最主流的推薦系統(tǒng)中內(nèi)容的流轉(zhuǎn)來(lái)舉例。在推薦系統(tǒng)中當(dāng)創(chuàng)作者發(fā)布了一條內(nèi)容后,該內(nèi)容會(huì)首先經(jīng)過(guò)安全部分的相關(guān)審核,通過(guò)審核后的內(nèi)容,通常需要進(jìn)行內(nèi)容入庫(kù)存儲(chǔ)、送入模型進(jìn)行特征的計(jì)算和生成。
假如后期我們想提升推薦的效果,需要單獨(dú)構(gòu)建一份冷啟動(dòng)的推薦池,此時(shí)也需要用到這部分內(nèi)容,那問(wèn)題來(lái)了,在沒(méi)有使用消息隊(duì)列時(shí),對(duì)于上游服務(wù)而言,需要通過(guò)擴(kuò)展新的邏輯來(lái)實(shí)現(xiàn)該功能。
同時(shí)在該場(chǎng)景里,會(huì)存在依賴三個(gè)下游服務(wù),如果其中一個(gè)下游服務(wù)失敗后,該如何處理,是重試還是返回失敗等這些細(xì)節(jié)的處理。
如果后期這部分?jǐn)?shù)據(jù)還想在其他渠道分發(fā),那又該如何對(duì)接。明顯這種場(chǎng)景下面臨著系統(tǒng)緊耦合的問(wèn)題。
我們?cè)賮?lái)看一下,如果我們一開(kāi)始就引入了消息隊(duì)列,那問(wèn)題又會(huì)變成怎樣的呢?
當(dāng)內(nèi)容審核通過(guò)后,就直接將數(shù)據(jù)生產(chǎn)出來(lái)丟到消息隊(duì)列中,下游的多個(gè)服務(wù)再?gòu)南㈥?duì)列消費(fèi)數(shù)據(jù)。
當(dāng)后續(xù)這一份數(shù)據(jù)需要擴(kuò)展供其他系統(tǒng)使用時(shí),也只要通過(guò)新的消費(fèi)者來(lái)接入到消息隊(duì)列消費(fèi)就 ok。
上游生產(chǎn)消息的模塊不要做任何的改動(dòng)。這樣我們就通過(guò)消息隊(duì)列進(jìn)行了系統(tǒng)應(yīng)用之間的解耦。這是消息隊(duì)列的第二個(gè)用途。
③業(yè)務(wù)流量削峰
消息對(duì)應(yīng)的第三個(gè)使用場(chǎng)景便是削峰。在現(xiàn)如今的互聯(lián)網(wǎng)世界中,電商場(chǎng)景中每年的 618 秒殺活動(dòng)、雙 11 搶購(gòu)便是最典型的案例。
這種場(chǎng)景中系統(tǒng)的峰值流量往往集中于一小段時(shí)間內(nèi),平常的流量比較可控,所以為了防止系統(tǒng)在短時(shí)間內(nèi)的峰值流量沖垮,往往采用消息隊(duì)列來(lái)削弱峰值流量。
高峰值期間產(chǎn)生的訂單消息等數(shù)據(jù)首先送入到消息隊(duì)列中暫存,然后供下游系統(tǒng)根據(jù)自己的消費(fèi)能力來(lái)逐步處理。
同時(shí)這類消息往往對(duì)時(shí)延的要求不是很高,比較適合采用消息隊(duì)列暫存。
我們?cè)趯?duì)本節(jié)的內(nèi)容做一個(gè)簡(jiǎn)單的總結(jié),上面通過(guò)三個(gè)簡(jiǎn)單的實(shí)例介紹了消息隊(duì)列的典型的三個(gè)使用場(chǎng)景:異步、解耦、削峰。
換個(gè)角度來(lái)理解可以看到,消息隊(duì)列主要適用于處理對(duì)消息要求不是很實(shí)時(shí),同時(shí)一份數(shù)據(jù)可能會(huì)多處使用的場(chǎng)景,不同的使用方處理速率不同。更多的消息隊(duì)列的使用場(chǎng)景讀者可以自行找資料閱讀和總結(jié)。
消息隊(duì)列“家族”有哪些成員
①消息隊(duì)列主流產(chǎn)品
上圖根據(jù)時(shí)間線展示了不同時(shí)間點(diǎn)產(chǎn)生的消息隊(duì)列產(chǎn)品,主要的產(chǎn)品有:
- ActiveMQ(2003)
- RabbitMQ(2006)
- Kafka(2010)
- RocketMQ(2011)
- Pulsar(2012)
這些消息隊(duì)列中或多或少我們都聽(tīng)過(guò)一些,部分也在項(xiàng)目中真實(shí)使用過(guò)。下面對(duì)上述幾個(gè)消息隊(duì)列做一個(gè)簡(jiǎn)單的介紹。
ActiveMQ:ActiveMQ 由 Apache 軟件基金會(huì)基于 Java 語(yǔ)言開(kāi)發(fā)的一個(gè)開(kāi)源的消息代理。
能夠支持多個(gè)客戶機(jī)或服務(wù)器。計(jì)算機(jī)集群等屬性支持 ActiveMQ 來(lái)管理通信系統(tǒng)。
RabbitMQ:RabbitMQ 是實(shí)現(xiàn)了高級(jí)消息隊(duì)列協(xié)議(AMQP)的開(kāi)源消息代理軟件(亦稱面向消息的中間件)。
RabbitMQ 服務(wù)器是用 Erlang 語(yǔ)言編寫的,而集群和故障轉(zhuǎn)移是構(gòu)建在開(kāi)放電信平臺(tái)框架上的。
所有主要的編程語(yǔ)言均有與代理接口通訊的客戶端庫(kù)。RabbitMQ 支持多種消息傳遞協(xié)議、傳遞確認(rèn)等特性。
Kafka:Apache Kafka 是由 Apache 軟件基金會(huì)開(kāi)發(fā)的一個(gè)開(kāi)源消息系統(tǒng)項(xiàng)目,由 Scala 寫成。
Kafka 最初是由 LinkedIn 開(kāi)發(fā),并于 2011 年初開(kāi)源。2012 年 10 月從 Apache Incubator 畢業(yè)。
該項(xiàng)目的目標(biāo)是為處理實(shí)時(shí)數(shù)據(jù)提供一個(gè)統(tǒng)一、高通量、低等待的平臺(tái)。Kafka 是一個(gè)分布式的、分區(qū)的、多復(fù)本的日志提交服務(wù)。它通過(guò)一種獨(dú)一無(wú)二的設(shè)計(jì)提供了一個(gè)消息系統(tǒng)的功能。
RocketMQ:Apache RocketMQ 是一個(gè)分布式消息和流媒體平臺(tái),具有低延遲、強(qiáng)一致、高性能和可靠性、萬(wàn)億級(jí)容量和靈活的可擴(kuò)展性。它有借鑒 Kafka 的設(shè)計(jì)思想,但不是 Kafka 的拷貝。
Pulsar:Apache Pulsar 是 Apache 軟件基金會(huì)頂級(jí)項(xiàng)目,是下一代云原生分布式消息流平臺(tái),集消息、存儲(chǔ)、輕量化函數(shù)式計(jì)算為一體,采用計(jì)算與存儲(chǔ)分離架構(gòu)設(shè)計(jì)。
支持多租戶、持久化存儲(chǔ)、多機(jī)房跨區(qū)域數(shù)據(jù)復(fù)制,具有強(qiáng)一致性、高吞吐、低延時(shí)及高可擴(kuò)展性等流數(shù)據(jù)存儲(chǔ)特性,被看作是云原生時(shí)代實(shí)時(shí)消息流傳輸、存儲(chǔ)和計(jì)算最佳解決方案。
②不同消息隊(duì)列對(duì)比
上圖詳細(xì)的展示了幾種消息隊(duì)列的各自功能及優(yōu)缺點(diǎn),首先,ActiveMQ 和 RabbitMQ 二者屬于同一量級(jí),在吞吐量上比后面三者差一個(gè)量級(jí)。
其次,支持強(qiáng)一致性的有 RocketMQ 和 Pulsar,在對(duì)消息一致性要求比較高的場(chǎng)景可以采用這些產(chǎn)品。
同時(shí) Kafka 雖然會(huì)有數(shù)據(jù)丟失的風(fēng)險(xiǎn),但其吞吐量比較高同時(shí)社區(qū)非常活躍,在大數(shù)據(jù)的絕大部分場(chǎng)景里,都可以采用 Kafka。
最后 Kafka、RocketMQ、Pulsar 這幾款是基于磁盤存儲(chǔ)數(shù)據(jù)的,內(nèi)存加速訪問(wèn)。
而 ActiveMQ、RabbitMQ 采用內(nèi)存存儲(chǔ)數(shù)據(jù),也支持?jǐn)?shù)據(jù)持久化到磁盤。
消息隊(duì)列背后的設(shè)計(jì)思想
在前面,第一節(jié)內(nèi)容中,主要介紹了為什么要使用消息隊(duì)列,消息隊(duì)列適合解決哪些問(wèn)題?
在第二節(jié)內(nèi)容中,又介紹了有哪些可選擇的消息隊(duì)列,以及他們之間各自的優(yōu)缺點(diǎn)。
這一節(jié)是最重要的內(nèi)容,主要會(huì)介紹一下上述消息隊(duì)列背后的通用的一些設(shè)計(jì)思想。
部分思想可以擴(kuò)展到其他的業(yè)務(wù)模型或者領(lǐng)域內(nèi)。后面講到對(duì)應(yīng)內(nèi)容也會(huì)有所提及。
①消息隊(duì)列核心模型
上圖是幾乎所有消息隊(duì)列設(shè)計(jì)的一個(gè)核心模型。對(duì)于一個(gè)消息隊(duì)列而言,從數(shù)據(jù)流向的維度,可以拆解為三大部分:生產(chǎn)者、消息隊(duì)列集群、消費(fèi)者。
數(shù)據(jù)是從生產(chǎn)者流向消息隊(duì)列集群,最終再?gòu)南㈥?duì)列集群流向消費(fèi)者,下面對(duì)這幾個(gè)概念進(jìn)行一一闡述。
生產(chǎn)者:生產(chǎn)數(shù)據(jù)的服務(wù),通常也稱為數(shù)據(jù)的輸入提供方,這里的數(shù)據(jù)通常指我們的業(yè)務(wù)數(shù)據(jù),例如推薦場(chǎng)景中用戶對(duì)內(nèi)容的點(diǎn)擊數(shù)據(jù)、內(nèi)容曝光數(shù)據(jù)、電商中的訂單數(shù)據(jù)等等。
生產(chǎn)者通常是作為客戶端的方式存在,但在支持事務(wù)消息的消息隊(duì)列中,生產(chǎn)者也被設(shè)計(jì)為服務(wù)端,實(shí)現(xiàn)事務(wù)消息這一特性。
其次生產(chǎn)者通常會(huì)有多個(gè),消息隊(duì)列集群內(nèi)部也會(huì)有多個(gè)分區(qū)隊(duì)列,所以在生產(chǎn)者發(fā)送數(shù)據(jù)時(shí),通常會(huì)存在負(fù)載均衡的一些策略,常見(jiàn)的有按 key hash、輪詢、隨機(jī)等方式。
其本質(zhì)是一條數(shù)據(jù),被消息隊(duì)列封裝后也被稱為一條消息,該條消息只能發(fā)送到其消息隊(duì)列集群內(nèi)部的一個(gè)分區(qū)隊(duì)列中。因此只需按照一定的策略從多個(gè)隊(duì)列中選擇一個(gè)隊(duì)列即可。
消息隊(duì)列集群:消息隊(duì)列集群是消息隊(duì)列這種組件實(shí)現(xiàn)中的核心中的核心,它的主要功能是存儲(chǔ)消息、過(guò)濾消息、分發(fā)消息。
其中存儲(chǔ)消息主要指生產(chǎn)者生產(chǎn)的數(shù)據(jù)需要存儲(chǔ)到消息隊(duì)列內(nèi)部;存儲(chǔ)消息可以說(shuō)是消息隊(duì)列的核心,一個(gè)消息隊(duì)列吞吐量的高低、性能優(yōu)劣都和它的存儲(chǔ)模型脫不開(kāi)關(guān)系。這部分內(nèi)容會(huì)在下一部分進(jìn)行介紹。
過(guò)濾消息只指消息隊(duì)列可以通過(guò)一定的規(guī)則或者策略進(jìn)行消息的過(guò)濾,該項(xiàng)能力通常也被稱為消息路由。
過(guò)濾消息屬于高階的特性功能,AMQP 協(xié)議對(duì)這些能力抽象的比較完備,部分消息隊(duì)列可以選擇性的實(shí)現(xiàn)該協(xié)議來(lái)達(dá)到該功能,關(guān)于 AMQP 協(xié)議內(nèi)容讀者可以自行搜索資料閱讀,此處不再展開(kāi)。
分發(fā)消息是指消息隊(duì)列通常需要將消息分發(fā)給處理同一邏輯的多個(gè)消費(fèi)者處理或者處理不同邏輯的不同消費(fèi)者處理。
分發(fā)消息可以說(shuō)和消費(fèi)者模型想掛鉤,這塊會(huì)涉及到不同的數(shù)據(jù)獲取方式,也會(huì)涉及到消費(fèi)者消費(fèi)消息的模型。
此外絕大部分的消息隊(duì)列也都支持對(duì)消息進(jìn)行分類,分類的標(biāo)簽稱為 topic(主題),一個(gè) topic 中存放的是同一類消息。
消費(fèi)者:最終消息隊(duì)列存儲(chǔ)的消息會(huì)被消費(fèi)者消費(fèi)使用,消費(fèi)者也可以看做消息隊(duì)列中數(shù)據(jù)的輸出方。
消費(fèi)者通常有兩種方式從消息隊(duì)列中獲取數(shù)據(jù):推送(push)數(shù)據(jù)、拉取(pull)數(shù)據(jù)。其次消費(fèi)者也經(jīng)常是作為客戶端的角色出現(xiàn)在在消息隊(duì)列這種組件中。
②消息隊(duì)列數(shù)據(jù)組織方式
在這一節(jié)中,我們?cè)敿?xì)看看消息隊(duì)列存儲(chǔ)消息這個(gè)環(huán)節(jié)的一些權(quán)衡考量,通常數(shù)據(jù)的存儲(chǔ)無(wú)外乎就是兩種:
- 一種是存儲(chǔ)在非易失性存儲(chǔ)中,例如磁盤這種介質(zhì)。
- 另一種是選擇存儲(chǔ)在易失性存儲(chǔ)中,典型的就是內(nèi)存。
關(guān)于二者的對(duì)比大家可以參考下表,此處就不再贅述。
通常在大部分組件設(shè)計(jì)時(shí),往往會(huì)選擇一種主要介質(zhì)來(lái)存儲(chǔ)、另一種介質(zhì)作為輔助使用。
就拿 Redis 來(lái)說(shuō),它主要采用內(nèi)存存儲(chǔ)數(shù)據(jù),磁盤用來(lái)做輔助的持久化。拿 RabbitMQ 舉例,它也是主要采用內(nèi)存存儲(chǔ)消息,但也支持將消息持久化到磁盤。
而 RocketMQ、Kafka、Pulsar 這種,則是數(shù)據(jù)主要存儲(chǔ)在磁盤,通過(guò)內(nèi)存來(lái)助力提升系統(tǒng)的性能。
關(guān)系型數(shù)據(jù)庫(kù)例如 MySQL 這種組件也是主要采用磁盤組織數(shù)據(jù),合理利用內(nèi)存提升性能。
針對(duì)采用內(nèi)存存儲(chǔ)數(shù)據(jù)的方案而言,難點(diǎn)一方面在于如何在不降低訪問(wèn)效率的情況下,充分利用有限的內(nèi)存空間來(lái)存儲(chǔ)盡可能多的數(shù)據(jù),這個(gè)過(guò)程中少不了對(duì)數(shù)據(jù)結(jié)構(gòu)的選型、優(yōu)化。
另一方面在于如何保證數(shù)據(jù)盡可能少的丟失,我們可以看到針對(duì)此問(wèn)題的解決方案通常是快照+廣泛意義的 wal 文件來(lái)解決。此類典型的代表就是 Redis 啦。
針對(duì)采用磁盤存儲(chǔ)數(shù)據(jù)的方案而言,難點(diǎn)一方面在于如何根據(jù)系統(tǒng)所要解決的特點(diǎn)場(chǎng)景進(jìn)行合理的對(duì)磁盤布局。
讀多寫少情況下采用 B+ 樹(shù)方式存儲(chǔ)數(shù)據(jù);寫多讀少情況下采用 lsm tree 這類方案處理。
另一方面在于如何盡可能減少對(duì)磁盤的頻繁訪問(wèn),一些做法是采用 mmap 進(jìn)行內(nèi)存映射,提升讀性能;還有一些則是采用緩存機(jī)制緩存頻繁訪問(wèn)的數(shù)據(jù)。
還有一些則是采用巧妙的數(shù)據(jù)結(jié)構(gòu)布局,充分利用磁盤預(yù)讀特性保證系統(tǒng)性能。
總的來(lái)說(shuō),針對(duì)寫磁盤的優(yōu)化,要不采用順序?qū)懱嵘阅?、要不采用異步寫磁盤提升性能(異步寫磁盤時(shí)需要結(jié)合 wal 保證數(shù)據(jù)的持久化,事實(shí)上 wal 也主要采用順序?qū)懙奶匦?。
針對(duì)讀磁盤的優(yōu)化,一方面是緩存、另一方面是 mmap 內(nèi)存映射加速讀。
上述這些存儲(chǔ)方案上權(quán)衡的選擇在 Kafka、RocketMQ、Pulsar 中都可以看到。
其實(shí)拋開(kāi)消息隊(duì)列而言,這些存儲(chǔ)方案的選擇上無(wú)論是關(guān)系型數(shù)據(jù)庫(kù)還是 kv 型組件都是通用的。
下圖列舉了幾種磁盤上的數(shù)據(jù)組織方式,僅供大家參考:
③獲取數(shù)據(jù)的推、拉兩種方案對(duì)比
在前面提到,消費(fèi)者在從消息隊(duì)列中獲取數(shù)據(jù)時(shí),主要有兩種方案:
- 等待推送數(shù)據(jù)
- 主動(dòng)拉取數(shù)據(jù)
目前的消息隊(duì)列實(shí)現(xiàn)時(shí),都會(huì)選擇支持兩種的至少一種,關(guān)于這兩種方案的對(duì)比,大家可以參考下表。
在此處,個(gè)人想拋開(kāi)消息隊(duì)列談一點(diǎn)關(guān)于這兩種方案的理解,其實(shí)推拉模型不僅僅只用于消息隊(duì)列這種組件中,更一般意義上,它解決的其實(shí)是數(shù)據(jù)傳送雙方的一個(gè)問(wèn)題。
本質(zhì)是數(shù)據(jù)需要從一方流向另一方。順著這個(gè)思路來(lái)看,下面這三個(gè)例子都是遵循這個(gè)原則。
網(wǎng)絡(luò)中傳輸?shù)臄?shù)據(jù):在 IO 多路復(fù)用中,以 epoll 為例,當(dāng)內(nèi)核檢測(cè)到監(jiān)聽(tīng)的描述符有數(shù)據(jù)到來(lái)時(shí),epoll_wait() 阻塞會(huì)返回,上層用戶態(tài)程序就知道有數(shù)據(jù)就緒了,然后可以通過(guò) read() 系統(tǒng)調(diào)用函數(shù)讀取數(shù)據(jù)。
這個(gè)過(guò)程就緒通知,類似于推送,但推送的不是數(shù)據(jù),而是數(shù)據(jù)就緒的信號(hào)。具體的數(shù)據(jù)獲取方式還是需要通過(guò)拉取的方式來(lái)主動(dòng)讀。
Feeds 流系統(tǒng)用戶時(shí)間線后臺(tái)實(shí)現(xiàn)方案(讀擴(kuò)散、寫擴(kuò)散): 讀擴(kuò)散和寫擴(kuò)散更是這樣一個(gè) case。
對(duì)于讀擴(kuò)散而言,主要采用拉取的方式獲取數(shù)據(jù)。而對(duì)于寫擴(kuò)散而言,它是典型的數(shù)據(jù)推送的方式。當(dāng)然在系統(tǒng)實(shí)現(xiàn)中,更復(fù)雜的場(chǎng)景往往會(huì)選擇讀寫結(jié)合的思路來(lái)實(shí)現(xiàn)。
生活中的點(diǎn)外賣例子:當(dāng)下單點(diǎn)外賣時(shí),通常也會(huì)有兩種方式可以選擇:外賣派送、到店自取。
不過(guò)通常外賣派送比較實(shí)時(shí),我們通常就選擇這種方式了而已??梢钥闯鐾赓u派送其實(shí)就是一種推的方式,而到店自取,則是拉的方式。
④消息隊(duì)列消費(fèi)模型
本節(jié)我們來(lái)介紹最后一部分內(nèi)容,消息隊(duì)列中消費(fèi)者的消費(fèi)模型。下圖中上半部分展示了最簡(jiǎn)單的一種消費(fèi)模型。一個(gè)生產(chǎn)者、一個(gè)消費(fèi)者。
但往往我們的一份數(shù)據(jù)通常會(huì)被不同場(chǎng)景所使用。那這個(gè)時(shí)候,首先就會(huì)存在每種場(chǎng)景需要使用全量的數(shù)據(jù)、而且不同場(chǎng)景之間不會(huì)相關(guān)影響,彼此獨(dú)立。
方便理解起見(jiàn),我們假設(shè)有 N 個(gè)場(chǎng)景需要使用這同一份數(shù)據(jù),每個(gè)場(chǎng)景需要消費(fèi)全量的數(shù)據(jù)。
而在 N 個(gè)場(chǎng)景中的一種場(chǎng)景里,又會(huì)有多個(gè)消費(fèi)者一起分?jǐn)傁M(fèi)這些數(shù)據(jù)。我們假設(shè)一個(gè)場(chǎng)景里有 M 個(gè)消費(fèi)者。由于每個(gè)場(chǎng)景中包含 M 個(gè)消費(fèi)者,我們也將其采用消費(fèi)者組來(lái)描述。
通過(guò)上面的介紹,我們可以用下面一句話總結(jié)消息隊(duì)列中的消費(fèi)模型:消費(fèi)者消費(fèi)者模型其實(shí)是一個(gè) 1:N:M 的關(guān)系,一份數(shù)據(jù)被 N 個(gè)消費(fèi)者組獨(dú)立使用,每個(gè)消費(fèi)者組中有 M 個(gè)消費(fèi)者進(jìn)行分?jǐn)傁M(fèi)。
其實(shí)這種模型也稱為發(fā)布訂閱模型,對(duì)于一條消息而言,組間廣播、組內(nèi)單播。一條消息只能被一個(gè)消費(fèi)者組中的一個(gè)消費(fèi)者使用。
在消費(fèi)者組內(nèi)部也存在一些負(fù)載均衡的策略。常用的有:輪詢、隨機(jī)、hash、一致性 hash 等方案。
這部分內(nèi)容我們重點(diǎn)介紹了關(guān)于消息隊(duì)列背后的一些設(shè)計(jì)思想,其中包括:消息隊(duì)列的核心模型、數(shù)據(jù)存儲(chǔ)模型、推拉方案獲取數(shù)據(jù)對(duì)比、消費(fèi)者消費(fèi)模型。
其中數(shù)據(jù)存儲(chǔ)模型不僅僅適用于消息隊(duì)列,也同樣適用于其他數(shù)據(jù)存儲(chǔ)組件的方案選擇。
同理數(shù)據(jù)獲取的推拉兩種方案也不僅僅局限于消息隊(duì)列。我們可以在很多業(yè)務(wù)場(chǎng)景里看到同類思想的影子。
總結(jié)
到此,本文也就告一段落了。本文主要從理論、抽象層面泛泛的談了下關(guān)于消息隊(duì)列的一些思想和理念。
主要介紹了消息隊(duì)列的使用場(chǎng)景,主流的消息隊(duì)列可選方案以及他們之間的優(yōu)缺點(diǎn)。
最后介紹了一些關(guān)于消息隊(duì)列背后的設(shè)計(jì)理念。本文只是拋磚引玉,希望上述內(nèi)容能輔助大家一起重新認(rèn)識(shí)消息隊(duì)列。
后面會(huì)逐步挑選上述的幾種消息隊(duì)列(Kafka、RocketMQ、Pulsar),重點(diǎn)分析其內(nèi)部實(shí)現(xiàn)機(jī)制,敬請(qǐng)期待。限于個(gè)人水平有限,理解有誤之處歡迎大家批評(píng)指正。
參考資料:
- ActiveMQ 與 RabbitMQ 的區(qū)別
- Kafka、ActiveMQ、RabbitMQ、RocketMQ 區(qū)別以及高可用原理
- Kafka、RabbitMQ、RocketMQ 等消息中間件的對(duì)比
- Apache Pulsar 在騰訊計(jì)費(fèi)場(chǎng)景下的應(yīng)用
- kafka Push vs. pull
- 消息隊(duì)列-推/拉模式學(xué)習(xí) & ActiveMQ 及 JMS 學(xué)習(xí)
作者:文小飛
簡(jiǎn)介:騰訊 Cloud9 項(xiàng)目組后臺(tái)開(kāi)發(fā)工程師。2 年后臺(tái)開(kāi)發(fā)經(jīng)驗(yàn),熟悉推薦系統(tǒng)后臺(tái)工作;對(duì)網(wǎng)絡(luò)、存儲(chǔ)、分布式共識(shí)算法(raft)等技術(shù)比較感興趣。
編輯:陶家龍
出處:轉(zhuǎn)載自公眾號(hào)半路出家的后臺(tái)技術(shù)人(ID:wenxiaofeiCode)
當(dāng)前文章:Kafka、RocketMQ、Pulsar全方位對(duì)比!
網(wǎng)頁(yè)路徑:http://www.5511xx.com/article/ccejjdh.html


咨詢
建站咨詢
