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


背景

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

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

BIGO 消息隊列平台使用的是開源 Kafka,然而隨着業務數據量的成倍增長、消息實時性和系統穩定性要求不斷提高,多個 Kafka 集群的維護成本越來越高,主要體現在:

  • 數據存儲和消息隊列服務綁定,集群擴縮容/分區均衡需要大量拷貝數據,造成集群性能下降
  • 當分區副本不處於 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 軟件基金會頂級項目。

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 集群。

壓測/使用 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)時,問題 4、5、6、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/streamnative/pulsar-manager。

需要重點關注的指標如下:

  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 低。

現有的/默認的 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 分鍾

這些問題的影響是: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 寫入成功率。

這個熔斷策略存在的問題是:某台 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/bookkeeper/pull/2327。

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

限流

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

在生產環境中,在高吞吐場景下,我們經常遇到 broker direct memory OOM,導致 broker 進程掛掉。這里的原因可能是底層 bookie 寫入變慢,導致大量數據積壓在 broker direct memory 中。Producer 發送的消息在 broker 中的處理過程如下圖所示:

在生產環境中,我們不能保證底層 bookie 始終保持非常低的寫延遲,所以需要在 broker 層做限流。Pulsar 社區的鵬輝開發了限流功能,限流邏輯如下圖所示:

在 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 喚醒。

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

這里的問題是:當 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。處理邏輯如下圖所示:

這個功能在 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。處理流程如下圖所示:

判斷是否有 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 的判定如下圖所示。

  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 生產落地過程中的一些經驗。

本篇主要解決了開篇提到的這幾個問題(1、2、5、7、8、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 生態集成方向。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM