背景
Apache Pulsar 是下一代分布式消息流平臺(tái),采用計(jì)算存儲(chǔ)分層架構(gòu)娱局,具備多租戶彰亥、高一致、高性能衰齐、百萬(wàn) topic任斋、數(shù)據(jù)平滑遷移等諸多優(yōu)勢(shì)。越來(lái)越多的企業(yè)正在使用 Pulsar 或者嘗試將 Pulsar 應(yīng)用到生產(chǎn)環(huán)境中耻涛。
騰訊把 Pulsar 作為計(jì)費(fèi)系統(tǒng)的消息總線來(lái)支撐千億級(jí)在線交易废酷。騰訊計(jì)費(fèi)體量龐大,要解決的核心問題就是必須確保錢貨一致抹缕。首先澈蟆,保證每一筆支付交易不出現(xiàn)錯(cuò)賬,做到高一致卓研、高可靠趴俘。其次,保證計(jì)費(fèi)承載的所有業(yè)務(wù) 7*24 可用奏赘,做到高可用寥闪、高性能。計(jì)費(fèi)消息總線必須具備這些能力磨淌。
Pulsar 架構(gòu)解析
在一致性方面疲憋,Pulsar 采用 Quorum 算法,通過(guò) write quorum 和 ack quorum 來(lái)保證分布式消息隊(duì)列的副本數(shù)和強(qiáng)一致寫入的應(yīng)答數(shù)(A>W/2)梁只。在性能方面缚柳,Pulsar 采用 Pipeline 方式生產(chǎn)消息埃脏,通過(guò)順序?qū)懞蜅l帶化寫入降低磁盤 IO 壓力,多種緩存減少網(wǎng)絡(luò)請(qǐng)求加快消費(fèi)效率喂击。
Pulsar 性能高主要體現(xiàn)在網(wǎng)絡(luò)模型剂癌、通信協(xié)議、隊(duì)列模型翰绊、磁盤 IO 和條帶化寫入佩谷。下面我會(huì)一一詳細(xì)講解。
網(wǎng)絡(luò)模型
Pulsar Broker 是一個(gè)典型的 Reactor 模型监嗜,主要包含一個(gè)網(wǎng)絡(luò)線程池谐檀,負(fù)責(zé)處理網(wǎng)絡(luò)請(qǐng)求,進(jìn)行網(wǎng)絡(luò)的收發(fā)以及編解碼裁奇,接著把請(qǐng)求通過(guò)請(qǐng)求隊(duì)列推送給核心線程池進(jìn)行處理桐猬。首先,Pulsar 采用多線程方式刽肠,充分利用現(xiàn)代系統(tǒng)的多核優(yōu)勢(shì)溃肪,把同一任務(wù)請(qǐng)求分配給同一個(gè)線程處理,盡量避免線程之間切換帶來(lái)的開銷音五。其次惫撰,Pulsar 采用隊(duì)列方式實(shí)現(xiàn)了網(wǎng)絡(luò)處理模塊及核心處理模塊的異步解耦,實(shí)現(xiàn)了網(wǎng)絡(luò)處理和文件 I/O 并行處理躺涝,極大地提高了整個(gè)系統(tǒng)的效率厨钻。
通信協(xié)議
信息(message)采用二進(jìn)制編碼,格式簡(jiǎn)單坚嗜;客戶端生成二進(jìn)制數(shù)據(jù)直接發(fā)送給 Pulsar 后端 broker夯膀,broker 端不解碼直接發(fā)送給 bookie 存儲(chǔ),存儲(chǔ)格式也是二進(jìn)制苍蔬,所以消息生產(chǎn)消費(fèi)過(guò)程沒有任何編解碼操作诱建。消息的壓縮以及批量發(fā)送都是在客戶端完成,這能進(jìn)一步提升 broker 處理消息的能力碟绑。
隊(duì)列模型
Pulsar 對(duì)主題(topic)進(jìn)行分區(qū)(partition),并盡量將不同的分區(qū)分配到不同的 Broker蜈敢,實(shí)現(xiàn)水平擴(kuò)展汽抚。Pulsar 支持在線調(diào)整分區(qū)數(shù)量,理論上支持無(wú)限吞吐量造烁。雖然 ZooKeeper 的容量和性能會(huì)影響 broker 個(gè)數(shù)和分區(qū)數(shù)量否过,但該限制上限非常大午笛,可以認(rèn)為沒有上限苗桂。
磁盤 IO
消息隊(duì)列屬于磁盤 IO 密集型系統(tǒng),所以優(yōu)化磁盤 IO 至關(guān)重要煤伟。Pulsar 中的磁盤相關(guān)操作主要分為操作日志和數(shù)據(jù)日志兩類癌佩。操作日志用于數(shù)據(jù)恢復(fù),采用完全順序?qū)懙哪J奖阆牵瑢懭氤晒纯烧J(rèn)為生產(chǎn)成功围辙,因此 Pulsar 可以支持百萬(wàn)主題放案,不會(huì)因?yàn)殡S機(jī)寫而導(dǎo)致性能急劇下降。
操作日志也可以是亂序的掸冤,這樣可以讓操作日志寫入保持最佳寫入速率友雳,數(shù)據(jù)日志會(huì)進(jìn)行排序和去重,雖然出現(xiàn)寫放大的情況沥阱,但是這種收益是值得的:通過(guò)將操作日志和數(shù)據(jù)日志掛在到不同的磁盤上,將讀寫 IO 分離考杉,進(jìn)一步提升整個(gè)系統(tǒng) IO 相關(guān)的處理能力。
條帶化寫入
條帶化寫入能夠利用更多的 bookie 節(jié)點(diǎn)來(lái)進(jìn)行 IO 分擔(dān)咽袜;Bookie 設(shè)置了寫緩存和讀緩存枕稀。最新的消息放在寫緩存询刹,其他消息會(huì)批量從文件讀取加入到讀緩存中萎坷,提升讀取效率。
從架構(gòu)來(lái)看蔽挠,Pulsar 在處理消息的各個(gè)流程中沒有明顯的卡點(diǎn)瓜浸。操作日志持久化只有一個(gè)線程來(lái)負(fù)責(zé)刷盤比原,可能會(huì)造成卡頓杠巡。根據(jù)磁盤特性,可以設(shè)置多塊盤氢拥,多個(gè)目錄,提升磁盤讀寫性能厘线,這完全能夠滿足我們的需求出革。
測(cè)試
在騰訊計(jì)費(fèi)場(chǎng)景中造壮,我們?cè)O(shè)置相同的場(chǎng)景骂束,分別對(duì) Pulsar 和 Kafka 進(jìn)行了壓測(cè)對(duì)比耳璧,具體的測(cè)試場(chǎng)景如下展箱。
壓測(cè)數(shù)據(jù)如下:
以上數(shù)據(jù)可以看到混驰,網(wǎng)絡(luò) IO 方面,3 個(gè)副本多分區(qū)的情況下栖榨,Pulsar 幾乎要把 broker 網(wǎng)卡出流量跑滿,因?yàn)橐环輸?shù)據(jù)需要在 broker 端分發(fā) 3 次满粗,這是計(jì)算存儲(chǔ)分離的代價(jià)愚争。
Kafka 的性能數(shù)據(jù)有點(diǎn)讓人失望,整體性能沒有上去轰枝,這應(yīng)該和 Kafka 本身的副本同步機(jī)制有關(guān):Kafka 采用的是 follow 同步拉取的策略,導(dǎo)致整體效率并不高步淹。
延遲方面,Pulsar 在生產(chǎn)端表現(xiàn)更優(yōu)越些贤旷,當(dāng)資源沒有到達(dá)瓶頸時(shí)砾脑,整個(gè)時(shí)耗 99% 在 10 毫秒以內(nèi),在垃圾回收(Garbage Collection盅藻,GC)和創(chuàng)建操作日志文件時(shí)會(huì)出現(xiàn)波動(dòng)畅铭。
從壓測(cè)的結(jié)果來(lái)看,在高一致的場(chǎng)景下硕噩,Pulsar 性能優(yōu)于 Kafka。如果設(shè)置 log.flush.interval.messages=1 的情況辉懒,Kafka 性能表現(xiàn)更差谍失,kafka 在設(shè)計(jì)之初就是為高吞吐,并沒有類似直接同步刷盤這些參數(shù)快鱼。
此外,我們還測(cè)試了其他場(chǎng)景线罕,比如百萬(wàn) Topic 和跨地域復(fù)制等柒莉。在百萬(wàn) Topic 場(chǎng)景的生產(chǎn)和消費(fèi)場(chǎng)景測(cè)試中,Pulsar 沒有因?yàn)?Topic 數(shù)量增長(zhǎng)而出現(xiàn)性能急劇下降的情況兢孝,而 Kafka 因?yàn)榇罅康碾S機(jī)寫導(dǎo)致系統(tǒng)快速變慢。
Pulsar 原生支持跨地域復(fù)制雳殊,并支持同步和異步兩種方式窗轩。Kafka 在同城跨地域復(fù)制中,吞吐量不高,復(fù)制速度很慢介陶,所以在跨地域復(fù)制場(chǎng)景中色建,我們測(cè)試了 Pulsar 同步復(fù)制方式哺呜,存儲(chǔ)集群采用跨城部署箕戳,等待 ACK 時(shí)必須包含多地應(yīng)答,測(cè)試使用的相關(guān)參數(shù)和同城一致玻墅。測(cè)試結(jié)果證明壮虫,在跨城情況下,Pulsar 吞吐量可以達(dá)到 28萬(wàn)QPS旨指。當(dāng)然,跨城跨地域復(fù)制的性能很大程度依賴于當(dāng)前的網(wǎng)絡(luò)質(zhì)量谆构。
可用性分析
作為新型分布式消息流平臺(tái),Pulsar 有很多優(yōu)勢(shì)呵晨。得益于 bookie 的分片處理以及 ledger 選擇存儲(chǔ)節(jié)點(diǎn)的策略熬尺,運(yùn)維 Pulsar 非常簡(jiǎn)單摸屠,可以擺脫類似 Kafka 手動(dòng)平衡數(shù)據(jù)煩擾季二。但 Pulsar 也不是十全十美揭措,本身也存在一些問題察皇,社區(qū)仍在改進(jìn)中。
Pulsar 對(duì) ZooKeeper 的強(qiáng)依賴
Pulsar 對(duì) ZooKeeper 有很強(qiáng)的依賴饼记。在極限情況下判莉,ZooKeeper 集群出現(xiàn)宕機(jī)或者阻塞讨便,會(huì)導(dǎo)致整個(gè)服務(wù)宕機(jī)以政。ZooKeeper 集群奔潰的概率相對(duì)小,畢竟 ZooKeeper 經(jīng)過(guò)了大量線上系統(tǒng)的考驗(yàn)傲霸,使用還是相對(duì)廣泛的眉反。但 ZooKeeper 堵塞的概率相對(duì)較高穆役,比如在百萬(wàn) Topic 場(chǎng)景下,會(huì)產(chǎn)生百萬(wàn)級(jí)的 ledger 元數(shù)據(jù)信息耿币,這些數(shù)據(jù)都需要與 ZooKeeper 進(jìn)行交互。
例如十性,創(chuàng)建一次主題(topic)塑悼,需要?jiǎng)?chuàng)建主題分區(qū)元數(shù)據(jù)、Topic 名厢蒜、Topic 存儲(chǔ) ledger 節(jié)點(diǎn);而創(chuàng)建一次 ledger 又需要?jiǎng)?chuàng)建和刪除唯一的 ledgerid 和 ledger 元數(shù)據(jù)信息節(jié)點(diǎn)愕贡,一共需要 5 次 ZooKeeper 寫入操作巷屿,一次訂閱也需要類似的 4 次 ZooKeeper 寫入操作,所以總共需要 9 次寫入操作憨琳。如果同時(shí)集中創(chuàng)建百萬(wàn)級(jí)的主題浓冒,勢(shì)必會(huì)對(duì) ZooKeeper 造成很大的壓力。
Pulsar 具有分散 ZooKeeper 部署的能力稳懒,能夠在一定程度上緩解 ZooKeeper 的壓力闲擦,依賴最大的是 zookeeperServer 這個(gè) ZooKeeper 集群。從之前的分析來(lái)看纯路,寫操作相對(duì)可控寞忿,可以通過(guò)控制臺(tái)創(chuàng)建 Topic。bookie 依賴的 ZooKeeper 操作頻率最高叫编,如果該 ZooKeeper 出現(xiàn)阻塞霹抛,當(dāng)前寫入并不會(huì)造成影響。
可以按照同樣的思路優(yōu)化對(duì) zookeeperServerzk 的依賴杯拐。至少對(duì)于當(dāng)前的服務(wù)可以持續(xù)一段時(shí)間端逼,給 ZooKeeper 足夠的時(shí)間進(jìn)行恢復(fù)朗兵;其次減少 ZooKeeper 的寫入次數(shù)顶滩,只用于必要的操作,比如 broker 選舉等浊吏。像 broker 的負(fù)載信息救氯,可以尋求其他存儲(chǔ)介質(zhì),尤其是當(dāng)一個(gè) broker 服務(wù)大量主題時(shí)着憨,這個(gè)信息會(huì)達(dá)到兆(M)級(jí)別甲抖。我們正在和 Pulsar 社區(qū)攜手優(yōu)化 broker 負(fù)載功能。
Pulsar 內(nèi)存管理稍復(fù)雜
Pulsar 的內(nèi)存由 JVM 的堆內(nèi)存和堆外存構(gòu)成准谚,消息的發(fā)送和緩存通過(guò)堆外內(nèi)存來(lái)存儲(chǔ),減少 IO 造成的垃圾回收(GC)樊破;堆內(nèi)存主要緩存 ZooKeeper 相關(guān)數(shù)據(jù)愉棱,比如 ledger 的元數(shù)據(jù)信息和訂閱者重推的消息 ID 緩存信息哲戚,通過(guò) dump 內(nèi)存分析發(fā)現(xiàn),一個(gè) ledger 元數(shù)據(jù)信息需要占用約 10K朋其,一個(gè)訂閱者者重推消息 ID 緩存初始為 16K脆炎,且會(huì)持續(xù)增長(zhǎng)。當(dāng) broker 的內(nèi)存持續(xù)增長(zhǎng)時(shí)秒裕,最終頻繁進(jìn)行整體垃圾回收(full GC),直到最終退出。
要解決這個(gè)問題入蛆,首先要找到可以減少內(nèi)存占用的字段硕勿,比如 ledger 元數(shù)據(jù)信息里面的 bookie 地址信息哨毁。每個(gè) ledger 都會(huì)創(chuàng)建對(duì)象源武,而 bookie 節(jié)點(diǎn)非常有限,可以通過(guò)全局變量來(lái)減少創(chuàng)建不必要的對(duì)象粱栖;訂閱者重推消息 ID 緩存可以把初始化控制在 1K 內(nèi),定期進(jìn)行縮容等幔崖。這些操作可以大大提升 Broker 的可用性渣淤。
和 Kafka 相比,Pulsar broker 的優(yōu)點(diǎn)比較多价认,Pulsar 能夠自動(dòng)進(jìn)行負(fù)載均衡,不會(huì)因?yàn)槟硞€(gè) broker 負(fù)載過(guò)高導(dǎo)致服務(wù)不穩(wěn)定渠退,可以快速擴(kuò)容,降低整個(gè)集群的負(fù)載智什。
總結(jié)
總體來(lái)說(shuō),Pulsar 在高一致場(chǎng)景中旱眯,性能表現(xiàn)優(yōu)異证九,目前已在騰訊內(nèi)部廣泛使用,比如騰訊金融和大數(shù)據(jù)場(chǎng)景呀页。大數(shù)據(jù)場(chǎng)景主要基于 KOP 模式拥坛,目前其性能已經(jīng)非常接近 Kafka,某些場(chǎng)景甚至已經(jīng)超越 Kafka猜惋。我們深信,在社區(qū)和廣大開發(fā)愛好者的共同努力下缓窜,Pulsar 會(huì)越來(lái)越好谍咆,開啟下一代云原生消息流的新篇章。
本文作者:劉德志
騰訊專家工程師摹察、TEG 技術(shù)工程事業(yè)群和計(jì)費(fèi)系統(tǒng)開發(fā)者