一、介紹
Phoenix是什麼?
Phoenix=HBase+SQL
可以理解爲在HBase的上層套了一層SQL引擎,支持用sql方式訪問HBase。
支持毫秒到秒級的低延時OLTP和操作型分析查詢
Phoenix能做什麼?
1.支持標準的SQL語法 轉爲HBase API
2.支持將算子、過濾條件下推到server端,並行執行
3.二級索引、分頁查詢、Join、輕量級事務等能力
結構:
- 客戶端 : JDBC程序或命令行,將SQL進行解析優化生成QueryPlan,進而轉化爲HBase Scans,調用HBase API下發查詢計算請求,並接收返回結果;
- 服務端 :
- Phoenix元數據表(如圖中SYSTEM.CATALOG) 儲存Phoenix表與元數據表的映射,建表時的信息和表狀態等。
- Phoenix協處理器(Endpoint類型) 處理二級索引、聚合及JOIN計算等。
優點:
1.SQL門檻低,使用便利,用戶接入成本低
2.用戶無需關心 rowkey設計, 熱點、分頁,簡單join等的設計
3.部分場景下讀取性能比直接讀HBase有提升
爲什麼部分場景比直接讀HBase快?
1.編譯SQL成爲原生HBASE的可並行執行的scan
2.計算下推,server端的coprocessor執行聚合
3.下推where過濾條件到server端的scan filter上
4.利用統計信息優化、選擇查詢計劃
5.二級索引 提高非行鍵查詢性能
6.skip scan 能力來優化IN,LIKE和OR查詢
7.可選的對行鍵進行加鹽以實現負載均衡,避免熱點
缺點:
1.寫入性能相比HBase下降: 寫入時需要對字段做一定處理,對狀態表更新,性能有一定下降,在20%以內
2.複雜join、groupby 性能低: 掃描數據量大
3.與二級索引的一致性不夠完善,僅有3種策略
4.部分場景讀性能有提升,但如果用戶將自己的需求以HBase原生API實現,性能相較於Phoenix是更優的。Phoenix內部經過解析,優化執行計劃等一些操作是有一定耗時的。
如何使用Phoenix?
1.JDBC API
2.使用Python編寫的命令行工具(sqlline, sqlline-thin和psql等)
3.SQuirrel
二、讀寫鏈路
讀:
客戶端:
1.接收sql
2.Parser 解析sql ,生成執行計劃QueryPlan
3.Optimizer 優化查詢計劃(判斷索引表是否可用,如可用則替換爲索引表的查詢計劃)
4.轉化成HBase 的 scan,發送RPC請求到RegionServer上
5.如有orderby count等聚合計算,請求到對應的協處理器方法上
服務端:
1.接受RPC請求,處理查詢
2.聚合計算先在多個rs上計算後,把多個計算後的結果返回給客戶端,客戶端再計算。
寫:
客戶端:
1.接收sql
2.解析轉成HBase的put ,發送RPC請求到RegionServer上(主表)
服務端:
1.接受RPC請求,處理主表的Put
2.協處理器的後臺線程,定時將新寫入主表的數據讀出,再put到索引表對應的HBase表上。
三、二級索引
適合用索引表的場景
-
-
- 單個主表滿足不了的查詢
- 過濾條件幾乎固定的,不在主表主鍵字段上的查詢
-
phoenix表的主鍵是由一個或多個字段組成,適合按rowkey,或前綴部分rowkey過濾查詢。但如有其他查詢場景無法指定前綴rowkey,要按其他字段做查詢條件,查詢需要掃描表的全量數據。hbase不適合掃描全表操作,數據量稍微大點掃描全表就不可用了。
使用索引表,查詢時可以根據索引表的主鍵快速掃描出需要的數據。
原理:
1.創建索引表時指定查詢場景下where 的字段和select的字段,最終索引表主鍵由做where條件的字段和主表主鍵字段一起組成,二級索引表底層也是HBase表。
2.查詢時客戶端解析sql,判斷是否有合適的二級索引,如果有則優化查詢計劃將scan落到索引表對應的HBase表上。
4.在索引表對應的HBase表上,索引表主鍵相當於rowkey,按rowkey進行掃描即可。
3.server端的協處理器的後臺線程會定時將新寫入主表的數據同步到二級索引表中。(歷史數據可通過異步補二級索引程序跑)
同步/異步:
1.異步建索引表比同步建索引表多加了ASYNC標識
2.異步索引表建好後一直是building狀態(可寫不可讀),
3.單純依賴phoenix內部補數據線程補數據很慢,且會增加集羣負載,通常直接跑異步二級索引,跑完後索引表就是active狀態
4.新建的主表一般建同步的索引表,如果主表已經有數據 就建異步索引表。
(如果主表有數據 建了同步的索引表,建索引表時會補數,補數完成才創建成功,耗時很久,若有同時有新寫入可能追不上)
四、常用運維手段及常見問題
1. 異步補二級索引
什麼時候需要跑異步二級索引?
建好異步索引表後,需要補歷史主表數據的情況下需要跑。
如何跑?
使用Phoenix的內置工具IndexTool執行。
如有需求可聯繫@數據引擎服務號v2 。
原理:
IndexTool是phoenix內置的工具,用作Build主表全量索引數據:
工具內使用snapshot,後起IndexTool MR job,output並bulkload到對應hbase集羣索引表,對regionserver讀寫無壓力。
2.主表寫阻塞或二級索引表被禁用
爲什麼會發生?
受主表索引表一致性策略影響,默認策略是: 當寫索引表失敗後,disable索引表,不阻塞主表寫。
這樣帶來的風險是:當寫索引表失敗時,索引表被disable,所有查詢落到主表上,出現掃全表情況,查詢慢超時,rs宕機,還可能影響其他業務。
最近在推使用推薦策略:當寫索引表失敗後,不disable索引表,阻塞主表寫。 這樣不會影響查詢,只是新的寫入受影響。
ps:第3種策略是disable索引表,不阻塞主表寫,這樣數據會不一致,不建議使用。
影響: 查詢時落到主表會掃全表
恢復:
1.確定寫索引表失敗原因,機器問題就挪出。更新索引表狀態爲active
2.寫入還是失敗可能需要重啓rs(主表和索引表儘量在不同分組,避免滾動升級期間寫索引表失敗引發一系列問題)
3.二級索引表不可用及恢復
現象: 索引表禁用時間戳(INDEX_DISABLE_TIMESTAMP)>0
影響: sql的查詢落到了主表上,沒有落到索引表上。由於主鍵不同,落到主表上後會掃全表,帶來rs壓力變大甚至宕機的風險。
需要做:
1.確定索引表狀態(查system.catalog表)
2.恢復主表下所有索引表狀態爲active(alter set)
alter index IDX_P002 ON TEST_NS.P003 ACTIVE;
3.如有主表索引表數據不一致的風險,需要補數據。
索引表被disable期間,如果繼續寫數據,數據會有不一致的情況。
狀態: