小米Kylin平滑遷移HBase實踐

小米運維發表於2022-12-05

根據美團等其他公司在Kylin社群的公開分享資料,跨HBase叢集升級方案需要在新叢集重新構建歷史的Cube,或者有一段時間的服務停止。
小米在Kylin生產環境的跨HBase叢集遷移中實現了無中斷的平滑遷移,對業務的影響減到最低。
往期文章回顧:Talos網路卡負載最佳化:基於個性化一致性雜湊的負載均衡
  背景     
小米Kylin生產環境部署的是基於社群2.5.2修改的內部版本,所依賴HBase叢集是一個公共叢集,小米內部很多離線計算服務共享使用該HBase叢集。由於Kylin已經產生超過6000張HBase表,給HBase的metadata管理造成了不小的壓力,HBase metadata節點異常恢復的速度也受到極大的影響。隨著業務的增長,Kylin HBase表繼續快速增長,HBase叢集的運維壓力也越來越大。
為了應對快速增長的業務需求,我們決定將Kylin使用的HBase叢集獨立運維。同時,公共叢集的HBase是基於社群0.98.11的小米內部版本,版本較舊。在叢集獨立過程中,HBase團隊推薦使用最新基於社群2.2.0的小米內部版本 ,升級後HBase對超大metadata的管理也更友好。
  目標與挑戰     
小米Kylin生產環境上執行著超過50個專案、300多個cube,服務於很多線上的BI或報表系統。本次升級希望儘量減小對業務的影響:

  1. 遷移資料和切換叢集期間,查詢服務不中斷;
  2. 專案、資料模型和cube的新增、更改、發起構建、發起合併等操作不受影響;
  3. 資料構建任務可延後排程,但不能超過天級別;

Kylin儲存在HBase中的資料主要有兩類:Kylin metadata(後設資料)、Cube預計算資料。
後設資料中儲存著所有的使用者、專案和資料模型的資訊;資料模型對應的結果資料表;資料任務的執行引數、狀態和日誌;查詢使用的詞典等重要資訊。由於我們接入了很多自動化BI系統,這部分資訊隨時在變化。
Cube預計算資料是查詢使用的結果資料,每一個segment對應著一張資料表,預計算的資料表生成之後不會變化。我們雖然可以透過HBase snapshot複製後在新叢集restore的方式將資料複製到新的叢集,但是由於生產環境的Kylin中的資料表比較多,且以每天400張的速度不斷生成(注:因為有合併和過期刪除策略,每天資料表的增加數量要少於400)。新的資料表生成後會在metadata中標記為可查詢,若此時資料表的同步未完成,就會導致查詢失敗。
我們面對挑戰是如何保障資料遷移的過程中的服務可用性:

  1. Kylin metadata不斷變化,Cube預計算資料存量巨大且在持續增加;
  2. metadata可以做到秒級別同步,Cube預計算資料只能做到天級別(存量)和小時級別(增量)的同步;
  3. metadata新舊叢集保證一致,Cube預計算資料遷移過程中保障可用;

如下圖所示:
小米Kylin平滑遷移HBase實踐
圖1-通常方案的問題
  遷移方案     
因為我們維護了基於Kylin-2.5.2的內部版本,希望透過修改程式碼實現平滑遷移,其關鍵點是:

  1. 透過HBase replication保證新舊叢集Kylin metadata的資料同步

Kylin的meta資訊儲存在HBase的kylin_metadata表中,兩個叢集的此表保持同步更新。

  1. Kylin支援連線多個HBase叢集

查詢時如果在首選HBase中找不到需要的HTable,則回退到備選HBase叢集。(已提交社群:KYLIN-4175)

  1. 任務排程支援安全模式

安全模式下,使用者可繼續提交構建任務,且已在排程中的任務可以繼續執行,但新提交的任務暫緩排程。(已提交社群:KYLIN-4178)
遷移示意圖如下:
小米Kylin平滑遷移HBase實踐
圖2-支援secondary HBase方案
除了上述關鍵點,還需要注意一些細節問題。
1. 超大metadata的資料遷移
  超過閾值(預設為10MB)的metadata儲存在HBase依賴的HDFS上,需要手動遷移這部分資料。我們透過Hadoop distcp來遷移此部分資料。
2. coprocessor的更新
  Kylin使用了HBase的coprocessor機制,在執行查詢的時候掃描HBase的資料。起初我們認為可以使用相容HBase 0.98和2.2的coprocessor,實際測試中發現需要更新為支援HBase2.2的coprocessor。Kylin提供了工具來進行批次的更新。
構建基於HBase 2.2的Kylin,需要基於社群的2.5.x-hadoop3.1或2.6.x-hadoop3.1分支。我們選擇從Hadoop3.1的分支上移植相關特性。相關的JIRA有:KYLIN-2565、KYLIN-3518

>>>>

遷移步驟

具體遷移步驟如下:

  • HBase團隊搭建好基於HBase 2.2的獨立HBase叢集
  • HBase團隊新增新老叢集kylin_metadata表的非同步replication;
  • HBase團隊透過snapshot + restore同步HBase其他表,並更新coprocessor;
  • 在測試節點上回放生產環境查詢請求,驗證新叢集HBase資料表可正常提供查詢;
  • 開啟JobServer的安全模式,禁用新的任務排程;
  • 滾動升級QueryServer,切換至相容新舊HBase;
  • 等待安全模式下所有任務執行完成,切換JobServer至新HBase並關閉安全模式;
  • 等待表全部遷移完成,使用KylinHealthCheck工具檢查HBase表,確認所有在用cube segment對應的HBase表存在;
  • 檢查確認後,從Kylin去除舊HBase叢集配置;
  • 舊HBase叢集資料保留一段時間,最後清理刪除。

  問題&解決     
在演練和執行的過程中,我們遇到了如下的一些問題:

>>>>

Kylin metadata的一致性驗證

Metadata作為最重要的HBase表,影響著Kylin的主要功能。雖然有HBase replication來保證資料同步,也最好雙重確認來保障服務可用性。
我們在Kylin中開發了一個指令碼來批次對比兩個meta表,透過掃描meta表所有的鍵值和時間戳來發現差異。在初期確實發現了差異,也依此來修正了replication的配置。在HBase團隊的協助下,該表做到了實時的同步。

>>>>

新HBase資料表的可用性驗證

為了驗證新叢集的資料可用性,我們啟動了一個測試的Kylin例項用以模擬相容多個HBase叢集的查詢。測試例項不直接對使用者服務,而是透過回放SQL query來進行可用性測試。回放測試自動驗證查詢是否正常返回。
這種測試方式彌補了迴歸測試用例覆蓋範圍的不足,透過測試我們確實發現了隱藏的問題並進行了修復。在生產環境的切換中,未發生新的問題。

>>>>

HBase2 protobuf變更帶來的影響

測試中發現,若HBase返回資料量較大時會查詢報錯,提示訊息的長度超過限制:
InvalidProtocolBufferException:Protocol message was too large. May be malicious.
在查詢時,HBase和Kylin之間的資料傳送透過protobuf序列化。HBase 2修改了返回資料的方式,從一次性返回變成了流式的返回,從而觸發了protobuf的長度檢查邏輯。這個長度在protobuf 3之前的版本被限制為64M,支援透過setSizeLimit()方法來修改。
實際上,大多數Hadoop專案都會使用shaded protobuf並修改這個限制。由於Kylin專案中未使用自己打包的protobuf,因此這裡需要透過介面修改長度限制。
相關討論見:KYLIN-3973。

>>>>

HBase寫大檔案的異常

當Cube的預計算結果資料量比較大,單HBase region的檔案大小超過配置的閾值時,向HBase 2.2寫檔案會造成海量的小檔案。這一步發生在將計算的結果轉換為HFile時,此步驟的任務執行時間也比較長。這是由HBase 2.2的BUG導致,HBase的修復方案已合入最新分支。可以移植該patch以解決問題,也修改配置hbase.hregion.max.filesize來解決。
相關討論見:HBASE-22887、KYLIN-4292、KYLIN-4293。

>>>>

部分資料構建任務失敗

遷移過程中有兩種資料構建任務的失敗:包更新導致的失敗、segment合併的失敗。
由於Kylin的任務機制,在提交任務的時候就已經指定了使用的jar包的絕對路徑。如果Kylin的依賴升級後,jar包版本號發生了變化,就會導致執行異常。社群版本尚未修復,可以透過保留原來版本的檔案來避免該問題。相關討論見:KYLIN-4268。
另外,多叢集的HBase配置僅支援了查詢引擎,在合併最新生成的HBase表時會出現異常。我們認為segment合併可以接受一定時間的延遲,在HBase表同步完成後再觸發相關合並操作即可。
總結與展望
本次Kylin的HBase跨叢集遷移和版本升級的挑戰點是如何保證對使用者的影響最小。遷移的重點是設計一個高效遷移方案、保證遷移過程的資料一致性和正確性、保證測試方案的完整覆蓋,同時需要設計執行過程中的異常情況的判定和處理機制。
最後的Kylin滾動升級過程耗時2小時,也就意味著使用者作業的排程延後為2小時。基於前期的大量工作,最終實現了對業務的影響最小。我們在維護的內部版本的基礎上,透過技術修改優雅解決問題,相關成果也反饋給社群。
>>>>

後續改進

目前使用HBase作為Kylin的預計算結果儲存有著諸多問題。除了本文提到的海量表,還包括不支援第二索引、查詢引擎無法分散式、掃描表的資料量和時間存在限制等問題,這些都限制了Kylin的能力。社群正在實現Kylin on Parquet的方案,資料儲存使用Parquet,查詢引擎使用SparkSQL,此方案能夠極大的提升Kylin的能力。我們期待該方案的落地,也會積極的參與相關討論、開發和測試。
致謝
感謝HBase團隊同學在遷移期間的給力支援!
關於我們
小米雲平臺計算平臺團隊,負責為小米集團各業務線提供高品質的彈性排程和計算服務。包括離線平臺(Spark,Hadoop Yarn,Kylin,Drois等),流式平臺(Kafka,Flink及自研Talos等),彈性平臺(Docker,Kubernetes等)。武漢團隊主要負責Kylin、Druid等OLAP引擎開發。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559359/viewspace-2669548/,如需轉載,請註明出處,否則將追究法律責任。

相關文章