天天看點

HBase解讀 | 阿裡雲HBase SQL(Phoenix)服務深度解讀

阿裡雲HBase SQL服務簡介

雲HBase2.0是阿裡雲對社群HBase2.0的深度定制,在核心層面做了大量優化更新,并提供全球多活、備份恢複、冷存儲等企業級特性,目前已被廣泛應用于車聯網、社交、推薦、畫像等場景。阿裡雲HBase

SQL基于Phoenix 5.0版本,為雲HBase2.0賦予NewSQL特性,降低KV接口使用複雜性,并提供Schema、Secondary

Indexes、View 、Bulk Loading(離線大規模load資料)、Atomic Upsert、Salted

Tables、Dynamic Columns、Skip

Scan等特性的能力,大大降低了使用者的使用門檻,關于更多Phoenix的介紹參考“HBase進化之從NoSQL到NewSQL,鳳凰涅槃成就Phoenix”:

https://yq.aliyun.com/articles/680772

阿裡雲HBase團隊将SQL能力服務化,在産品、核心上做了一系列優化更新,筆者将在本文中對這些特性做深度解讀。

HBase解讀 | 阿裡雲HBase SQL(Phoenix)服務深度解讀

雲HBase SQL團隊針對社群Phoenix5.0版本進行深度測試,對輕用戶端進行了一系列的優化和Bug Fix,并回報給Phoenix和Avatica社群,推動社群共同發展。

1.輕用戶端寫性能優化

在對輕用戶端的寫入性能測試時,我們發現社群輕用戶端的寫入性能比直接使用重用戶端慢2~3倍,主要原因正式由于輕用戶端相比重用戶端多了一層HTTP傳輸鍊路,是以在盡量不修改業務代碼的前提下,如何減少請求次數是優化寫性能的重點。

在業務代碼中經常使用JDBC的PreparedStatement的executeUpdate進行寫入,社群輕用戶端在autoCommit為false時會将資料傳輸至QueryServer并緩存,在commit時将資料batch寫入到HBase中。阿裡雲Phoenix修改executeUpdate執行邏輯,将資料緩存在用戶端,commit時将批量資料發到QueryServer并直接寫入HBase,在這一階段減少了輕用戶端到QueryServer的RPC請求次數,并避免緩存在QueryServer的資料在未送出前由于服務挂掉而丢失。優化後在代碼寫入性能提升了2倍多,與重用戶端性能基本沒有差距。

2.支援upsert multi values文法

原生Phoenix在寫入時僅支援單次upsert一條資料的文法,這在對接MyBatis等不支援commit的架構時,每次寫入一條資料并送出HBase性能上較差,為此阿裡雲Phoenix在SQL服務上支援單次upsert寫入多值功能,文法示例:upsert

into tableName(col1,col2,...) values

(v11,v12,...),(v21,v22,...),...,(vn1,vn2,...)

在使用時注意:

為避免列次序混亂,必須指定寫入列

寫入資料其中一條失敗導緻整批資料寫入失敗

3.支援QueryServer線程池最大線程和HTTP傳輸參數可配

QueryServer使用Jetty做為HttpServer,在初始化時預設最大200個線程,在使用配置比較高的HBase叢集時,往往由于處理線程數成為性能瓶頸,阿裡雲Phoenix修改了Avatica代碼,通過增加配置方式使得線程數以及HTTP傳輸size大小等都可配,增加Phoenix使用的靈活性,具體配置及說明如下:

參數名

描述

phoenix.queryserver.maximun.threads

QueryServer最大線程數,預設200

phoenix.queryserver.minimum.threads

QueryServer最小線程數,預設8

phoenix.queryserver.idle.timeout

線程空閑逾時時間,預設60s

phoenix.queryserver.maximum.header.size

HTTP請求標頭大小,預設65536byte

以上參數在雲HBase控制台都可以進行修改,并重新開機HBase SQL服務後生效。

4.輕用戶端Connection逾時Reopen時設定參數丢失問題

輕用戶端連接配接預設空閑10min會逾時,下次使用時會進行重建,如果在逾時前設定autoCommit、schema等連接配接屬性會在reOpen時失效,這是社群avatica的一個bug,我們對此進行修複并貢獻到社群,對應JIRA:

https://issues.apache.org/jira/browse/CALCITE-2882(貢獻社群calcite-avatica 1.14.0版本)

5.輕用戶端PrepareStatement預編譯帶有子查詢/join語句時參數越界

在使用輕用戶端PrepareStatement預編譯SQL時會将Phoenix用戶端的ParamMetaData同步到輕用戶端的Connection,當SQL帶有子查詢或join語句時,Phoenix在實作上缺失了右表的Meta資訊,導緻出現參數越界的問題。

阿裡雲的Phoenix版本也對此進行修複,詳細見JIRA:

https://issues.apache.org/jira/browse/PHOENIX-5192

6.輕用戶端寫入Array類型資料NPE

輕用戶端寫入Array類型資料時由于擷取Array中子元素的類型預設處理為空,導緻在寫入時出現NPE。問題修複見JIRA:

https://issues.apache.org/jira/browse/CALCITE-2939(貢獻社群calcite-avatica 1.14.0版本)

我們對Phoenix Core做了大量穩定性、性能方面的優化和改進,送出了數十個patch給社群,團隊的瑾謙同學也成為了Phoenix社群的Commiter。下面介紹幾個比較有代表性的改進工作:

1.大表MetaCache緩存優化

Phoenix每次查詢都需要使用表的所有Region資訊,當表很大有上萬個Region時,讀取meta表的Region資訊并緩存到用戶端需要耗時幾十秒,占用查詢時間超過80%以上。阿裡雲Phoenix使用ZooKeeper訂閱的方式,通過監控Region的狀态變化,當Region發生balance/merge/split動作時,更新用戶端緩存失效的Region資訊,這樣可以大大減少用戶端因為Region中繼資料更新不及時導緻的查詢失敗,同時顯著提高查詢性能。

HBase解讀 | 阿裡雲HBase SQL(Phoenix)服務深度解讀

優化效果:經過測試對一張大表查詢時如果出現Region狀态變化,查詢時延由40s降低到5s左右。

2.使用Lookup Join提升大表的索引表回查性能

如果Phoenix二級索引不是覆寫索引,也就是說SELECT語句中的傳回字段不在索引表中,那麼在執行過程中會先查詢索引表,擷取RowKey,然後再用SemiJoin主表的方式擷取最終結果。除了索引表本身的Scan開銷外,還存在網絡開銷和SemiJoin本身的開銷。我們采用Lookup

Join的方式進行優化,在服務端scan索引表的時候,直接回查主表。經過測試,性能有大幅提高,500w資料量的查詢,原有方式需要200s,而新的方式隻需要10s,如果主表開啟bloomfilter,性能還能進一步提高到5s左右。

3.使用MultiGet取代SkipScan

Phoenix在執行SemiJoin的時候會使用SkipScan的方式,該方式比較通用,scan的過程中會skip掉一定的讀HFile開銷,但是當SemiJoin的查詢條件比較多并且比較分散時,就轉變為了近似掃全表,這時性能就會下降嚴重,甚至逾時。對于這種情況,我們采用了MultiGet的方式取代SkipScan會獲得更好的性能。當使用者對Primary

Key做in查詢時,可以通過添加“USE_GET”的hint使用該功能,可以支援10w級别的子查詢結果。在查詢條件比較多并且分散的情況,會有數量級的性能提升。

4.臨時禁止掉存在風險的功能feature

社群Phoenix功能很多很全,但是某些功能存在一定缺陷,或者會引入風險,在確定功能完善可用之前,我們會選擇将部分功能禁掉,以避免使用者誤用,導緻錯誤。目前涉及到的功能有:

ColumnDef中的DESC關鍵字。對于可變長度類型,比如varchar、decimal,該功能可能範圍查詢結果傳回錯誤。

全表掃描。對于沒有加查詢條件的查詢語句,可能會觸發全表掃描,導緻系統不穩定。

Local Index。由于社群回報和我們在實際支援使用者的過程中發現的Local Index問題較多,而且大部分二級索引的場景,Global Index已經足夠使用,是以我們臨時禁掉了Local Index的功能。

5.時區問題解決

社群Phoenix在時區處理上的邏輯會導緻使用者的不同用法,寫入資料和查詢結果不一緻。詳見文章“Phoenix關于時區的處理方式說明”:

https://yq.aliyun.com/articles/684390

阿裡雲HBase團隊在SQL服務上持續深耕,不斷在穩定性、易用性、功能以及性能上繼續增強優化,并不斷回報社群,積極推動Phoenx社群的發展。從HBase的架構上來看,相比于其他NoSQL存儲引擎,其在資料規模,擴充性上具有明顯優勢。跟大資料其他元件,比如,搜尋引擎、分析引擎、消息引擎,會更緊密的結合,SQL服務也會在這方面進行更多的探索,滿足使用者在實際使用過程中遇到的複雜查詢、複雜分析等需求。在這裡可以預告下,我們基于HBase和Solr雙引擎,支援複雜查詢的Phoenix

Search Index功能即将上線。

HBase解讀 | 阿裡雲HBase SQL(Phoenix)服務深度解讀