滴滴在HBase性能與可用性上的探索與實踐

桔妹導讀:HBase作爲Hadoop生態中表現較爲突出的分佈式在線數據存儲產品,在滴滴有着非常廣泛的應用,但同樣存在比較突出的短板問題——例如可用性較弱、毛刺嚴重等,一定程度上限制了它的業務邊界。本文主要介紹在此背景下,HBase團隊近期進行的一些探索工作。

1. 

背景

HBase 是一個基於 HDFS 的低成本、分佈式LSM結構數據庫,可以支持毫秒級別查詢;支持海量的PB級的大數據存儲,適用於高QPS的隨機讀寫和前綴範圍查詢等場景。此外,優秀的開源環境使得HBase還可以支持豐富的上下游生態與離線任務。

目前在滴滴內部,HBase基本覆蓋了全部業務線,數據量PB規模,吞吐超千萬級別;業務包含司乘軌跡、訂單、特徵工程、推薦引擎、IOT、APM等各種場景,基於HBase的多模生態諸如OLAP(Kylin)、時序(OpenTSDB)、時空(GeoMesa)、圖(JanusGraph)亦均有應用。

2020年下半年,HBase團隊逐漸將視野投向端上/類端上業務,希望能夠承載更加重要的流量。然而對於HBase自身架構和實現而言,主要存在兩方面痛點:

1.可用性問題

架構層面看,HBase在CAP定理中選擇了C,以較弱的可用性爲代價換取強一致性,數據層面依賴HDFS保證數據安全,計算層面region無副本。

這樣當region遷移、分裂、合併、RS宕機等情況發生時,對應region都會有短時不可用;而作爲高吞吐的數據服務,客戶端往往都會大量使用線程池,少量region不可用會迅速形成木桶短板,進而放大爲整體TPS掉底。

而這種“預期內的”抖動、掉底,是無法滿足互聯網行業端上場景的可用性要求的。

社區提供的region replica功能一定程度上可以緩解這一問題,但一方面目前這個feature可靠性還不算高,社區仍在推進各種加固和改善,目測穩定的目標release版本可能要放到未發佈的3.0了;另一方面端上服務需要雙機房,保證容災和降級,而replica是集羣內的region副本,顯然也不能支持。

2.毛刺問題

HBase主要受Java GC和底層HDFS共用影響,HBase的毛刺相對突出,是進一步提升性能的瓶頸點。

 

基於以上兩個痛點問題,HBase團隊近半年進行了一些嘗試與探索,主要是基於 replication的客戶端多路讀功能 與 HBase-ZGC應用實踐,預期能夠優化HBase的可用性與毛刺問題,簡單分享給大家。

2. 

基於replication的客戶端多路讀功

2020年來,爲提升HBase可用性,我們大體經歷了兩個階段:

1replication主備


replication是HBase的異步數據同步機制,和Mysql利用Binlog實現主從庫類似,HBase利用WAL實現主備集羣的數據同步。大致流程爲主集羣記錄寫入的WAL,並將數據異步發送給備集羣,備集羣接收數據並將其轉換爲put/delete操作,批量寫入備集羣。提供最終一致性保證。

圖片來源:HBase官方文檔

detailed_information_about_cluster_replication

這一階段存在的問題:

  • 故障時用戶有感知,需用戶側切讀;

  • 備集羣利用率較低,資源閒置存在浪費;

2. replication + failover


failover是滴滴HBase團隊基於replication自研的增強feature,架構如下圖:

  • 相比第一階段,failover可以基於zk實現服務切換,不需用戶操作。但仍然存在用戶有感知、備集羣無法充分利用的問題;

  • 基於以上背景,我們又開發了基於replication的客戶端多路讀功能,預期解決以下問題:

    • 故障時用戶無感知;

    • 提升備集羣利用率;

    • 打磨HBase毛刺;

1. 設計

整體設計參考HDFS的hedgedRead功能,客戶端首先向主集羣發起讀請求,一定時間沒有返回結果則併發向備集羣發起請求,兩者取先完成者返回。

實際上HBase的regionReplica也是類似的實現。

2.新增配置

param

default value

desc

hbase.client.hedged.read

false

是否開啓多路讀

hbase.client.hedged.read.timeout

50

啓動備集羣讀線程的時間閾值

hbase.zookeeper.quorum.hedged.read

-

備集羣zk地址

3.性能測試

3.1 用例設計

  1. 兩個集羣分別創建主備測試表,構建replication

  2. ycsb打入100w測試數據

  3. 測試組打開多路讀,對照組關閉多路讀,各發起10w次scan

  4. 客戶端統計max、P999、P99

3.2 測試結論

max對比

P999對比

P99對比

多路讀對於max和P999有較佳優化效果,可以有效打磨毛刺。

4.未盡事項和思考

1. 多路讀功能基於replication實現,因此只能實現最終一致性,備集羣讀到的數據有可能和主集羣存在差異;

2. 目前此功能僅作用於查詢,主集羣宕機時,最新數據無法同步,因此備集羣查詢最新數據可能查詢不到;

3. HBase的scan操作可能分解爲多次RPC,由於相關session信息在不同集羣間沒有同步,數據也不能保證完全一致,因此多路讀只在第一次RPC時生效,之後的請求會固定訪問第一次RPC時最終使用的集羣。

多路讀本質上是多活建設,但CAP較難跨越,多活可以提供高可用能力,但強一致性很難得到保障。

但我們可以通過“讓用戶選擇”的方式來解決這一問題:

  • 方案一:多活 + 最終一致性

  • 方案二:主備 + 強一致性

對於方案一,當前的多路讀實現了讀鏈路的多活,寫鏈路仍有優化空間,例如提升replication效率、降低兩集羣間數據lag等;

對於方案二,可以基於社區的同步replication實現,此外failover的功能仍需我們做更多工作,實現更加智能的自動切換,降低用戶感知。

3. 

HBase-ZGC應用實踐

1.爲什麼要更換GC算法?

隨着滴滴內部越來越多的端上和類端上業務使用HBase作爲存儲引擎,用戶對HBase讀寫延遲穩定性的要求也越來越高,HBase的GC毛刺問題尤爲突出,G1無法滿足性能需求。

好消息是JDK15在9月15號正式發佈,劃時代的ZGC正式轉正,我們決定嘗試用ZGC來解決GC毛刺問題。

ZGC(The Z Garbage Collector):ZGC是JDK11之後發佈的一款可伸縮的低延遲JVM垃圾收集器。

ZGC官方的設計目標如下:

  • Max pause times of a few milliseconds(*)

  • Pause times do not increase with the heap or live-set size (*)

  • Handle heaps ranging from a 8MB to 16TB in size

ZGC 是一個併發的、單代的、基於區域的、NUMA 感知的壓縮收集器,Stop-the-world 階段僅限於根掃描,因此 GC 暫停時間不會隨堆或活動集(live set)的變大而增加。

ZGC 的核心設計原則是將Load barriers與染色對象指針結合使用,這使得 ZGC 能夠在 Java 應用程序線程運行時執行併發操作,例如對象重定向。從 Java 線程的角度來看,在 Java 對象中加載引用字段的行爲受到加載屏障的影響。除了對象地址之外,colored oops 還包含加載屏障使用的信息,以確定在允許 Java 線程使用指針之前是否需要採取某些操作。

ZGC相比G1

  • 更低延遲:GC停頓時間更短,不超過 10ms

  • 更大內存:堆內存支持範圍更大(8MB-16TB)

SPECjbb 2015基準測試,128G堆,ZGC的暫停時間遠低於G1

相較於G1只有寫屏障沒有讀屏障,複製移動的過程需要Stop the world,ZGC通過讀屏障、Remark標記和重定向表來併發拷貝非GC Roots對象,儘可能的減少了Stop the world。

官方的性能測試對比可以參考JEP333。本文主要介紹HBase場景的ZGC應用實踐,對ZGC的原理不展開介紹。

2. HBase應用ZGC實踐

2.1 選擇JDK版本

由於需要在生產環境使用,而Orace JDK商業使用開始收費,所以我們需要一個免費版的JDK。經過對比,我們最終選取了AdoptOpenJDK的JDK15版本。

1)AdoptOpenJDK 是社區(倫敦JUG)維護版的OpenJDK,提供預構建的二進制文件,主要維護LTS及最新版本;和OpenJDK一樣,AdoptOpenJDK 也支持 GPL 協議且免費,不同的是OpenJDK只會由Oracle提供6個月的安全更新,而AdoptOpenJDK則由社區提供至少4年的免費長期支持(LTS)。

2)選擇JDK15的原因: 

  • JDK11存在小概率crash的問題

  • ZGC在JDK15版本正式生產環境可用

2.2 編譯HBase(基於AdoptOpenJDK15)

滴滴內部使用的HBase版本是基於社區1.4.8基礎上開發的版本,不支持JDK11及以上版本的編譯,所以需要解決一些編譯問題。

社區3.x及2.3.x版本開始支持JDK11,參考 HBASE-22972。在1.4.8版本的編譯過程中,主要遇到了以下幾類編譯問題:

  • 1. 部分類找不到或被刪除,比如javax.xml.ws.http.HTTPException。解決辦法:找到替換類或依賴包;

  • 2. 一些類不可讀,比如sun.nio.ch.DirectBuffer。解決辦法:運行時添加--add-exports=java.base/sun.nio.ch=ALL-UNNAMED;

  • 3. 依賴的組件包不支持JDK15,如Jetty、Jruby等。解決辦法:升級對應的組件到高版本;

  • 4. 編譯插件不支持JDK15,如maven-shade-plugin、extra-enforcer-rules等。解決辦法:升級對應的插件到高版本。

2.3 應用ZGC的效果:

1、順序讀場景ZGC和G1性能表現對比

Scan場景下,ZGC的P99延遲降低20%,P999降低40%。

2、壓力測試場景對比ZGC和G1的性能表現

構造寫壓力測試場景,RegionServer的全局Memstore寫滿,觸發Upper Limit,G1GC回收不過來,觸發Full GC,耗時超過40s(ZK會話的超時時間),RS服務會宕機。

對比同等寫入壓力下,ZGC 99.93%的回收時間都在10ms以內,只有2次在10~20ms之間,RS服務未宕機。

備註:如果內存分配過快,ZGC也可能會出現回收不過來的問題,這種情況下可以通過增大堆內存的方式緩解。

HBase使用ZGC可以有效的降低了服務端P99及P999的延時,非常適合對延遲較敏感的業務場景。

3. 

總結

HBase在真正海量數據的離線應用場景下具備毋庸置疑的競爭力,但受其自身實現短板的限制,距離端上應用的標準還是存在一定距離的。滴滴HBase希望通過一系列優化手段,服務好離線業務的同時,未來可以接入更多的不涉及核心流程的線上/類線上業務,歡迎感興趣的同學一起交流。 

本文作者

團隊招聘

滴滴大數據架構離線引擎&HBase 團隊主要負責滴滴集團大數據離線存儲、離線計算、NoSQL 等引擎的開發與運維工作,通過持續應用和研發新一代大數據技術,構建穩定可靠、低成本、高性能的大數據基礎設施,更多賦能業務,創造更多價值。

 

團隊持續招聘 HDFS、YARN,Spark,HBase 等領域專家,參與滴滴大數據架構的建設工作,歡迎加入。

 

可投遞簡歷到 [email protected],郵件主題請命名爲「姓名-應聘部門-應聘方向」。

掃碼瞭解更多崗位

延伸閱讀

內容編輯 | Teeo

聯繫我們 | [email protected]


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章