當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 架構(gòu)師社區(qū)
[導(dǎo)讀]在開(kāi)源的業(yè)界已經(jīng)有這么多消息隊(duì)列中間件了,Pulsar 作為一個(gè)新勢(shì)力到底有什么優(yōu)點(diǎn)呢?

在開(kāi)源的業(yè)界已經(jīng)有這么多消息隊(duì)列中間件了,Pulsar 作為一個(gè)新勢(shì)力到底有什么優(yōu)點(diǎn)呢?

Pulsar 自從出身就不斷的再和其他的消息隊(duì)列(Kafka,RocketMQ 等等)做比較。

但是 Pulsar 的設(shè)計(jì)思想和大多數(shù)的消息隊(duì)列中間件都不同,具備了高吞吐,低延遲,計(jì)算存儲(chǔ)分離,多租戶,異地復(fù)制等功能。

所以 Pulsar 也被譽(yù)為下一代消息隊(duì)列中間件,接下來(lái)我會(huì)一一對(duì)其進(jìn)行詳細(xì)的解析。

Pulsar 架構(gòu)原理

Pulsar 架構(gòu)原理如下圖:

再見(jiàn),Kafka!再見(jiàn),RocketMQ!

再見(jiàn),Kafka!再見(jiàn),RocketMQ!

整體的架構(gòu)和其他的消息隊(duì)列中間件差別不是太大,相信大家也看到了很多熟悉的名詞,接下來(lái)會(huì)給大家一一解釋這些名詞的含義。

名詞解釋?zhuān)?/span>

  • Producer:消息生產(chǎn)者,將消息發(fā)送到 Broker。

  • Consumer:消息消費(fèi)者,從 Broker 讀取消息到客戶端,進(jìn)行消費(fèi)處理。

  • Broker:可以看作是 Pulsar 的 Server,Producer 和 Consumer 都看作是 Client 消息處理的節(jié)點(diǎn)。

    Pulsar 的 Broker 和其他消息中間件的都不一樣,他是無(wú)狀態(tài)的沒(méi)有存儲(chǔ),所以可以無(wú)限制的擴(kuò)展,這個(gè)后面也會(huì)詳解講到。

  • Bookie:負(fù)責(zé)所有消息的持久化,這里采用的是 Apache Bookeeper。

  • ZK:和 Kafka 一樣 Pulsar 也是使用 ZK 保存一些元數(shù)據(jù),比如配置管理,Topic 分配,租戶等等。

  • Service Discovery:可以理解為 Pulsar 中的 Nginx,只用一個(gè) URL 就可以和整個(gè) Broker 進(jìn)行打交道,當(dāng)然也可以使用自己的服務(wù)發(fā)現(xiàn)。

    客戶端發(fā)出的讀取,更新或刪除主題的初始請(qǐng)求將發(fā)送給可能不是處理該主題的 Broker 。

    如果這個(gè) Broker 不能處理該主題的請(qǐng)求,Broker 將會(huì)把該請(qǐng)求重定向到可以處理主題請(qǐng)求的 Broker。



不論是 Kafka,RocketMQ 還是我們的 Pulsar 其實(shí)作為消息隊(duì)列中間件最為重要的大概就是分為三個(gè)部分:

  • Producer 是如何生產(chǎn)消息,發(fā)送到對(duì)應(yīng)的 Broker。

  • Broker 是如何處理消息,將高效的持久化以及查詢。

  • Consumer 是如何進(jìn)行消費(fèi)消息。


而我們后面也會(huì)圍繞著這三個(gè)部分進(jìn)行展開(kāi)講解。

Producer 生產(chǎn)消息

先簡(jiǎn)單看一下如何用代碼進(jìn)行消息發(fā)送:
PulsarClient client = PulsarClient.create("pulsar://pulsar.us-west.example.com:6650");

Producer producer = client.createProducer( "persistent://sample/standalone/ns1/my-topic"); // Publish 10 messages to the topic for (int i = 0; i < 10; i++) {
    producer.send("my-message".getBytes());
}

Step1:首先使用我們的 URL 創(chuàng)建一個(gè) Client 這個(gè) URL 是我們 Service Discovery 的地址,如果我們使用單機(jī)模式可以進(jìn)行直連。

Step2:我們傳入了一個(gè)類(lèi)似 URL 的參數(shù),我們只需要傳遞這個(gè)就能指定我們到底在哪個(gè) Topic 或者 Namespace 下面創(chuàng)建的,URL 的格式為:

{persistent|non-persistent}://tenant/namespace/topic 


再見(jiàn),Kafka!再見(jiàn),RocketMQ!

Step3: 調(diào)用 Send 方法發(fā)送消息,這里也提供了 sendAsync 方法支持異步發(fā)送。

上面三個(gè)步驟中,步驟 1,2 屬于我們準(zhǔn)備階段,用于構(gòu)建客戶端,構(gòu)建 Producer,我們真的核心邏輯在 Send 中。

那這里我先提幾個(gè)小問(wèn)題,大家可以先想想在其他消息隊(duì)列中是怎么做的,然后再對(duì)比 Pulsar 的看一下:

  • 我們調(diào)用了 Send 之后是會(huì)立即發(fā)送嗎?

  • 如果是多 Partition,怎么找到我應(yīng)該發(fā)送到哪個(gè) Broker 呢?

發(fā)送模式

我們上面說(shuō)了 Send 分為 Async 和 Sync 兩種模式,但實(shí)際上在 Pulsar 內(nèi)部 Sync 模式也是采用的 Async 模式,在 Sync 模式下模擬回調(diào)阻塞,達(dá)到同步的效果。

這個(gè)在 Kafka 中也是采用的這個(gè)模式,但是在 RocketMQ 中,所有的 Send 都是真正的同步,都會(huì)直接請(qǐng)求到 Broker。

基于這個(gè)模式,在 Pulsar 和 Kafka 中都支持批量發(fā)送,在 RocketMQ 中是直接發(fā)送,批量發(fā)送有什么好處呢?

當(dāng)我們發(fā)送的 TPS 特別高的時(shí)候,如果每次發(fā)送都直接和 Broker 直連,可能會(huì)做很多的重復(fù)工作,比如壓縮,鑒權(quán),創(chuàng)建鏈接等等。
比如我們發(fā)送 1000 條消息,那么可能會(huì)做 1000 次這個(gè)重復(fù)的工作,如果是批量發(fā)送的話這 1000 條消息合并成一次請(qǐng)求,相對(duì)來(lái)說(shuō)壓縮,鑒權(quán)這些工作就只需要做一次。

再見(jiàn),Kafka!再見(jiàn),RocketMQ!

有同學(xué)可能會(huì)問(wèn),批量發(fā)送會(huì)不會(huì)導(dǎo)致發(fā)送的時(shí)間會(huì)有一定的延誤?這個(gè)其實(shí)不需要擔(dān)心,在 Pulsar 中默認(rèn)定時(shí)每隔 1ms 發(fā)送一次 Batch,或者當(dāng) batchsize 默認(rèn)到了 1000 都會(huì)進(jìn)行發(fā)送,這個(gè)發(fā)送的頻率都還是很快的。

發(fā)送負(fù)載均衡

在消息隊(duì)列中通常會(huì)將 Topic 進(jìn)行水平擴(kuò)展,在 Pulsar 和 Kafka 中叫做 Partition,在 RocketMQ 中叫做 Queue,本質(zhì)上都是分區(qū),我們可以將不同分區(qū)落在不同的 Broker 上,達(dá)到我們水平擴(kuò)展的效果。

在我們發(fā)送的時(shí)候可以自己制定選擇 Partition 的策略,也可以使用它默認(rèn)輪訓(xùn) Partition 策略。

當(dāng)我們選擇了 Partition 之后,我們?cè)趺创_定哪一個(gè) Partition 對(duì)應(yīng)哪一個(gè) Broker 呢?

可以先看看下面這個(gè)圖:

再見(jiàn),Kafka!再見(jiàn),RocketMQ!

Step1:我們所有的信息分區(qū)映射信息在 ZK 和 Broker 的緩存中都有進(jìn)行存儲(chǔ)。

Step2:我們通過(guò)查詢 Broker,可以獲取到分區(qū)和 Broker 的關(guān)系,并且定時(shí)更新。

Step3:在 Pulsar 中每個(gè)分區(qū)在發(fā)送端的時(shí)候都被抽象成為一個(gè)單獨(dú)的 Producer,這個(gè)和 Kafka,RocketMQ 都不一樣。

在 Kafka 里面大概就是選擇了 Partition 之后然后再去找 Partition 對(duì)應(yīng)的 Broker 地址,然后進(jìn)行發(fā)送。
Pulsar 將每一個(gè) Partition 都封裝成 Producer,在代碼實(shí)現(xiàn)上就不需要去關(guān)注他具體對(duì)應(yīng)的是哪個(gè) Broker,所有的邏輯都在 Producer 這個(gè)代碼里面,整體來(lái)說(shuō)比較干凈。
再見(jiàn),Kafka!再見(jiàn),RocketMQ!

壓縮消息

消息壓縮是優(yōu)化信息傳輸?shù)氖侄沃唬覀兺ǔ?匆?jiàn)一些大型文件都會(huì)是以一個(gè)壓縮包的形式提供下載。

在我們消息隊(duì)列中我們也可以用這種思想,我們將一個(gè) Batch 的消息,比如有 1000 條可能有 1M 的傳輸大小,但是經(jīng)過(guò)壓縮之后可能就只會(huì)有幾十 KB,增加了我們和 Broker 的傳輸效率,但是與之同時(shí)我們的 CPU 也帶來(lái)了損耗。
Pulsar 客戶端支持多種壓縮類(lèi)型,如 lz4、zlib、zstd、snappy 等。

client.newProducer() .topic(“test-topic”) .compressionType(CompressionType.LZ4) .create();

Broker

接下來(lái)我們來(lái)說(shuō)說(shuō)第二個(gè)比較重要的部分 Broker,在 Broker 的設(shè)計(jì)中 Pulsar 和其他所有的消息隊(duì)列差別比較大,而正是因?yàn)檫@個(gè)差別也成為了他的特點(diǎn)。

計(jì)算和存儲(chǔ)分離

首先我們來(lái)說(shuō)說(shuō)他最大的特點(diǎn):計(jì)算和存儲(chǔ)分離。

我們?cè)陂_(kāi)始的說(shuō)過(guò) Pulsar 是下一代消息隊(duì)列,就非常得益于他這個(gè)架構(gòu)設(shè)計(jì),無(wú)論是 Kafka 還是 RocketMQ,所有的計(jì)算和存儲(chǔ)都放在同一個(gè)機(jī)器上。

這個(gè)模式有幾個(gè)弊端:

  • 擴(kuò)展困難:當(dāng)我們需要擴(kuò)展的集群的時(shí)候,我們通常是因?yàn)?CPU 或者磁盤(pán)其中一個(gè)原因影響,但是我們卻要申請(qǐng)一個(gè)可能 CPU 和磁盤(pán)配置都很好的機(jī)器,造成了資源浪費(fèi)。并且 Kafka 這種進(jìn)行擴(kuò)展,還需要進(jìn)行遷移數(shù)據(jù),過(guò)程十分繁雜。

  • 負(fù)載不均衡: 當(dāng)某些 Partion 數(shù)據(jù)特別多的時(shí)候,會(huì)導(dǎo)致 Broker 負(fù)載不均衡,如下面圖,如果某個(gè) Partition 數(shù)據(jù)特別多,那么就會(huì)導(dǎo)致某個(gè) Broker(輪船)承載過(guò)多的數(shù)據(jù),但是另外的 Broker 可能又比較空閑。

再見(jiàn),Kafka!再見(jiàn),RocketMQ!

Pulsar 計(jì)算分離架構(gòu)能夠非常好的解決這個(gè)問(wèn)題:
  • 對(duì)于計(jì)算:也就是我們的 Broker,提供消息隊(duì)列的讀寫(xiě),不存儲(chǔ)任何數(shù)據(jù),無(wú)狀態(tài)對(duì)于我們擴(kuò)展非常友好,只要你機(jī)器足夠,就能隨便上。

    擴(kuò)容 Broker 往往適用于增加 Consumer 的吞吐,當(dāng)我們有一些大流量的業(yè)務(wù)或者活動(dòng),比如電商大促,可以提前進(jìn)行 Broker 的擴(kuò)容。

  • 對(duì)于存儲(chǔ):也就是我們的 Bookie,只提供消息隊(duì)列的存儲(chǔ),如果對(duì)消息量有要求的,我們可以擴(kuò)容 Bookie,并且我們不需要遷移數(shù)據(jù),擴(kuò)容十分方便。

消息存儲(chǔ)

名詞解析:

再見(jiàn),Kafka!再見(jiàn),RocketMQ!

上圖是 Bookie 的讀寫(xiě)架構(gòu)圖,里面有一些名詞需要先介紹一下:
  • Entry:是存儲(chǔ)到 bookkeeper 中的一條記錄,其中包含 Entry ID,記錄實(shí)體等。

  • Ledger:可以認(rèn)為 ledger 是用來(lái)存儲(chǔ) Entry 的,多個(gè) Entry 序列組成一個(gè) ledger。

  • Journal:其實(shí)就是 bookkeeper 的 WAL(write ahead log),用于存 bookkeeper 的事務(wù)日志,journal 文件有一個(gè)最大大小,達(dá)到這個(gè)大小后會(huì)新起一個(gè) journal 文件。

  • Entry log:存儲(chǔ) Entry 的文件,ledger 是一個(gè)邏輯上的概念,entry 會(huì)先按 ledger 聚合,然后寫(xiě)入 entry log 文件中。同樣,entry log 會(huì)有一個(gè)最大值,達(dá)到最大值后會(huì)新起一個(gè)新的 entry log 文件。

  • Index file:ledger 的索引文件,ledger 中的 entry 被寫(xiě)入到了 entry log 文件中,索引文件用于 entry log 文件中每一個(gè) ledger 做索引,記錄每個(gè) ledger 在 entry log 中的存儲(chǔ)位置以及數(shù)據(jù)在 entry log 文件中的長(zhǎng)度。

  • MetaData Storage: 元數(shù)據(jù)存儲(chǔ),是用于存儲(chǔ) bookie 相關(guān)的元數(shù)據(jù),比如 bookie 上有哪些 ledger,bookkeeper 目前使用的是 zk 存儲(chǔ),所以在部署 bookkeeper 前,要先有 zk 集群。

再見(jiàn),Kafka!再見(jiàn),RocketMQ!

整體架構(gòu)上的寫(xiě)流程:

  • Step1:Broker 發(fā)起寫(xiě)請(qǐng)求,首先對(duì) Journal 磁盤(pán)寫(xiě)入 WAL,熟悉 MySQL 的朋友知道 redolog,journal 和 redolog 作用一樣都是用于恢復(fù)沒(méi)有持久化的數(shù)據(jù)。

  • Step2:然后再將數(shù)據(jù)寫(xiě)入 index 和 ledger,這里為了保持性能不會(huì)直接寫(xiě)盤(pán),而是寫(xiě) pagecache,然后異步刷盤(pán)。

  • Step3:對(duì)寫(xiě)入進(jìn)行 ack。

讀流程為:

  • Step1:先讀取 index,當(dāng)然也是先讀取 cache,再走 disk。

  • Step2:獲取到 index 之后,根據(jù) index 去 entry logger 中去對(duì)應(yīng)的數(shù)據(jù)。

如何高效讀寫(xiě)?在 Kafka 中當(dāng)我們的 Topic 變多了之后,由于 Kafka 一個(gè) Topic 一個(gè)文件,就會(huì)導(dǎo)致我們的磁盤(pán) IO 從順序?qū)懽兂呻S機(jī)寫(xiě)。

在 RocketMQ 中雖然將多個(gè) Topic 對(duì)應(yīng)一個(gè)寫(xiě)入文件,讓寫(xiě)入變成了順序?qū)懀俏覀兊淖x取很容易導(dǎo)致我們的 Pagecache 被各種覆蓋刷新,這對(duì)于我們的 IO 的影響是非常大的。

所以 Pulsar 在讀寫(xiě)兩個(gè)方面針對(duì)這些問(wèn)題都做了很多優(yōu)化:

寫(xiě)流程:順序?qū)?Pagecache。在寫(xiě)流程中我們的所有的文件都是獨(dú)立磁盤(pán),并且同步刷盤(pán)的只有 Journal。

Journal 是順序?qū)懸粋€(gè) journal-wal 文件,順序?qū)懶史浅8?。ledger 和 index 雖然都會(huì)存在多個(gè)文件,但是我們只會(huì)寫(xiě)入 Pagecache,異步刷盤(pán),所以隨機(jī)寫(xiě)不會(huì)影響我們的性能。

讀流程:broker cache+bookie cache,在 Pulsar 中對(duì)于追尾讀(tailing read)非常友好基本不會(huì)走 IO。

一般情況下我們的 Consumer 是會(huì)立即去拿 Producer 發(fā)送的消息的,所以這部分在持久化之后依然在 Broker 中作為 Cache 存在。

當(dāng)然就算 Broker 沒(méi)有 Cache(比如 Broker 是新建的),我們的 Bookie 也會(huì)在 Memtable 中有自己的 Cache,通過(guò)多重 Cache 減少讀流程走 IO。

我們可以發(fā)現(xiàn)在最理想的情況下讀寫(xiě)的 IO 是完全隔離開(kāi)來(lái)的,所以在 Pulsar 中能很容易就支持百萬(wàn)級(jí) Topic,而在我們的 Kafka 和 RocketMQ 中這個(gè)是非常困難的。

無(wú)限流式存儲(chǔ)
一個(gè) Topic 實(shí)際上是一個(gè) ledgers流(Segment),通過(guò)這個(gè)設(shè)計(jì)所以 Pulsar 他并不是一個(gè)單純的消息隊(duì)列系統(tǒng),他也可以代替流式系統(tǒng),所以他也叫流原生平臺(tái),可以替代 Flink 等系統(tǒng)。

再見(jiàn),Kafka!再見(jiàn),RocketMQ!

可以看見(jiàn)我們的 Event Stream(topic/partition),由多個(gè) Segment 存儲(chǔ)組成,而每個(gè) Segment 由 Entry 組成,這個(gè)可以看作是我們每批發(fā)送的消息通常會(huì)看作是一個(gè) Entry。

Segment 可以看作是我們寫(xiě)入文件的一個(gè)基本維度,同一個(gè) Segment 的數(shù)據(jù)會(huì)寫(xiě)在同一個(gè)文件上面,不同 Segment 將會(huì)是不同文件,而 Segment 之間的在 Metadata 中進(jìn)行保存。

再見(jiàn),Kafka!再見(jiàn),RocketMQ!

分層存儲(chǔ)
在 Kafka 和 RocketMQ 中消息是會(huì)有一定的保存時(shí)間的,因?yàn)榇疟P(pán)會(huì)有空間限制。
在 Pulsar 中也提供這個(gè)功能,但是如果你想讓自己的消息永久存儲(chǔ),那么可以使用分級(jí)存儲(chǔ),我們可以將一些比較老的數(shù)據(jù),定時(shí)的刷新到廉價(jià)的存儲(chǔ)中,比如 s3,那么我們就可以無(wú)限存儲(chǔ)我們的消息隊(duì)列了。

再見(jiàn),Kafka!再見(jiàn),RocketMQ!

數(shù)據(jù)復(fù)制
在 Pulsar 中的數(shù)據(jù)復(fù)制和 Kafka,RocketMQ 都有很大的不同,在其他消息隊(duì)列中通常是其他副本主動(dòng)同步,通常這個(gè)時(shí)間就會(huì)變得不可預(yù)測(cè)。

再見(jiàn),Kafka!再見(jiàn),RocketMQ!

而在 Pulsar 采用了類(lèi)似 Qurom 協(xié)議,給一組可用的 Bookie 池,然后并發(fā)的寫(xiě)入其中的一部分 Bookie,只要返回部分成功(通常大于 1/2)就好。
  • Ensemble Size(E):決定給定 Ledger 可用的 Bookie 池大小。

  • Write Quorum Size(Qw):指定 Pulsar 向其中寫(xiě)入 Entry 的 Bookie 數(shù)量。

  • Ack Quorum Size(Qa):指定必須 Ack 寫(xiě)入的 Bookie 數(shù)量。

采用這種并發(fā)寫(xiě)的方式,會(huì)更加高效的進(jìn)行數(shù)據(jù)復(fù)制,尤其是當(dāng)數(shù)據(jù)副本比較多的時(shí)候。

Consumer

接下來(lái)我們來(lái)聊聊 Pulsar 中最后一個(gè)比較重要的組成 Consumer。

訂閱模式

訂閱模式是用來(lái)定義我們的消息如何分配給不同的消費(fèi)者,不同消息隊(duì)列中間件都有自己的訂閱模式。

一般我們常見(jiàn)的訂閱模式有:

  • 集群模式:一條消息只能被一個(gè)集群內(nèi)的消費(fèi)者所消費(fèi)。

  • 廣播模式: 一條消息能被集群內(nèi)所有的消費(fèi)者消費(fèi)。

再見(jiàn),Kafka!再見(jiàn),RocketMQ!

在 Pulsar 中提供了 4 種訂閱模式,分別是:

獨(dú)占:顧名思義只能由一個(gè)消費(fèi)者獨(dú)占,如果同一個(gè)集群內(nèi)有第二個(gè)消費(fèi)者去注冊(cè),第二個(gè)就會(huì)失敗,這個(gè)適用于全局有序的消息。

災(zāi)備:加強(qiáng)版獨(dú)占,如果獨(dú)占的那個(gè)掛了,會(huì)自動(dòng)的切換到另外一個(gè)好的消費(fèi)者,但是還是只能由一個(gè)獨(dú)占。

共享模式:這個(gè)模式看起來(lái)有點(diǎn)像集群模式,一條消息也是只能被一個(gè)集群內(nèi)消費(fèi)者消費(fèi),但是和 RocketMQ 不同的是,RocketMQ 是以 Partition 維度,同一個(gè) Partition 的數(shù)據(jù)都會(huì)被發(fā)到一個(gè)機(jī)器上。

在 Pulsar 中消費(fèi)不會(huì)以 Partition 維度,而是輪訓(xùn)所有消費(fèi)者進(jìn)行消息發(fā)送。這有個(gè)什么好處呢?

如果你有 100 臺(tái)機(jī)器,但是你只有 10 個(gè) Partition 其實(shí)你只有 10 臺(tái)消費(fèi)者能運(yùn)轉(zhuǎn),但是在 Pulsar 中 100 臺(tái)機(jī)器都可以進(jìn)行消費(fèi)處理。

鍵共享:類(lèi)似上面說(shuō)的 Partition 維度去發(fā)送,在 RocketMQ 中同一個(gè) Key 的順序消息都會(huì)被發(fā)送到一個(gè) Partition。

但是這里不會(huì)有 Partition 維度,而只是按照 Key 的 Hash 去分配到固定的 Consumer,也解決了消費(fèi)者能力限制于 Partition 個(gè)數(shù)問(wèn)題。

消息獲取模式

不論是在 Kafka 還是在 RocketMQ 中我們都是 Client 定時(shí)輪訓(xùn)我們的 Broker 獲取消息,這種模式叫做長(zhǎng)輪訓(xùn)(Long-Polling)模式。

這種模式有一個(gè)缺點(diǎn)網(wǎng)絡(luò)開(kāi)銷(xiāo)比較大,我們來(lái)計(jì)算一下 Consumer 被消費(fèi)的時(shí)延,我們假設(shè) Broker 和 Consumer 之間的一次網(wǎng)絡(luò)延時(shí)為 R。

那么我們總共的時(shí)間為:

  • 當(dāng)某一條消息 A 剛到 Broker 的,這個(gè)時(shí)候 long-polling 剛好打包完數(shù)據(jù)返回,Broker 返回到 Consumer 這個(gè)時(shí)間為 R。

  • Consumer 又再次發(fā)送 Request 請(qǐng)求,這個(gè)又為 R。

  • 將我們的消息 A 返回給 Consumer 這里又為 R。

如果只考慮網(wǎng)絡(luò)時(shí)延,我們可以看見(jiàn)我們這條消息的消費(fèi)時(shí)延大概是 3R,所以我們必須想點(diǎn)什么對(duì)其進(jìn)行一些優(yōu)化。

有同學(xué)可能馬上就能想到,我們消息來(lái)了直接推送給我們的 Consumer 不就對(duì)了,這下我們的時(shí)延只會(huì)有一次 R,這個(gè)就是我們常見(jiàn)的推模式。

但是簡(jiǎn)單的推模式是有問(wèn)題的,如果我們有生產(chǎn)速度遠(yuǎn)遠(yuǎn)大于消費(fèi)速度,那么推送的消息肯定會(huì)干爆我們的內(nèi)存,這個(gè)就是背壓。

那么我們?cè)趺唇鉀Q背壓呢?我們就可以優(yōu)化推送方式,將其變?yōu)閯?dòng)態(tài)推送,我們結(jié)合 Long-polling,在 long-polling 請(qǐng)求時(shí)將 Buffer 剩余空間告知給 Broker,由 Broker 負(fù)責(zé)推送數(shù)據(jù)。

此時(shí) Broker 知道最多可以推送多少條數(shù)據(jù),那么就可以控制推送行為,不至于沖垮 Consumer。

舉個(gè)例子:Consumer 發(fā)起請(qǐng)求時(shí) Buffer 剩余容量為 100,Broker 每次最多返回 32 條消息。

那么 Consumer 的這次 long-polling 請(qǐng)求 Broker 將在執(zhí)行 3 次 Push(共 Push 96 條消息)之后返回 Response 給 Consumer(Response 包含 4 條消息)。

如果采用 long-polling 模型,Consumer 每發(fā)送一次請(qǐng)求 Broker 執(zhí)行一次響應(yīng)。

這個(gè)例子需要進(jìn)行 4 次 long-polling 交互(共 4 個(gè) Request 和 4 個(gè) Response,8 次網(wǎng)絡(luò)操作;Dynamic Push/Pull 中是 1 個(gè) Request,3 次 Push 和 1 個(gè) Response,共 5 次網(wǎng)絡(luò)操作)。

所以 Pulsar 就采用了這種消息獲取模式,從 Consumer 層進(jìn)一步優(yōu)化消息達(dá)到時(shí)間。

我覺(jué)得這個(gè)設(shè)計(jì)非常巧妙,很多中間件的這種 long-polling 模式都可以參考這種思想去做一個(gè)改善。

總結(jié)

Apache Pulsar 很多設(shè)計(jì)思想都和其他中間件不一樣,但無(wú)疑于其更加貼近于未來(lái)。

大膽預(yù)測(cè)一下其他的一些消息中間件未來(lái)的發(fā)展也都會(huì)向其靠攏,目前國(guó)內(nèi)的 Pulsar 使用者也是越來(lái)越多,騰訊云提供了 Pulsar 的云版本 TDMQ。

當(dāng)然還有一些其他的知名公司華為,知乎,虎牙等等有都在對(duì)其做一個(gè)逐步的嘗試,我相信 Pulsar 真的是一個(gè)趨勢(shì)。
最后也讓我想起了最近大江大河大結(jié)局的一句話:

所有的變化,都可能伴隨著痛苦和彎路,開(kāi)放的道路,也不會(huì)是闊野坦途,但大江大河,奔涌向前的趨勢(shì),不是任何險(xiǎn)灘暗礁,能夠阻擋的。道之所在,雖千萬(wàn)人吾往矣。


		

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱(chēng),數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱(chēng)"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉