phoenix 與 hbase 整合,將hbase 自定義的namespace 放到phoenix 中進行完美整合

注意: 這裏以ambari 集羣進行整合說明

1. 前提條件

一. ambari 集羣上已經安裝好了phoenix 插件以及hbase 組件

二. 保證ambari 集羣的hdfs系統,zookeeper 系統,hbase 集羣,phoenix 組件server ,ranger 管理權限系統 已經正常運行.

 

 2. 配置hbase的namespace映射爲phoenix數據庫; (到hbase 服務的cofig 配置選項卡下選擇"自定義 hbase-site.xml" 配置中添加一下內容)
2.1 修改hbase-site.xml,增加下面配置項並重啓bhase服務,修改後hbase namespace會映射爲數據庫的schema .

 

property>
  <name>phoenix.schema.isNamespaceMappingEnabled</name>
  <value>true</value>
</property>
<property>
  <name>phoenix.schema.mapSystemTablesToNamespace</name>
  <value>true</value>
</property>

 

以上是大部分博客或者簡書都說到的,都需要配置的內容,但是在實際操作過程中發現此時hbase 和phoenix 只是針對系統namespace 是起到作用的,但是自定義的namespace  在phoenix 中是怎麼也找不着(我這裏是這樣的),經過兩天的查找資料以及查看phoenix 的官網(http://phoenix.apache.org/views.html)關於hbase 與phoenix 進行整合的講解方法,最終得到了答案 .

 

需要進行下面至關重要的一步:

3.進行hbase 與phoenix 的映射 表關係

參考網址: https://community.hortonworks.com/questions/215750/how-to-map-a-phoenix-viewtable-with-a-different-na.html

先在phoenix shell  命令行,使用命令查看:

命令:

select DISTINCT TABLE_SCHEM from SYSTEM.CATALOG;

     1). 若發現 只有一個schem 那說明只是系統的 ;

      2). 若發現不知一個schem  的話,說明上面的配置已經完全找到hbase 的namespace ,其下面的操作都不需要在進行操作了,直接就進行關於phoenix 與hbase 的表進行映射吧.

 

若你出現方框中的第一個情況,在phoenix shell  命令行直接進行下面這條sql 語句:

CREATE SCHEMA IF NOT EXISTS   "test"; 

   注意:

       1. 這裏"test" 是我集羣中hbase 的namespace 中一個測試庫,請換成自己的hbase 集羣 的namespace;

       2. phoenix shell 的sql 語句中有大小寫區分,默認是使用字母大寫,使用雙引號就不會轉換成大寫; 

    當添加schema 成功之後,然後再執行第一條sql 命令查看 schema ,會發現我們已經成功添加了一個schema  .然後按照 常規操作建立phoenix 與 hbase 建立映射表 關係 

以上就是hbase與phoenix 組件進行整合細節操作 .


4. phoenix 一些擴展內容

 下面的內容是參考網址( https://www.jianshu.com/p/91decdd7fc5d ) 的內容

     我覺得寫的是非常好的,但是沒有進行實踐過,希望大家可以學習一下.

 

加鹽表

1. 什麼是加鹽?

在密碼學中,加鹽是指在散列之前將散列內容(例如:密碼)的任意固定位置插入特定的字符串。這個在散列中加入字符串的方式稱爲“加鹽”。其作用是讓加鹽後的散列結果和沒有加鹽的結果不相同,在不同的應用情景中,這個處理可以增加額外的安全性。而Phoenix中加鹽是指對pk對應的byte數組插入特定的byte數據。

2. 加鹽能解決什麼問題?

加鹽能解決HBASE讀寫熱點問題,例如:單調遞增rowkey數據的持續寫入,使得負載集中在某一個RegionServer上引起的熱點問題。

3. 怎麼對錶加鹽?

在創建表的時候指定屬性值:SALT_BUCKETS,其值表示所分buckets(region)數量, 範圍是1~256。

CREATE TABLE table (key VARCHAR PRIMARY KEY, col VARCHAR) SALT_BUCKETS = 8;

4. 加鹽的原理是什麼?

加鹽的過程就是在原來key的基礎上增加一個byte作爲前綴,計算公式如下:

new_row_key = (++index % BUCKETS_NUMBER) + original_key

下圖展示了自增rowkey通過加鹽被打散寫入到各個region中的過程

5. 一個表“加多少鹽合適”?

當可用block cache的大小小於表數據大小時,較優的slated bucket是和region server數量相同,這樣可以得到更好的讀寫性能。

當表的數量很大時,基本上會忽略blcok cache的優化收益,大部分數據仍然需要走磁盤IO。比如對於10個region server集羣的大表,可以考慮設計64~128個slat buckets。

6. 加鹽時需要注意

創建加鹽表時不能再指定split key。

太大的slated buckets會減小range查詢的靈活性,甚至降低查詢性能。

References

https://phoenix.apache.org/salted.html

https://zh.wikipedia.org/wiki/%E7%9B%90_(%E5%AF%86%E7%A0%81%E5%AD%A6)

https://community.hortonworks.com/questions/26269/how-many-salt-buckets-should-i-use-for-my-phoenix.html

 


二級索引

一.概要

目前HBASE只有基於字典序的主鍵索引,對於非主鍵過濾條件的查詢都會變成掃全表操作,爲了解決這個問題Phoenix引入了二級索引功能。然而此二級索引又有別於傳統關係型數據庫的二級索引,本文將詳細描述Phoenix中二級索引功能、用法和原理,希望能夠對大家在業務技術選型時起到一些幫助作用。

二.二級索引

示例表如下(爲了能夠容易通過HBASE SHELL對照表內容,我們對屬性值COLUMN_ENCODED_BYTES設置爲0,不對column family進行編碼):

CREATE TABLE  TEST (   ID VARCHAR NOT NULL  PRIMARY KEY,   COL1 VARCHAR,   COL2 VARCHAR  ) COLUMN_ENCODED_BYTES=0;

upsert into TEST values('1', '2', '3');

1. 全局索引

全局索引更多的應用在讀較多的場景。它對應一張獨立的HBASE表。對於全局索引,在查詢中檢索的列如果不在索引表中,默認的索引表將不會被使用,除非使用hint。

創建全局索引:

CREATE INDEX IDX_COL1 ON TEST(COL1)

通過HBASE SHELL觀察生成的索引表IDX_COL1。我們發現全局索引表的RowKey存儲了索引列的值和原表RowKey的值,這樣編碼更有利於提高查詢的性能。

hbase(main):001:0> scan 'IDX_COL1'ROW                        COLUMN+CELL 2\x001                    column=0:_0, timestamp=1520935113031, value=x1 row(s) in 0.1650 seconds

實際上全局索引的RowKey將會按照如下格式進行編碼

 

SALT BYTE: 全局索引表和普通phoenix表一樣,可以在創建索引時指定SALT_BUCKETS或者split key。此byte正是存儲着salt。TENANT_ID: 當前數據對應的多租戶ID。INDEX VALUE: 索引數據。PK VALUE: 原表的RowKey。

2. 本地索引

因爲本地索引和原數據是存儲在同一個表中的,所以更適合寫多的場景。對於本地索引,查詢中無論是否指定hint或者是查詢的列是否都在索引表中,都會使用索引表。

創建本地索引:

create local index LOCAL_IDX_COL1 ON TEST(COL1);

通過HBASE SHELL觀察表'TEST', 我們可以看到表中多了一行column爲L#0:_0的索引數據。

hbase(main):001:0> scan 'TEST'ROW                        COLUMN+CELL \x00\x002\x001            column=L#0:_0, timestamp=1520935997600, value=_0 1                         column=0:COL1, timestamp=1520935997600, value=2 1                         column=0:COL2, timestamp=1520935997600, value=3 1                         column=0:_0, timestamp=1520935997600, value=x2 row(s) in 0.1680 seconds

本地索引的RowKey將會按照如下格式進行編碼

 

REGION START KEY : 當前row所在region的start key。加上這個start key的好處是,可以讓索引數據和原數據儘量在同一個region, 減小IO,提升性能。INDEX ID : 每個ID對應不同的索引表。TENANT ID :當前數據對應的多租戶ID。INDEX VALUE: 索引數據。PK VALUE: 原表的RowKey。

3. 覆蓋索引

覆蓋索引的特點是把原數據存儲在索引數據表中,這樣在查詢到索引數據時就不需要再次返回到原表查詢,可以直接拿到查詢結果。

創建覆蓋索引:

create  index IDX_COL1_COVER_COL2 on TEST(COL1) include(COL2);

通過HBASE SHELL 查詢表IDX_COL1_COVER_COL2, 我們發現include的列的值被寫入到了value中。

hbase(main):003:0> scan 'IDX_COL1_COVER_COL2'ROW                   COLUMN+CELL 2\x001               column=0:0:COL2, timestamp=1520943893821, value=3 2\x001               column=0:_0, timestamp=1520943893821, value=x1 row(s) in 0.0180 seconds

對於類似select col2 from TEST where COL1='2'的查詢,查詢一次索引表就能獲得結果。其查詢計劃如下:

+--------------------------------------------------------------------------------------+-----------------+----------------+---+|                                         PLAN                                         | EST_BYTES_READ  | EST_ROWS_READ  | E |+--------------------------------------------------------------------------------------+-----------------+----------------+---+| CLIENT 1-CHUNK PARALLEL 1-WAY ROUND ROBIN RANGE SCAN OVER IDX_COL1_COVER_COL2 ['2']  | null            | null           | n |+--------------------------------------------------------------------------------------+-----------------+----------------+---+

4. 函數索引

函數索引的特點是能根據表達式創建索引,適用於對查詢表,過濾條件是表達式的表創建索引。例如:

//創建函數索引CREATE INDEX CONCATE_IDX ON TEST (UPPER(COL1||COL2))//查詢函數索引SELECT * FROM TEST WHERE UPPER(COL1||COL2)='23'

三.什麼是Phoenix的二級索引?

Phoenix的二級索引我們基本上已經介紹過了,我們回過頭來繼續看Phoenix二級索引的官方定義:Secondary indexes are an orthogonal way to access data from its primary access path。簡單理解爲,在主訪問路徑(通過row key訪問)上發生正交的一種方法,更清楚的應該描述爲:索引列訪問和row key訪問產生交集時的一種索引方法。我們來通過一個例子說明:

1. 對錶TEST的COL1創建全局索引

CREATEINDEXIDX_COL1ONTEST(COL1);

2. 對於如下查詢必將發生FULL SCAN

select*fromTESTwhereCOL1='2';

以上查詢的查詢計劃如下:

+----------------------------------------------------------------+-----------------+----------------+--------------+|                              PLAN                              | EST_BYTES_READ  | EST_ROWS_READ  | EST_INFO_TS  |+----------------------------------------------------------------+-----------------+----------------+--------------+| CLIENT1-CHUNK PARALLEL1-WAY ROUND ROBIN FULL SCAN OVER TEST  |null|null|null||     SERVER FILTER BY COL1 ='2'|null|null|null|+----------------------------------------------------------------+-----------------+----------------+--------------+

3. 對於以下查詢將會形成點查。因爲二級索引是RowKey的交集。

select * from TEST where id='1' and COL1='2'

查詢計劃如下

+---------------------------------------------------------------------------------------------+-----------------+-------------+|                                            PLAN                                             | EST_BYTES_READ  | EST_ROWS_RE |+---------------------------------------------------------------------------------------------+-----------------+-------------+| CLIENT 1-CHUNK 1 ROWS 203 BYTES PARALLEL 1-WAY ROUND ROBIN POINT LOOKUP ON 1 KEY OVER TEST  | 203             | 1           ||     SERVER FILTER BY COL1 = '2'                                                             | 203             | 1           |+---------------------------------------------------------------------------------------------+-----------------+-------------+

對於2中所描述的查詢爲什麼會發生FULL SCAN? 正如Phoenix二級索引官方定義的一樣,因爲“沒有和RowKey列的查詢發生正交關係”,除非使用Hint強制指定索引表。

四.索引Building

Phoenix的二級索引創建有同步和異步兩種方式。

在執行CREATE INDEX IDX_COL1 ON TEST(COL1)時會進行索引數據的同步。此方法適用於數據量較小的情況。

異步build索引需要藉助MR,創建異步索引語法和同步索引相差一個關鍵字:ASYNC。

//創建異步索引CREATE INDEX ASYNC_IDX ON DB.TEST (COL1) ASYNC//build 索引數據${HBASE_HOME}/bin/hbase org.apache.phoenix.mapreduce.index.IndexTool --schema DB --data-table TEST --index-table ASYNC_IDX  --output-path ASYNC_IDX_HFILES

五.索引問題彙總

1. 創建同步索引超時怎麼辦?

在客戶端配置文件hbase-site.xml中,把超時參數設置大一些,足夠build索引數據的時間。

 

2. 索引表最多可以創建多少個?

建議不超過10個

3. 爲什麼索引表多了,單條寫入會變慢?

索引表越多寫放大越嚴重。寫放大情況可以參考下圖。

 

References

https://phoenix.apache.org/secondary_indexing.html

https://community.hortonworks.com/articles/61705/art-of-phoenix-secondary-indexes.html


MR在Ali-Phoenix上的使用

一.MR在Phoenix上的用途

利用MR對Phoenix表(可帶有二級索引表)進行Bulkload入庫, 其原理是直接生成主表(二級索引表)的HFILE寫入HDFS。相對於走API的數據導入方式,不僅速度更快,而且對HBASE集羣的負載也會小很多。目前雲HBASE上的Phoenix支持以下數據源的Bulkload工具:

CsvBulkLoadTool

JsonBulkLoadTool

RegexBulkLoadTool

ODPSBulkLoadTool(待上線)

利用MR Building二級索引。當主表數據量較大時,可以通過創建異步索引,使用MR快速同步索引數據。

二.如何訪問雲HBASE的HDFS?

由於雲HBASE上沒有MR,需要藉助外部的計算引擎(自建的HADOOP集羣或者EMR),而使用外部的計算引擎的首先面臨的問題是,如何跨集羣訪問HDFS。

由於雲HBASE的HDFS端口默認是不開的,需要聯繫工作人員開通。

端口開通以後,要想順利的訪問HDFS是HA配置的雲HBASE集羣,需要向工作人員獲取雲HBASE的主備(emr-header-1,emr-header-2)namenode host/IP。參考如下配置模板,設置hadoop客戶端配置文件:

core-site.xml

hdfs-site.xml

驗證訪問雲HBASE HDFS

hadoop dfs -ls hdfs://emr-cluster/

三.BULKLOAD PHOENIX表

1. 由於要和雲HBASE通信,所以客戶端的依賴的hbase-protocol.jar需要是1.1.x版本。可以使用鏈接:http://central.maven.org/maven2/org/apache/hbase/hbase-protocol/1.1.1/hbase-protocol-1.1.1.jar 下載。

2. 以EMR訪問雲HBASE爲例。EMR集羣需要把雲HBASE HDFS的emr-cluster 相關配置和當前EMR的HDFS配置合在一起形成新的配置文件,單獨存放在一個目錄(${conf-dir})下。通過yarn命令的--config參數指定新的配置目錄,使這些配置文件放在CLASSPATH最前面覆蓋掉當前EMR集羣hadoop_conf_dir下的配置,以便bulkload程序能識別到雲HBASE HA的HDFS URL。

3. 執行BULKLOAD命令

yarn --config ${CONF_DIR} jar ${PHOENIX_HOME}/phoenix-${version}-client.jar org.apache.phoenix.mapreduce.CsvBulkLoadTool --table "TABLENAME" --input "hdfs://emr-header-1.cluster-55090:9000/tmp/test_data"  --zookeeper "zk1,zk2,zk3" --output "hdfs://emr-cluster/tmp/tmp_data"

注意: --output 配置的是雲HBASE的臨時文件,這樣直接把生成的HFILE存儲在雲HBASE的HDFS上,後續的只有簡單的move操作。否則,如果生成在EMR集羣還需要走網絡發送到雲HBASE HDFS上。

 

 

 

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