Phoenix on HBase
阿新 • • 發佈:2017-08-02
inpu and 增加 src 集群負載 .cn 步長 傳輸 hbase (一)概要
Apache Phoenix是基於BSD許可開源的一個Java中間層,可以讓開發者在Apache HBase上執行SQL查詢。Apache Phoenix主要特性:
# mvn package -DskipTests -Dhadoop.profile=2 將Phoenix服務端二進制拷貝至HBase region server lib 目錄下,這裏以CDH為例: # mv $PHOENIX_HOME/phoenix-core/target/phoenix-core-4.0.0-incubating.jar /opt/cloudera/parcels/CDH/lib/hbase/lib/
# mv $PHOENIX_HOME/phoenix-hadoop2-compat/target/phoenix-hadoop2-compat-4.0.0-incubating.jar /opt/cloudera/parcels/CDH/lib/hbase/lib/ 將Phoenix客戶端二進制增加至Client CLASSPATH # CLASSPATH=$CLASSPATH:$PHOENIX_HOME/phoenix-assembly/target/phoenix-4.0.0-incubating-client.jar (三)Quick Start
1)Shell 操作
啟動HBase驗證
# hbase shell
hbase(main):001:0> list 啟動Phoenix # bin/sqlline.py zk_host
0: jdbc:phoenix:zk_host> !columns TEST 回到HBase Terminal: hbase(main):001:0> list
hbase(main):002:0> scan ‘TEST‘ 2)Java Client
新建一個Java Client Source 文件,內容如下:
# java -cp phoenix-assembly/target/phoenix-4.0.0-incubating-client.jar:. TestJava 3)數據導入 3.1 Loading CSV data via PSQL 以Phoenix自帶的examples為例,建表、導入數據、查詢結果,命令如下: #bin/psql.py zk_host examples/WEB_STAT.sql examples/WEB_STAT.csv examples/WEB_STAT_QUERIES.sql 詳細用法參考如下: http://phoenix.incubator.apache.org/bulk_dataload.html 3.2 Loading via MapReduce 3.2.1)建表 #bin/psql.py zk_host examples/WEB_STAT.sql 3.2.2)創建待導入HDFS數據文件 # sudo -u hdfs hadoop fs -mkdir /user/phoenix/
# sudo -u hdfs hadoop fs -put examples/WEB_STAT.csv /user/phoenix/ 3.2.3)從HDFS向Phoenix HBase導入數據(以CDH為例) # sudo -u hdfs HADOOP_CLASSPATH=$(hbase classpath) hadoop jar phoenix-assembly/target/phoenix-4.0.0-incubating-client.jar org.apache.phoenix.mapreduce.CsvBulkLoadTool -zookeeper zk_host --table WEB_STAT --input /user/phoenix/WEB_STAT.csv 或者 # sudo -u hdfs HADOOP_CLASSPATH=/opt/cloudera/parcels/CDH-5.0.0-1.cdh5.0.0.p0.47/lib/hbase/hbase-protocol.jar:/etc/hbase/conf hadoop jar phoenix-assembly/target/phoenix-4.0.0-incubating-client.jar org.apache.phoenix.mapreduce.CsvBulkLoadTool -zookeeper zk_host --table WEB_STAT --input /user/phoenix/WEB_STAT.csv 4)映射現有HBase表 在Phoenix中通過CREATE TABLE/CREATE VIEW DDL映射HBase表
phoenix> CREATE TABLE "t1" ( pk VARCHAR PRIMARY KEY, "cf".a VARCHAR, "cf".B VARCHAR, "cf".C VARCHAR );
phoenix> select * from "t1"; 在HBase中使用Shell創建一個測試表,並插入若幹數據 hbase> put ‘t1‘, ‘row1‘, ‘cf:a‘, ‘value1‘
hbase> put ‘t1‘, ‘row1‘, ‘cf:B‘, ‘value2‘
hbase> put ‘t1‘, ‘row1‘, ‘cf:c‘, ‘value3‘
hbase> scan ‘t1‘ 註意:
1.1)Mutable Index
CREATE SEQUENCE my_sequence START WITH -1000;
CREATE SEQUENCE my_sequence INCREMENT BY 10;
CREATE SEQUENCE my_schema.my_sequence START 0 CACHE 10;
這裏以bin/psql.py客戶端腳本執行調優為例,修改$PHOENIX/phoenix-assembly/target目錄下的phoenix-4.0.0-incubating-client.jar的hbase-default.xml文件,增加如下內容以實現將客戶端默認緩存從100MB調整為1GB:
phoenix.query.maxServerCacheBytes
1024000000
- 嵌入式的JDBC驅動,實現了大部分的java.sql接口,包括元數據API
- 可以通過多部行鍵或是鍵/值單元對列進行建模
- 完善的查詢支持,可以使用多個謂詞以及優化的掃描鍵
- DDL支持:通過CREATE TABLE、DROP TABLE及ALTER TABLE來添加/刪除列
- 版本化的模式倉庫:當寫入數據時,快照查詢會使用恰當的模式
- DML支持:用於逐行插入的UPSERT VALUES、用於相同或不同表之間大量數據傳輸的UPSERT SELECT、用於刪除行的DELETE
- 通過客戶端的批處理實現的有限的事務支持
- 單表——還沒有連接,同時二級索引也在開發當中
- 緊跟ANSI SQL標準,HIVE不完全支持SQL92,而Phoenix 接近ANSI SQL-2003
- Phoenix 2.x - HBase 0.94.x
- Phoenix 3.x - HBase 0.94.x
- Phoenix 4.x - HBase 0.98.1+
# mvn package -DskipTests -Dhadoop.profile=2 將Phoenix服務端二進制拷貝至HBase region server lib 目錄下,這裏以CDH為例: # mv $PHOENIX_HOME/phoenix-core/target/phoenix-core-4.0.0-incubating.jar /opt/cloudera/parcels/CDH/lib/hbase/lib/
# mv $PHOENIX_HOME/phoenix-hadoop2-compat/target/phoenix-hadoop2-compat-4.0.0-incubating.jar /opt/cloudera/parcels/CDH/lib/hbase/lib/ 將Phoenix客戶端二進制增加至Client CLASSPATH # CLASSPATH=$CLASSPATH:$PHOENIX_HOME/phoenix-assembly/target/phoenix-4.0.0-incubating-client.jar (三)Quick Start
hbase(main):001:0> list 啟動Phoenix # bin/sqlline.py zk_host
create table test (mykey integer not null primary key, mycolumn varchar); upsert into test values (1,‘Hello‘); upsert into test values (2,‘World!‘); select * from test;註意:Phoenix使用sqlline作為連接終端,詳細命令可參考http://www.hydromatic.net/sqlline/manual.html,如可使用如下命令查看HBase數據庫表和表的列屬性: 0: jdbc:phoenix:zk_host> !tables
0: jdbc:phoenix:zk_host> !columns TEST 回到HBase Terminal: hbase(main):001:0> list
hbase(main):002:0> scan ‘TEST‘ 2)Java Client
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.PreparedStatement; import java.sql.Statement; public class TestJava { public static void main(String[] args) throws SQLException { Statement stmt = null; ResultSet rset = null; Connection con = DriverManager.getConnection("jdbc:phoenix:[zk_host]"); // 已通過Shell建立 //stmt = con.createStatement(); //stmt.executeUpdate("create table test (mykey integer not null primary key, mycolumn varchar)"); //stmt.executeUpdate("upsert into test values (1,‘Hello‘)"); //stmt.executeUpdate("upsert into test values (2,‘World!‘)"); //con.commit(); PreparedStatement statement = con.prepareStatement("select * from test"); rset = statement.executeQuery(); while (rset.next()) { System.out.println(rset.getString("mycolumn")); } statement.close(); con.close(); } }編譯並執行: # javac TestJava.java
# java -cp phoenix-assembly/target/phoenix-4.0.0-incubating-client.jar:. TestJava 3)數據導入 3.1 Loading CSV data via PSQL 以Phoenix自帶的examples為例,建表、導入數據、查詢結果,命令如下: #bin/psql.py zk_host examples/WEB_STAT.sql examples/WEB_STAT.csv examples/WEB_STAT_QUERIES.sql 詳細用法參考如下: http://phoenix.incubator.apache.org/bulk_dataload.html 3.2 Loading via MapReduce 3.2.1)建表 #bin/psql.py zk_host examples/WEB_STAT.sql 3.2.2)創建待導入HDFS數據文件 # sudo -u hdfs hadoop fs -mkdir /user/phoenix/
# sudo -u hdfs hadoop fs -put examples/WEB_STAT.csv /user/phoenix/ 3.2.3)從HDFS向Phoenix HBase導入數據(以CDH為例) # sudo -u hdfs HADOOP_CLASSPATH=$(hbase classpath) hadoop jar phoenix-assembly/target/phoenix-4.0.0-incubating-client.jar org.apache.phoenix.mapreduce.CsvBulkLoadTool -zookeeper zk_host --table WEB_STAT --input /user/phoenix/WEB_STAT.csv 或者 # sudo -u hdfs HADOOP_CLASSPATH=/opt/cloudera/parcels/CDH-5.0.0-1.cdh5.0.0.p0.47/lib/hbase/hbase-protocol.jar:/etc/hbase/conf hadoop jar phoenix-assembly/target/phoenix-4.0.0-incubating-client.jar org.apache.phoenix.mapreduce.CsvBulkLoadTool -zookeeper zk_host --table WEB_STAT --input /user/phoenix/WEB_STAT.csv 4)映射現有HBase表 在Phoenix中通過CREATE TABLE/CREATE VIEW DDL映射HBase表
phoenix> CREATE TABLE "t1" ( pk VARCHAR PRIMARY KEY, "cf".a VARCHAR, "cf".B VARCHAR, "cf".C VARCHAR );
phoenix> select * from "t1"; 在HBase中使用Shell創建一個測試表,並插入若幹數據 hbase> put ‘t1‘, ‘row1‘, ‘cf:a‘, ‘value1‘
hbase> put ‘t1‘, ‘row1‘, ‘cf:B‘, ‘value2‘
hbase> put ‘t1‘, ‘row1‘, ‘cf:c‘, ‘value3‘
hbase> scan ‘t1‘ 註意:
- 在Phoenix中DDL/DML是忽略大小寫的,而表名和列名是區分大小寫的;
- CREATE VIEW風險較小,但是readonly無法新增修改數據;
- CREATE TABLE風險較大,一旦表結構與HBase原有表不一致,原表將會被新表覆蓋,造成數據丟失;
- 映射表創建後,遺留數據無法查詢,新增修改後的數據才可見
1.1)Mutable Index
CREATE TABLE my_table (k VARCHAR PRIMARY KEY, v1 VARCHAR, v2 BIGINT);為列v1查詢建立索引
CREATE INDEX my_index ON my_table (v1);為列v1,v2查詢建立索引
CREATE INDEX my_index ON my_table (v1) INCLUDE (v2);1.2)Immutable Index 要使用此索引形式,必須在建表時指定IMMUTABLE_ROWS=true,如:
CREATE TABLE my_table (k VARCHAR PRIMARY KEY, v VARCHAR) IMMUTABLE_ROWS=true;
註意:只有當查詢cloumns完全匹配索引時,基於索引的查詢才能生效。例如:
create table usertable (id varchar primary key, firstname varchar, lastname varchar);
create index idx_name on usertable (firstname);
查詢語句:2)Paged Queries SELECT * FROM TEST LIMIT 1000; SELECT title, author, isbn, description FROM library WHERE published_date > 2010 AND (title, author, isbn) > (?, ?, ?) ORDER BY title, author, isbn LIMIT 20
select id, firstname, lastname from usertable where firstname = ‘foo‘;
由於索引只有firstname,而查詢cloumns還包括了lastname,因此上述查詢索引並未生效,可將索引調整如下:
create index idx_name on usertable (firstname) include (lastname);
3)Sequences
創建序列
CREATE SEQUENCE my_sequence;CREATE SEQUENCE my_sequence START WITH -1000;
CREATE SEQUENCE my_sequence INCREMENT BY 10;
CREATE SEQUENCE my_schema.my_sequence START 0 CACHE 10;
插入數據
UPSERT INTO my_schema(MYKEY, MYCOLUMN) VALUES( NEXT VALUE FOR my_schema.my_sequence, ‘foo‘);
刪除序列
DROP SEQUENCE my_sequence;
DROP SEQUENCE IF EXISTS my_schema.my_sequence;
4)Salted Tables
在使用連續的row key時,避免RegionServer出現Hotspotting是HBase使用過程中的通用問題。詳細描述及解決方案參考http://blog.sematext.com/2012/04/09/hbasewd-avoid-regionserver-hotspotting-despite-writing-records-with-sequential-keys/。 其問題大致可描述為:HBase按照row key的字典序的形式存儲記錄,這可以非常快速的通過raw key定位數據,以及數據的startkey和endkey範圍。在很多應用場景中,很多時候采用自增或自減的序列作為HBase的row key,比如001,002,003……或者499,498,…… 在這種情況下,下一個序列必須由當前序列和步長計算得出,那麽如果Region由很多個RegionServer提供服務,這是沒有問題的。但很顯然在HBase的架構中,一個Region只有一個RegionServer提供服務。因此,當一個Region達到它預先設置的一個最大範圍時,將分裂成為兩個較小的Region,並由兩個RegionServer接管,無論怎樣分裂對Region的寫入負載總是落在某一個RegionServer的主機上,若需要全局序列實現自增,顯然就失去了集群負載均衡的作用,下圖是一個負載情況:
找到了問題原因,那麽解決方案就相對容易一下,例如可以salt row keys with a prefix,即為row key做一些添加劑,如增加前綴:
new_row_key = (++index % BUCKETS_NUMBER) + original_key
這裏簡單的根據數據的原始自增或自減的記錄或者ID作為index,對需要分片的bucket去余進行劃分,得到一個新的row key:
那麽HBase集群相對之前的負載將會大有改善,如下圖所示:
Phoenix中以Salted Table的方式支持上述接近方案,可以做如下定義,其中SALT_BUCKETS是1~256的自然數:
CREATE TABLE table (a_key VARCHAR PRIMARY KEY, a_col VARCHAR) SALT_BUCKETS = 20;
5)Configuration and Tuning
Apache Phoenix作為HBase的一個連接驅動,在客戶端做了很多定制優化。因此,應用程序可以對Client端的hbase-site.xml進行參數調優。詳細屬性說明參考:http://phoenix.incubator.apache.org/tuning.html這裏以bin/psql.py客戶端腳本執行調優為例,修改$PHOENIX/phoenix-assembly/target目錄下的phoenix-4.0.0-incubating-client.jar的hbase-default.xml文件,增加如下內容以實現將客戶端默認緩存從100MB調整為1GB:
phoenix.query.maxServerCacheBytes
1024000000
Phoenix on HBase