Apache Pulsar 在 BIGO 的性能調優實戰(上)

背景

在人工智能技術的支持下,BIGO 基於視頻的產品和服務受到普遍歡迎,在 150 多個國家/地區擁有用戶,其中包括 Bigo Live(直播)和 Likee(短視頻)。Bigo Live 在 150 多個國家/地區興起,Likee 有 1 億多用戶,並在 Z 世代中很受歡迎。git

隨着業務的迅速增加,BIGO 消息隊列平臺承載的數據規模出現了成倍增加,下游的在線模型訓練、在線推薦、實時數據分析、實時數倉等業務對消息的實時性和穩定性提出了更高的要求。github

BIGO 消息隊列平臺使用的是開源 Kafka,然而隨着業務數據量的成倍增加、消息實時性和系統穩定性要求不斷提升,多個 Kafka 集羣的維護成本愈來愈高,主要體如今:apache

  • 數據存儲和消息隊列服務綁定,集羣擴縮容/分區均衡須要大量拷貝數據,形成集羣性能降低
  • 當分區副本不處於 ISR(同步)狀態時,一旦有 broker 發生故障,可能會形成丟數或該分區沒法提供讀寫服務
  • 當 Kafka broker 磁盤故障/使用率太高時,須要進行人工干預
  • 集羣跨區域同步使用 KMM(Kafka Mirror Maker),性能和穩定性難以達到預期
  • 在 catch-up 讀場景下,容易出現 PageCache 污染,形成讀寫性能降低
  • 雖然 Kafka 的 topic partition 是順序寫入,可是當 broker上有成百上千個topic partition 時,從磁盤角度看就變成了隨機寫入,此時磁盤讀寫性能會隨着 topic partition 數量的增長而下降,所以 Kafka broker 上存儲的 topic partition 數量是有限制的
  • 隨着 Kafka 集羣規模的增加,Kakfa 集羣的運維成本急劇增加,須要投入大量的人力進行平常運維。在 BIGO,擴容一臺機器到 Kafka 集羣並進行分區均衡,須要 0.5人/天;縮容一臺機器須要 1 人/天

爲了提升消息隊列實時性、穩定性和可靠性,下降運維成本,咱們從新考慮了 Kafka 架構設計上的不足,調研可否從架構設計上解決這些問題,知足當前的業務要求。性能優化

下一代消息流平臺:Pulsar

Apache Pulsar 是 Apache 軟件基金會頂級項目,是下一代雲原生分佈式消息流平臺,集消息、存儲、輕量化函數式計算爲一體。Pulsar 於 2016 年由 Yahoo 開源並捐贈給 Apache 軟件基金會進行孵化,2018 年成爲Apache 軟件基金會頂級項目。session

Pulsar 採用計算與存儲分離的分層架構設計,支持多租戶、持久化存儲、多機房跨區域數據複製,具備強一致性、高吞吐以及低延時的高可擴展流數據存儲特性。架構

Pulsar 吸引咱們的主要特性以下:併發

  • 線性擴展:可以無縫擴容到成百上千個節點
  • 高吞吐:已經在 Yahoo 的生產環境中經受了考驗,支持每秒數百萬消息的 發佈-訂閱(Pub-Sub)
  • 低延遲:在大規模的消息量下依然可以保持低延遲(小於 5 ms)
  • 持久化機制:Plusar 的持久化機制構建在 Apache BookKeeper 上,提供了讀寫分離
  • 讀寫分離:BookKeeper 的讀寫分離 IO 模型極大發揮了磁盤順序寫性能,對機械硬盤相對比較友好,單臺 bookie 節點支撐的 topic 數不受限制

Apache Pulsar 的架構設計解決了咱們使用 Kafka 過程當中遇到的各類問題,而且提供了不少很是棒的特性,如多租戶、消息隊列和批流融合的消費模型、強一致性等。負載均衡

爲了進一步加深對 Apache Pulsar 的理解,衡量 Pulsar 可否真正知足咱們生產環境大規模消息 Pub-Sub 的需求,咱們從 2019 年 12 月份開始進行了一系列壓測工做。因爲咱們使用的是機械硬盤,沒有 SSD,在壓測過程當中遇到了一些列性能問題,很是感謝 StreamNative 同窗的幫助,感謝斯傑、翟佳、鵬輝的耐心指導和探討,通過一系列的性能調優,不斷提升 Pulsar 的吞吐和穩定性。運維

通過 3~4 個月的壓測和調優,2020 年 4 月份咱們正式在生產環境中使用 Pulsar 集羣。咱們採用 bookie 和 broker 在同一個節點的混部模式,逐步替換生產環境的 Kafka 集羣。截止到目前爲止,生產環境中 Pulsar 集羣規模爲十幾臺,日處理消息量爲百億級別,而且正在逐步擴容和遷移 Kafka 流量到 Pulsar 集羣。jvm

壓測/使用 Pulsar 遇到的問題

你們在使用/壓測 Pulsar 時,可能會遇到以下問題:

  1. Pulsar broker 節點負載不均衡。
  2. Pulsar broker 端 Cache 命中率低,致使大量讀請求進入 bookie,且讀性能比較差。
  3. 壓測時常常出現 broker 內存溢出現象(OOM)。
  4. Bookie 出現 direct memory OOM 致使進程掛掉。
  5. Bookie 節點負載不均衡,且常常抖動。
  6. 當 Journal 盤爲 HDD 時,雖然關閉了 fsync,可是 bookie add entry 99th latency 依舊很高,寫入性能較差。
  7. 當 bookie 中有大量讀請求時,出現寫被反壓,add entry latency 上升。
  8. Pulsar client 常常出現「Lookup Timeout Exception」。
  9. ZooKeeper 讀寫延遲太高致使整個 Pulsar 集羣不穩定。
  10. 使用 reader API(eg. pulsar flink connector) 消費 Pulsar topic 時,消費速度較慢(Pulsar 2.5.2 以前版本)。

當 Journal/Ledger 盤爲機械硬盤(HDD)時,問題 四、五、六、7 表現得尤其嚴重。這些問題直觀來看,是磁盤不夠快形成的,若是 Journal/Ledger 盤讀寫速度足夠快,就不會出現消息在 direct memory 中堆積,也就不會有一系列 OOM 的發生。

因爲在咱們消息隊列生產系統中,須要存儲的數據量比較大(TB ~ PB 級別),Journal 盤和 Ledger 盤都是 SSD 須要較高的成本,那麼有沒有可能在 Pulsar / BookKeeper 上作一些參數/策略的優化,讓 HDD 也能發揮出較好的性能呢?

在壓測和使用 Pulsar 過程當中,咱們遇到了一系列性能問題,主要分爲 Pulsar Broker 層面和 BookKeeper 層面。爲此,本系列性能調優文章分爲兩篇,分別介紹 BIGO 在使用 Pulsar 過程當中對 Pulsar Broker 和 Bookkeeper 進行性能調優的解決方案,以使得 Pulsar 不管在磁盤爲 SSD 仍是 HDD 場景下,都能得到比較好的性能。

因爲篇幅緣由,本次性能調優系列分爲兩部分,上半部分主要介紹 Pulsar broker 的性能調優,下半部分主要介紹 BookKeeper 與 Pulsar 結合過程當中的性能調優。

本文接下來主要介紹 Pulsar / BookKeeper 中和性能相關的部分,並提出一些性能調優的建議(這些性能調優方案已經在 BIGO 生產系統中穩定運行,並得到了不錯的收益)。

環境部署與監控

環境部署與監控

因爲 BookKeeper 和 Pulsar Broker 重度依賴 ZooKeeper,爲了保證 Pulsar 的穩定,須要保證 ZooKeeper Read/Write 低延遲。此外,BookKeeper 是 IO 密集型任務,爲了不 IO 之間互相干擾,Journal/Ledger 放在獨立磁盤上。總結以下:

  • Bookie Journal/Ledger 目錄放在獨立磁盤上
  • 當 Journal/Ledger 目錄的磁盤爲 HDD 時,ZooKeeper dataDir/dataLogDir 不要和 Journal/Ledger 目錄放在同一塊磁盤上

BookKeeper 和 Pulsar Broker 均依賴 direct memory,並且 BookKeeper 還依賴 PageCache 進行數據讀寫加速,因此合理的內存分配策略也是相當重要的。Pulsar 社區的 sijie 推薦的內存分配策略以下:

  • OS: 1 ~ 2 GB
  • JVM: 1/2

    • heap: 1/3
    • direct memory: 2/3
  • PageCache: 1/2

假設機器物理內存爲 128G,bookie 和 broker 混部,內存分配以下:

  • OS: 2GB
  • Broker: 31GB

    • heap: 10GB
    • direct memory: 21GB
  • Bookie: 32GB

    • heap: 10GB
    • direct memory: 22GB
  • PageCache: 63GB

Monitor:性能調優,監控先行

爲了更加直觀地發現系統性能瓶頸,咱們須要爲 Pulsar/BookKeeper 搭建一套完善的監控體系,確保每個環節都有相關指標上報,當出現異常(包括但不限於性能問題)時,可以經過相關監控指標快速定位性能瓶頸,並制定相應解決方案。

Pulsar/BookKeeper 都提供了 Prometheus 接口,相關統計指標能夠直接使用 Http 方式獲取並直接對接 Prometheus/Grafana。感興趣的同窗能夠直接按照 Pulsar Manager 的指導進行安裝: https://github.com/streamnati...

須要重點關注的指標以下:

  1. Pulsar Broker

    • jvm heap/gc
    • bytes in per broker
    • message in per broker
    • loadbalance
    • broker 端 Cache 命中率
    • bookie client quarantine ratio
    • bookie client request queue
  2. BookKeeper

    • bookie request queue size
    • bookie request queue wait time
    • add entry 99th latency
    • read entry 99th latency
    • journal create log latency
    • ledger write cache flush latency
    • entry read throttle
  3. ZooKeeper

    • local/global ZooKeeper read/write request latency

有一些指標在上面 repo 中沒有提供相應 Grafana 模板,你們能夠本身添加 PromQL 進行配置。

Pulsar broker 端性能調優

對 Pulsar broker 的性能調優,主要分爲以下幾個方面:

  1. 負載均衡

    • Broker 之間負載均衡
    • Bookie 節點之間的負載均衡
  2. 限流

    • Broker 接收消息須要作流控,防止突發洪峯流量致使 broker direct memory OOM。
    • Broker 發送消息給 consumer/reader 時須要作流控,防止一次發送太多消息形成 consumer/reader 頻繁 GC。
  3. 提升 Cache 命中率
  4. 保證 ZooKeeper 讀寫低延遲
  5. 關閉 auto bundle split,保證系統穩定

負載均衡

Broker 之間負載均衡

Broker 之間負載均衡,可以提升 broker 節點的利用率,提升 Broker Cache 命中率,下降 broker OOM 機率。這一部份內容主要涉及到 Pulsar bundle rebalance 相關知識。

Namespace Bundle 結構以下,每一個 namespace(命名空間)由必定數量的 bundle 組成,該 namespace 下的全部 topic 均經過 hash 方式映射到惟一 bundle 上,而後 bundle 經過 load/unload 方式加載/卸載到提供服務的 broker 上。

若是某個 broker 上沒有 bundle 或者 bundle 數量比其餘 broker 少,那麼這臺 broker 的流量就會比其餘 broker 低。

image

現有的/默認的 bundle rebalance 策略(OverloadShedder)爲:每隔一分鐘統計集羣中全部 broker 的 CPU、Memory、Direct Memory、BindWith In、BindWith Out 佔用率的最大值是否超過閾值(默認爲85%);若是超過閾值,則將必定數量大入流量的 bundle 從該 broker 中卸載掉,而後由 leader 決定將被卸載掉的 bundle 從新加載到負載最低的 broker 上。

這個策略存在的問題是:

  1. 默認閾值比較難達到,很容易致使集羣中大部分流量都集中在幾個 broker 上;
  2. 閾值調整標準難以肯定,受其餘因素影響較大,特別是這個節點上部署有其餘服務的狀況下;
  3. broker 重啓後,長時間沒有流量均衡到該 broker 上,由於其餘 broker 節點均沒有達到 bundle unload 閾值。

爲此,咱們開發了一個基於均值的負載均衡策略,並支持 CPU、Memory、Direct Memory、BindWith In、BindWith Out 權重配置,相關策略請參見 PR-6772

該策略在 Pulsar 2.6.0 版本開始支持,默認關閉,能夠在 broker.conf 中修改以下參數開啓:

loadBalancerLoadSheddingStrategy=org.apache.pulsar.broker.loadbalance.impl.ThresholdShedder

咱們能夠經過以下參數來精確控制不一樣採集指標的權重:

# The broker resource usage threshold.
# When the broker resource usage is greater than the pulsar cluster average resource usage,
# the threshold shredder will be triggered to offload bundles from the broker.
# It only takes effect in ThresholdSheddler strategy.
loadBalancerBrokerThresholdShedderPercentage=10

# When calculating new resource usage, the history usage accounts for.
# It only takes effect in ThresholdSheddler strategy.
loadBalancerHistoryResourcePercentage=0.9
# The BandWithIn usage weight when calculating new resource usage.
# It only takes effect in ThresholdShedder strategy.
loadBalancerBandwithInResourceWeight=1.0

# The BandWithOut usage weight when calculating new resource usage.
# It only takes effect in ThresholdShedder strategy.
loadBalancerBandwithOutResourceWeight=1.0

# The CPU usage weight when calculating new resource usage.
# It only takes effect in ThresholdShedder strategy.
loadBalancerCPUResourceWeight=1.0

# The heap memory usage weight when calculating new resource usage.
# It only takes effect in ThresholdShedder strategy.
loadBalancerMemoryResourceWeight=1.0

# The direct memory usage weight when calculating new resource usage.
# It only takes effect in ThresholdShedder strategy.
loadBalancerDirectMemoryResourceWeight=1.0

# Bundle unload minimum throughput threshold (MB), avoiding bundle unload frequently.
# It only takes effect in ThresholdShedder strategy.
loadBalancerBundleUnloadMinThroughputThreshold=10

均衡 bookie 節點之間的負載

Bookie 節點負載監控以下圖所示,咱們會發現:

  1. Bookie 節點之間負載並非均勻的,最高流量節點和最低流量節點可能相差幾百 MB/s
  2. 在高負載狀況下,某些節點的負載可能會出現週期性上漲和降低,週期爲 30 分鐘

image

這些問題的影響是:bookie 負載不均衡,致使 BookKeeper 集羣利用率降低,且容易出現抖動。

出現這個問題的緣由在於:bookie client 對 bookie 寫請求的熔斷策略粒度太大。

先來回顧一下 Pulsar broker 寫入 bookie 的策略:

當 broker 接收到 producer 發送的 message 時,首先會將消息存放在 broker 的 direct memory 中,而後調用 bookie client 根據配置的(EnsembleSize,WriteQuorum,AckQuorum)策略將 message 以 pipeline 方式發送給 bookies。

Bookie client 每分鐘會統計各 bookie 寫入的失敗率(包括寫超時等各種異常)。默認狀況下,當失敗率超過 5 次/分鐘時,這臺 bookie 將會被關入小黑屋 30 分鐘,避免持續向出現異常的 bookie 寫入數據,從而保證 message 寫入成功率。

image

這個熔斷策略存在的問題是:某臺 bookie 負載(流量)很高時,全部寫入到該 bookie 的消息有可能同時會變慢,全部 bookie client 可能同時收到寫入異常,如寫入超時等,那麼全部 bookie client 會同時把這臺 bookie 關入小黑屋 30 分鐘,等到 30 分鐘以後又同時加入可寫入列表中。這就致使了這臺 bookie 的負載週期性上漲和降低。

爲了解決該問題,咱們引入了基於機率的 quarantine 機制,當 bookie client 寫入消息出現異常時,並非直接將這臺 bookie 關入小黑屋,而是基於機率決定是否 quarantine。

這一 quarantine 策略能夠避免全部 bookie client 同時將同一臺 bookie 關入小黑屋,避免 bookie 入流量抖動。相關 PR 請參見:BookKeeper PR-2327 ,因爲代碼沒有合併和發佈到 bookie 主版本,你們若是想使用該功能,須要本身獨立編譯代碼:https://github.com/apache/boo...

image
從 BIGO 實踐測試來看,該功能將 bookie 節點之間入流量標準差從 75 MB/s 下降到 40 MB/s。

image

限流

>>Broker direct memory OOM(內存溢出)

在生產環境中,在高吞吐場景下,咱們常常遇到 broker direct memory OOM,致使 broker 進程掛掉。這裏的緣由多是底層 bookie 寫入變慢,致使大量數據積壓在 broker direct memory 中。Producer 發送的消息在 broker 中的處理過程以下圖所示:

image

在生產環境中,咱們不能保證底層 bookie 始終保持很是低的寫延遲,因此須要在 broker 層作限流。Pulsar 社區的鵬輝開發了限流功能,限流邏輯以下圖所示:

image

在 Pulsar 2.5.1 版本中已發佈,請參見 PR-6178

Consumer 消耗大量內存

當 producer 端以 batch 模式發送消息時,consumer 端每每會佔用過多內存致使頻繁 GC,監控上的表現是:這個 topic 的負載在 consumer 啓動時飆升,而後逐漸迴歸到正常水平。

這個問題的緣由須要結合 consumer 端的消費模式來看。

當 consumer 調用 receive 接口消費一條消息時,它會直接從本地的 receiverQueue 中請求一條消息,若是 receiverQueue 中還有消息能夠獲取,則直接將消息返回給 consumer 端,並更新 availablePermit,當 availablePermit < receiverQueueSize/2 時,Pulsar client 會將 availablePermit 發送給 broker,告訴 broker 須要 push 多少條消息過來;若是 receiverQueue 中沒有消息能夠獲取,則等待/返回失敗,直到 receiverQueue 收到 broker 推送的消息纔將 consumer 喚醒。

image

Broker 收到 availablePermit 以後,會從 broker Cache/bookie 中讀取 max(availablePermit, batchSize) 條 entry,併發送給 consumer 端。處理邏輯以下圖所示:

image

這裏的問題是:當 producer 開啓 batch 模式發送,一個 entry 包含多條消息,可是 broker 處理 availablePermit 請求仍然把一條消息做爲一個 entry 來處理,從而致使 broker 一次性將大量信息發送給 consumer,這些消息數量遠遠超過 availiablePermit(availiablePermit vs. availiablePermit * batchSize)的接受能力,引發 consumer 佔用內存暴漲,引起頻繁 GC,下降消費性能。

爲了解決 consumer 端內存暴漲問題,咱們在 broker 端統計每一個 topic 平均 entry 包含的消息數(avgMessageSizePerEntry), 當接收到 consumer 請求的 availablePermit 時,將其換算成須要發送的 entry 大小,而後從 broker Cache/bookie 中拉取相應數量的 entry,而後發送給 consumer。處理邏輯以下圖所示:

image

這個功能在 Pulsar 2.6.0 中已發佈,默認是關閉的,你們能夠經過以下開關啓用該功能:

# Precise dispatcher flow control according to history message number of each entry
preciseDispatcherFlowControl=true

提升 Cache 命中率

Pulsar 中有多層 Cache 提高 message 的讀性能,主要包括:

  • Broker Cache
  • Bookie write Cache(Memtable)
  • Bookie read Cache
  • OS PageCache

本章主要介紹 broker Cache 的運行機制和調優方案,bookie 側的 Cache 調優放在下篇介紹。

當 broker 收到 producer 發送給某個 topic 的消息時,首先會判斷該 topic 是否有 Active Cursor,若是有,則將收到的消息寫入該 topic 對應的 Cache 中;不然,不寫入 Cache。處理流程以下圖所示:

image
判斷是否有 Active Cursor 須要同時知足如下兩個條件:

  1. 有 durable cursor
  2. Cursor 的 lag 在 managedLedgerCursorBackloggedThreshold 範圍內

因爲 reader 使用 non-durable cursor 進行消費,因此 producer 寫入的消息不會進入 broker Cache,從而致使大量請求落到 bookie 上,性能有所損耗。

streamnative/pulsar-flink-connector 使用的是 reader API 進行消費,因此一樣存在消費性能低的問題。

咱們 BIGO 消息隊列團隊的趙榮生同窗修復了這個問題,將 durable cursor 從 Active Cursor 判斷條件中刪除,詳情請見 PR-6769 ,這個 feature 在 Pulsar 2.5.2 發佈,有遇到相關性能問題的同窗請升級 Pulsar 版本到 2.5.2 以上。

此外,咱們針對 topic 的每一個 subscription 添加了 Cache 命中率監控,方便進行消費性能問題定位,後續會貢獻到社區。

Tailing Read

對於已經在 broker Cache 中的數據,在 tailing read 場景下,咱們怎樣提升 Cache 命中率,下降從 bookie 讀取數據的機率呢?咱們的思路是儘量讓數據從 broker Cache 中讀取,爲了保證這一點,咱們從兩個地方着手優化:

  1. 控制斷定爲 Active Cursor 的最大 lag 範圍,默認是 1000 個 entry ,由以下參數控:
# Configure the threshold (in number of entries) from where a cursor should be considered 'backlogged'
# and thus should be set as inactive.
managedLedgerCursorBackloggedThreshold=1000

Active Cursor 的斷定以下圖所示。

image

  1. 控制 broker Cache 的 eviction 策略,目前 Pulsar 中只支持默認 eviction 策略,有需求的同窗能夠自行擴展。默認 eviction 策略由以下參數控制:
# Amount of memory to use for caching data payload in managed ledger. This memory
# is allocated from JVM direct memory and it's shared across all the topics
# running  in the same broker. By default, uses 1/5th of available direct memory
managedLedgerCacheSizeMB=

# Whether we should make a copy of the entry payloads when inserting in cache
managedLedgerCacheCopyEntries=false

# Threshold to which bring down the cache level when eviction is triggered
managedLedgerCacheEvictionWatermark=0.9

# Configure the cache eviction frequency for the managed ledger cache (evictions/sec)
managedLedgerCacheEvictionFrequency=100.0

# All entries that have stayed in cache for more than the configured time, will be evicted
managedLedgerCacheEvictionTimeThresholdMillis=1000

Catchup Read

對於 Catchup Read 場景,broker Cache 大機率會丟失,全部的 read 請求都會落到 bookie 上,那麼有沒有辦法提升讀 bookie 的性能呢?

Broker 向 bookie 批量發送讀取請求,最大 batch 由 dispatcherMaxReadBatchSize 控制,默認是 100 個 entry。

# Max number of entries to read from bookkeeper. By default it is 100 entries.
dispatcherMaxReadBatchSize=100

一次讀取的 batchSize 越大,底層 bookie 從磁盤讀取的效率越高,均攤到單個 entry 的 read latency 就越低。可是若是過大也會形成 batch 讀取延遲增長,由於底層 bookie 讀取操做時每次讀一條 entry,並且是同步讀取。

這一部分的讀取調優放在《Apache Pulsar 在 BIGO 的性能調優實戰(下)》中介紹。

保證 ZooKeeper 讀寫低延遲

因爲 Pulsar 和 BookKeeper 都是嚴重依賴 ZooKeeper 的,若是 ZooKeeper 讀寫延遲增長,就會致使 Pulsar 服務不穩定。因此須要優先保證 ZooKeeper 讀寫低延遲。建議以下:

  1. 在磁盤爲 HDD 狀況下,ZooKeeper dataDir/dataLogDir 不要和其餘消耗 IO 的服務(如 bookie Journal/Ledger 目錄)放在同一塊盤上(SSD 除外);
  2. ZooKeeper dataDir 和 dataLogDir 最好可以放在兩塊獨立磁盤上(SSD 除外);
  3. 監控 broker/bookie 網卡利用率,避免因爲網卡打滿而形成和 ZooKeeper 失聯。

關閉 auto bundle split,保證系統穩定

Pulsar bundle split 是一個比較耗費資源的操做,會形成鏈接到這個 bundle 上的全部 producer/consumer/reader 鏈接斷開並重連。通常狀況下,觸發 auto bundle split 的緣由是這個 bundle 的壓力比較大,須要切分紅兩個 bundle,將流量分攤到其餘 broker,來下降這個 bundle 的壓力。控制 auto bundle split 的參數以下:

# enable/disable namespace bundle auto split
loadBalancerAutoBundleSplitEnabled=true

# enable/disable automatic unloading of split bundles
loadBalancerAutoUnloadSplitBundlesEnabled=true

# maximum topics in a bundle, otherwise bundle split will be triggered
loadBalancerNamespaceBundleMaxTopics=1000

# maximum sessions (producers + consumers) in a bundle, otherwise bundle split will be triggered
loadBalancerNamespaceBundleMaxSessions=1000

# maximum msgRate (in + out) in a bundle, otherwise bundle split will be triggered
loadBalancerNamespaceBundleMaxMsgRate=30000

# maximum bandwidth (in + out) in a bundle, otherwise bundle split will be triggered
loadBalancerNamespaceBundleMaxBandwidthMbytes=100

當觸發 auto bundle split 時 broker 負載比較高,關閉這個 bundle 上的 producer/consumer/reader,鏈接就會變慢,而且 bundle split 的耗時也會變長,就很容易形成 client 端(producer/consumer/reader)鏈接超時而失敗,觸發 client 端自動重連,形成 Pulsar/Pulsar client 不穩定。

對於生產環境,咱們的建議是:預先爲每一個 namespace 分配好 bundle 數,並關閉 auto bundle split 功能。若是在運行過程當中發現某個 bundle 壓力過大,能夠在流量低峯期進行手動 bundle split,下降對 client 端的影響。

關於預先分配的 bundle 數量不宜太大,bundle 數太多會給 ZooKeeper 形成比較大的壓力,由於每個 bundle 都要按期向 ZooKeeper 彙報自身的統計數據。

總結

本篇從性能調優角度介紹了 Pulsar 在 BIGO 實踐中的優化方案,主要分爲環境部署、流量均衡、限流措施、提升 Cache 命中率、保證 Pulsar 穩定性等 5 個方面,並深刻介紹了 BIGO 消息隊列團隊在進行 Pulsar 生產落地過程當中的一些經驗。

本篇主要解決了開篇提到的這幾個問題(一、二、五、七、八、9 )。對於問題 3,咱們提出了一個緩解方案,但並無指出 Pulsar broker OOM 的根本緣由,這個問題須要從 BookKeeper 角度來解決,剩下的問題都和 BookKeeper 相關。

因爲 Pulsar 使用分層存儲架構,底層的 BookKeeper 仍須要進行一系列調優來配合上層 Pulsar,充分發揮高吞吐、低延遲性能;下篇將從 BookKeeper 性能調優角度介紹 BIGO 的實踐經驗。

很是感謝 StreamNative 同窗的悉心指導和無私幫助,讓 Pulsar 在 BIGO 落地邁出了堅實的一步。Apache Pulsar 提供的高吞吐、低延遲、高可靠性等特性極大提升了 BIGO 消息處理能力,下降了消息隊列運維成本,節約了近一半的硬件成本。

同時,咱們也積極融入 Pulsar 社區,並將相關成果貢獻回社區。咱們在 Pulsar Broker 負載均衡、Broker Cache 命中率優化、Broker 相關監控、Bookkeeper 讀寫性能優、Bookkeeper 磁盤 IO 性能優化、Pulsar 與 Flink & Flink SQL 結合等方面作了大量工做,幫助社區進一步優化、完善 Pulsar 功能。

關於做者

陳航,BIGO 大數據消息平臺團隊負責人,負責承載大規模服務與應用的集中發佈-訂閱消息平臺的建立與開發。他將 Apache Pulsar 引入到 BIGO 消息平臺,並打通上下游系統,如 Flink、ClickHouse 和其餘實時推薦與分析系統。他目前聚焦 Pulsar 性能調優、新功能開發及 Pulsar 生態集成方向。

相關文章
相關標籤/搜索