1. 程式人生 > >Phoenix二級索引原理及Bulkload注意問題

Phoenix二級索引原理及Bulkload注意問題

前言

最近在Hbase的使用過程中遇到了很多問題,通過各種查資料測試最終得到解決。趁此機會也對Hbase預分割槽及索引的原理作了一些較深入的學習,以便更好的使用Hbase及對資料庫效能調優。
下面對Hbase的索引觸發原理及Bulkload匯入資料需注意的問題作了簡要總結,希望能對大家起到一些幫助,共同學習進步。


1. Phoenix索引在Hbase中的儲存形式

使用phoenix為hbase中表example建立二級索引INDEX_EXAMPLE後,在Hbase或Phoenix中使用list!tables命令檢視當前表的時候,會發現多了資料庫中多了一張原表對應的索引表。

phoenix索引表在Hbase中也是以表的形式存在,且該表的Row_key就是建立索引時的所有索引欄位的拼接。當為多列建立索引時,rowkey實際上是這些column的組合,並且是按照它們的先後順序的組合。


2. 多列索引的原理

在Phoenix中,我們可以為一張表的多個列(column)建立索引,但是在查詢時必須要按照索引列的順序來查詢。例如,以下表為例:


# 建立表
CREATE TABLE example (
	row_key varchar primary key,
	col1 varchar,
	col2  varchar,
	col3 varchar,
	col4  varchar,
	col5 varchar
)


# 為col1,col2,col3三個列建立索引
create index idx_example on example (col1,col2,col3)

那麼為了保證查詢走索引,在查詢的時候需要注意:

在查詢時,可以同時將這3個索引列作為條件,且順序不限。但是,第一列必須是col1

這是因為,如果查詢時第一列不是col1,那麼就會進行全表掃描(full scan),速度會很慢。
而如果查詢的第一列是col1,就可以直接將滿足關於col1的資料記錄找出來。即使後面還有沒有被索引的列,也可以很快得到結果,因為滿足關於M.C0的結果集已經不大了(如果是這種情況的話),對其再進行一次查詢不會是full scan。


3. 使用Bulkload方式插入要注意的問題

Hbase和Phoenix都提供了Bulkload工具來支援快速大批量匯入資料,但當在表上建立索引後,再使用Bulkload方式匯入資料需注意資料插入後索引表是否同步更新。

3.1. 使用Hbase Bulkload方式(completeBulkload)

使用Hbase提供的bulkload方式批量匯入資料時,不能同步更新索引表。

這是因為當以bulkload的方式來將資料匯入到data table時,會繞開HBase的常規寫入路徑(client –> buffer –> memstore –> HLog –> StoreFile –> HFile),直接生成最終的HFiles。正常通過介面直接寫資料進Phoenix表,相應的索引表也是會更新的,但是直接寫資料到底層hbase表,這時候對應的索引表是不會更新,從而影響正常的使用者訪問。

優點:
支援java、Spark API,能夠在java、spark程式中直接呼叫。
缺點:
不支援索引的同步更新


3.2 使用Phoenix Bulkload方式(csvBulkload)

使用Hbase提供的bulkload方式批量匯入資料時,該表對應的索引表也會同步更新。

優點:
支援同步更新索引表。
缺點:
不支援java、Spark API,只能在命令列中使用,且需指定hadoop配置檔案。


參考:

Phoenix 索引生命週期
利用Phoenix為HBase建立二級索引
解決Hbase資料更新Phoenix對應索引表不更新問題