共計 3693 個字符,預計需要花費 10 分鐘才能閱讀完成。
今天就跟大家聊聊有關怎樣實現 Apache Pulsar 與 Kafka 在金融場景下的性能分析,可能很多人都不太了解,為了讓大家更加了解,丸趣 TV 小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
背景
Apache Pulsar 是下一代分布式消息流平臺,采用計算存儲分層架構,具備多租戶、高一致、高性能、百萬 topic、數據平滑遷移等諸多優勢。越來越多的企業正在使用 Pulsar 或者嘗試將 Pulsar 應用到生產環境中。
騰訊把 Pulsar 作為計費系統的消息總線來支撐千億級在線交易。騰訊計費體量龐大,要解決的核心問題就是必須確保錢貨一致。首先,保證每一筆支付交易不出現錯賬,做到高一致、高可靠。其次,保證計費承載的所有業務 7*24 可用,做到高可用、高性能。計費消息總線必須具備這些能力。
Pulsar 架構解析
在一致性方面,Pulsar 采用 Quorum 算法,通過 write quorum 和 ack quorum 來保證分布式消息隊列的副本數和強一致寫入的應答數 (A W/2)。在性能方面,Pulsar 采用 Pipeline 方式生產消息,通過順序寫和條帶化寫入降低磁盤 IO 壓力,多種緩存減少網絡請求加快消費效率。
Pulsar 性能高主要體現在網絡模型、通信協議、隊列模型、磁盤 IO 和條帶化寫入。下面我會一一詳細講解。
網絡模型
Pulsar Broker 是一個典型的 Reactor 模型,主要包含一個網絡線程池,負責處理網絡請求,進行網絡的收發以及編解碼,接著把請求通過請求隊列推送給核心線程池進行處理。首先,Pulsar 采用多線程方式,充分利用現代系統的多核優勢,把同一任務請求分配給同一個線程處理,盡量避免線程之間切換帶來的開銷。其次,Pulsar 采用隊列方式實現了網絡處理模塊及核心處理模塊的異步解耦,實現了網絡處理和文件 I/O 并行處理,極大地提高了整個系統的效率。
通信協議
信息(message)采用二進制編碼,格式簡單;客戶端生成二進制數據直接發送給 Pulsar 后端 broker,broker 端不解碼直接發送給 bookie 存儲,存儲格式也是二進制,所以消息生產消費過程沒有任何編解碼操作。消息的壓縮以及批量發送都是在客戶端完成,這能進一步提升 broker 處理消息的能力。
隊列模型
Pulsar 對主題(topic)進行分區(partition),并盡量將不同的分區分配到不同的 Broker,實現水平擴展。Pulsar 支持在線調整分區數量,理論上支持無限吞吐量。雖然 ZooKeeper 的容量和性能會影響 broker 個數和分區數量,但該限制上限非常大,可以認為沒有上限。
磁盤 IO
消息隊列屬于磁盤 IO 密集型系統,所以優化磁盤 IO 至關重要。Pulsar 中的磁盤相關操作主要分為操作日志和數據日志兩類。操作日志用于數據恢復,采用完全順序寫的模式,寫入成功即可認為生產成功,因此 Pulsar 可以支持百萬主題,不會因為隨機寫而導致性能急劇下降。
操作日志也可以是亂序的,這樣可以讓操作日志寫入保持最佳寫入速率,數據日志會進行排序和去重,雖然出現寫放大的情況,但是這種收益是值得的:通過將操作日志和數據日志掛在到不同的磁盤上,將讀寫 IO 分離,進一步提升整個系統 IO 相關的處理能力。
條帶化寫入
條帶化寫入能夠利用更多的 bookie 節點來進行 IO 分擔;Bookie 設置了寫緩存和讀緩存。最新的消息放在寫緩存,其他消息會批量從文件讀取加入到讀緩存中,提升讀取效率。
從架構來看,Pulsar 在處理消息的各個流程中沒有明顯的卡點。操作日志持久化只有一個線程來負責刷盤,可能會造成卡頓。根據磁盤特性,可以設置多塊盤,多個目錄,提升磁盤讀寫性能,這完全能夠滿足我們的需求。
測試
在騰訊計費場景中,我們設置相同的場景,分別對 Pulsar 和 Kafka 進行了壓測對比,具體的測試場景如下。
壓測數據如下:
以上數據可以看到,網絡 IO 方面,3 個副本多分區的情況下,Pulsar 幾乎要把 broker 網卡出流量跑滿,因為一份數據需要在 broker 端分發 3 次,這是計算存儲分離的代價。
Kafka 的性能數據有點讓人失望,整體性能沒有上去,這應該和 Kafka 本身的副本同步機制有關:Kafka 采用的是 follow 同步拉取的策略,導致整體效率并不高。
延遲方面,Pulsar 在生產端表現更優越些,當資源沒有到達瓶頸時,整個時耗 99% 在 10 毫秒以內,在垃圾回收(Garbage Collection,GC)和創建操作日志文件時會出現波動。
從壓測的結果來看,在高一致的場景下,Pulsar 性能優于 Kafka。如果設置 log.flush.interval.messages=1 的情況,Kafka 性能表現更差,kafka 在設計之初就是為高吞吐,并沒有類似直接同步刷盤這些參數。
此外,我們還測試了其他場景,比如百萬 Topic 和跨地域復制等。在百萬 Topic 場景的生產和消費場景測試中,Pulsar 沒有因為 Topic 數量增長而出現性能急劇下降的情況,而 Kafka 因為大量的隨機寫導致系統快速變慢。
Pulsar 原生支持跨地域復制,并支持同步和異步兩種方式。Kafka 在同城跨地域復制中,吞吐量不高,復制速度很慢,所以在跨地域復制場景中,我們測試了 Pulsar 同步復制方式,存儲集群采用跨城部署,等待 ACK 時必須包含多地應答,測試使用的相關參數和同城一致。測試結果證明,在跨城情況下,Pulsar 吞吐量可以達到 28 萬 QPS。當然,跨城跨地域復制的性能很大程度依賴于當前的網絡質量。
可用性分析
作為新型分布式消息流平臺,Pulsar 有很多優勢。得益于 bookie 的分片處理以及 ledger 選擇存儲節點的策略,運維 Pulsar 非常簡單,可以擺脫類似 Kafka 手動平衡數據煩擾。但 Pulsar 也不是十全十美,本身也存在一些問題,社區仍在改進中。
Pulsar 對 ZooKeeper 的強依賴
Pulsar 對 ZooKeeper 有很強的依賴。在極限情況下,ZooKeeper 集群出現宕機或者阻塞,會導致整個服務宕機。ZooKeeper 集群奔潰的概率相對小,畢竟 ZooKeeper 經過了大量線上系統的考驗,使用還是相對廣泛的。但 ZooKeeper 堵塞的概率相對較高,比如在百萬 Topic 場景下,會產生百萬級的 ledger 元數據信息,這些數據都需要與 ZooKeeper 進行交互。
例如,創建一次主題(topic),需要創建主題分區元數據、Topic 名、Topic 存儲 ledger 節點;而創建一次 ledger 又需要創建和刪除唯一的 ledgerid 和 ledger 元數據信息節點,一共需要 5 次 ZooKeeper 寫入操作,一次訂閱也需要類似的 4 次 ZooKeeper 寫入操作,所以總共需要 9 次寫入操作。如果同時集中創建百萬級的主題,勢必會對 ZooKeeper 造成很大的壓力。
Pulsar 具有分散 ZooKeeper 部署的能力,能夠在一定程度上緩解 ZooKeeper 的壓力,依賴最大的是 zookeeperServer 這個 ZooKeeper 集群。從之前的分析來看,寫操作相對可控,可以通過控制臺創建 Topic。bookie 依賴的 ZooKeeper 操作頻率最高,如果該 ZooKeeper 出現阻塞,當前寫入并不會造成影響。
可以按照同樣的思路優化對 zookeeperServerzk 的依賴。至少對于當前的服務可以持續一段時間,給 ZooKeeper 足夠的時間進行恢復;其次減少 ZooKeeper 的寫入次數,只用于必要的操作,比如 broker 選舉等。像 broker 的負載信息,可以尋求其他存儲介質,尤其是當一個 broker 服務大量主題時,這個信息會達到兆(M)級別。我們正在和 Pulsar 社區攜手優化 broker 負載功能。
Pulsar 內存管理稍復雜
Pulsar 的內存由 JVM 的堆內存和堆外存構成,消息的發送和緩存通過堆外內存來存儲,減少 IO 造成的垃圾回收(GC);堆內存主要緩存 ZooKeeper 相關數據,比如 ledger 的元數據信息和訂閱者重推的消息 ID 緩存信息,通過 dump 內存分析發現,一個 ledger 元數據信息需要占用約 10K,一個訂閱者者重推消息 ID 緩存初始為 16K,且會持續增長。當 broker 的內存持續增長時,最終頻繁進行整體垃圾回收(full GC),直到最終退出。
要解決這個問題,首先要找到可以減少內存占用的字段,比如 ledger 元數據信息里面的 bookie 地址信息。每個 ledger 都會創建對象,而 bookie 節點非常有限,可以通過全局變量來減少創建不必要的對象;訂閱者重推消息 ID 緩存可以把初始化控制在 1K 內,定期進行縮容等。這些操作可以大大提升 Broker 的可用性。
和 Kafka 相比,Pulsar broker 的優點比較多,Pulsar 能夠自動進行負載均衡,不會因為某個 broker 負載過高導致服務不穩定,可以快速擴容,降低整個集群的負載。
看完上述內容,你們對怎樣實現 Apache Pulsar 與 Kafka 在金融場景下的性能分析有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注丸趣 TV 行業資訊頻道,感謝大家的支持。