1 使用概述
Phoenix是基於HBase的SQL中介軟體產品,由Salesforce.com公司開源並託管於Github上。對於熟悉關係型資料庫的開發人員來說,通過Phoenix可以像使用MySQL等關係型資料庫一樣使用HBase中的資料表。值得注意的是,它還提供了JDBC驅動包供Java程式訪問資料。在實現時,充分利用了HBase副處理器和過濾器等底層 2 環境配置
首先需要安裝好HBase叢集,且採用的版本在0.94.4以上,JDK版本1.6以上。本文採用的phoenix版本為phoenix-2.0.1(http://phoenix-bin.github.com/client/phoenix-2.0.1-install.tar),所以如果有相關差異或更改,請以官方公布文檔為準。
安裝phoenix非常簡單,從下載的tar包中取出phoenix-2.0.1.jar,將其放入HBase叢集中所有RS節點安裝目錄lib中,同時記得移除之前安裝的phoenix老版本,如果安裝過的話。然後重啟所有RS節點服務。如果採用Java代碼訪問,請採用與之匹配的client版本,比如本文的phoenix-2.0.1-client.jar。
為便於測試,可將下載的包內容放置到HBase叢集某個節點機器上,比如本文將其放置到HMaster機器vnode120的$HBASE_HOME phoenix中,為檢驗phoenix是否安裝成功,請進入$HBASE_HOME/phoenix/bin目錄,並賦予所有*.sh可執行許可權,操作如下:
sqlline.sh為其提供的命令列工具,可以在其中執行建表,查詢等相關動作。運行該指令碼需要跟zk參數,vnode121為某個zk節點。連上後,執行!tables會列出所有通過phoenix建的表,其中SYSTEM.TABLE這張表預設會存在,其中存放phoenix實現中的資料類型映射等資訊。當能執行這些操作後,說明phoenix功能已經正常整合進現有HBase叢集中,您接下來就可以體驗HBase之上執行SQL功能的奇妙之旅了。
3 SQL特性詳解
1)create:可以建立一張表或視圖。表名如果沒有用雙引號括起來,預設都會使用其對應的大寫字母名字表示,括起來後跟括起來的值保持一致。如果建立的表已經存在,且其不是通過phoenix create文法建立的,則可以繼續使用phoenix create建立同名表,不影響原有表資料,但會影響通過phoenix select結果值存在部分不需要的值。建立視圖時,需要對應的表和列族已存在,不能對錶中資料進行更新操作。建表語句中,還可以附加一些HBase表、列族配置選項,如VERSIONS、MAX_FILESIZE etc.
CREATETABLE IF NOT EXISTS my_table ( id char(10) not null primary key, value integer);
CREATETABLE IF NOT EXISTS my_schema.my_table ( id char(10) not null primary key,value integer) DATA_BLOCK_ENCODING='NONE',VERSIONS=10,MAX_FILESIZE=20480;
2)alter:可添加或刪除一列或更新表屬性。被移除的列,其上資料會被刪除。如果該列是主鍵,不能被移除,如果移除列的是一個視圖,資料是不會受影響的。
ALTERTABLE my_table ADD dept_name varchar(50)
ALTERTABLE my_table DROP COLUMN parent_id
ALTERTABLE my_table SET IMMUTABLE_ROWS=true
3)drop:刪除表或視圖。如果刪除表,表中資料也會被刪除,如果是視圖則不受影響。
DROPTABLE my_schema.my_table
DROP VIEW my_view
4)upsert:更新或插入資料。如果表中不存在該資料則插入,否則更新,所以可以看出phoenix沒有單獨定義insert 或update命令。列列表可以省略,但後面插入的值順序需要與表schema定義順序保持一致,也可自己定義插入哪些column對應值,順序與之對應即可。目前還支援一種選擇性upsert的方式,它將另外一個查詢的結果作為值插入表中。如果auto commit開啟的話,會在服務端就提交了,否則會緩衝到用戶端,等著顯式提交的時候進行批量upsert,通過配置” phoenix.mutate.upsertBatchSize”指定大小,預設10000行/次。
UPSERTINTO TEST VALUES('foo','bar',3);
UPSERTINTO TEST(NAME,ID) VALUES('foo',123)
5)delete:刪除指定行。如果auto commit開啟,則會直接在服務端執行刪除。
DELETE FROM TEST;
DELETE FROM TEST WHERE ID=123;
6)index:二級索引。在表或視圖上建立二級索引,目前的版本僅支援對具有IMMUTABLE_ROWS屬性的表上添加二級索引。目前實現是在資料行插入後便插入了索引。當建立了索引後,其實也會在HBase中建立一張表,表名為該二級索引名,所以還可對該index指定建立表相關參數。同時還可刪除索引和修改索引。
CREATEINDEX my_idx ON sales.opportunity(last_updated_date DESC)
DROPINDEX my_idx ON sales.opportunity
ALTERINDEX my_idx ON sales.opportunity DISABLE
7)explain:執行計畫。提供一個很簡單的方式查看執行給定命令所需的邏輯步驟。每個步驟局勢以單行字串進行輸出表示。這個可以很容易定位查詢的效能瓶頸,或者所建二級索引是否生效等。
explain select * from test where age>0;
8)其他
constraint定義主鍵約束,預設按照列升序排列:
CONSTRAINTmy_pk PRIMARY KEY (host,created_date)
選項,如之前用到的IMMUTABLE_ROWS=true,預設設定了這個選項的表才允許建索引。Phoenix預設是修改HBase中繼資料來使之生效,適用於HColumnDescriptor和HTableDescriptor相關選項。值得一提的是SALT_BUCKETS選項,它為每個rowkey預置一個位元組,使其分布在不同rs上來避免寫熱點rs。
IMMUTABLE_ROWS=true
SALT_BUCKETS=10
hint,可重設預設的查詢行為。一般用於sql調優。目前支援SKIP_SCAN,RANGE_SCAN,NO_INTRA_REGION_PARALLELIZATION,NO_INDEX,INDEX5個hint。
select /*+NO_INDEX */* from test where age>0
建表,建索引或alter等操作的時候,名稱都可以用.分隔,如果是表,則前部分為schema名(預設null),如果是column,則前部分是family名(預設’_0’)。不用雙引號括起來的時候為大小寫不敏感的。
選擇運算式可以用*和<familyName>.*來表示所有列都選擇出來,或指定列族下所有列都選擇出來,注意的時候familyName是大小寫敏感的,列名是大小寫不敏感的。
為表定義分割點,可以使用preparedStatement.setBinary(int,byte[])提供任意位元組的分割。
目前不支援join和子查詢,可以為表和列定義別名,方法是使用as或直接將別名跟在真名後面。
目前查詢支援排序,比如按照某列升序,降序等。ORDER BY NAME ASC NULLSLAST。
支援的關係串連符有AND和OR。如果使用LIKE,可以用萬用字元_(單個字元)和%(任一字元)。若查詢的字串本身就包括則需要對其轉義(\)。Between是個閉區間[5,10]
比較子有<>,<=,>=,=,<,>,!=其中<>與!=等效。字串串連可以用||,數字和日期類型可以做+,-,*,/。
4 內建函數
支援的彙總函式有:
Ø AVG:求平均,如果沒有返回NULL
Ø SUM:
Ø COUNT:求行數,如果指定某列,則返回該列非空個數,如果為*或1,則返回所有行,加上distinct則返回不相同的行數
Ø MAX:求最大值
Ø MIN:求最小值
Ø PERCENTILE_CONT:指定。。
Ø PERCENTILE_DISC:指定佔比的列具體值是多少
Ø PERCENT_RANK:指定值占的百分比,PERCENT_RANK( 39 ) WITHINGROUP (ORDER BY id ASC)
Ø STDDEV_SAMP:樣本標準差
Ø STDDEV_POP:總體標準差
支援的字串函數:
Ø SUBSTR:取子串,預設是基於1的,如果想基於0,則指定0,如果指定為負數,則是從字串結尾算起
Ø TRIM:去除字串頭尾空格
Ø LTRIM:去除字串左側空格
Ø RTRIM:去除字串右側空格
Ø LENGTH:返回字串長度
Ø REGEXP_SUBSTR:通過指定Regex擷取子串
Ø REGEXP_REPLACE:正則替換
Ø UPPER:大寫轉換
Ø LOWER:小寫轉換
Ø REVERSE:字串反轉
Ø TO_CHAR:將日期、時間、時間戳記或數字格式化為一個字串。預設日期格式為yyyy-MM-dd HH:mm:ss,數字格式為#,##0.###。
支援的時間、日期函數:
Ø ROUND:四捨五入。
Ø TRUNC:截斷
Ø TO_DATE:轉換為date類型
Ø CURRENT_DATE:返回RS上當前日期
Ø CURRENT_TIME:返回RS上目前時間
支援的時間、日期函數:
Ø TO_NUMBER:轉換日期、時間、時間戳記為一個數字,可接受格式化串。
Ø COALESCE:指定預設值,如果相應值為null
5 資料類型
Ø INTEGER:範圍為-2147483648 到 2147483647,與java.lang.Integer映射。但注意的是其二進位表示需要其會把第一個符號位進行翻轉,這樣保證負數排列在正數前面。
Ø UNSIGNED_INT:範圍為0到2147483647,這個是與java.lang.Integer對應,其二進位呈現形式和Bytes.toBytes(int)方法產生的一致。
Ø BIGINT:範圍為-9223372036854775808 到9223372036854775807 ,與java.lang.Long對應。8個位元組,同時也是符號位反轉。
Ø UNSIGNED_LONG:可能值為0到9223372036854775807 ,與Bytes.toBytes(long)對應。
Ø TINYINT:-128到127。與java.lang.Byte對應。符號位也需要反轉。
Ø UNSIGNED_TINYINT:0到127。二進位表示形式就是一個單位元組,和Bytes.toBytes(byte)對應。
Ø SMALLINT:-32768到32767。與java.lang.Short對應。符號位需要反轉。
Ø UNSIGNED_SMALLINT:0到32767。二進位表示形式與Bytes.toBytes(short)對應。
Ø FLOAT: -3.402823466 E + 38 到 3.402823466 E + 38,與java.lang.Float對應,首位元組需要反轉。
Ø UNSIGNED_FLOAT: 0 到 3.402823466 E + 38,二進位表示形式與Bytes.toBytes(float)一致。
Ø DOUBLE:範圍為-1.7976931348623158 E + 308 到 1.7976931348623158 E + 308。與java.lang.Double對應,二進位形式首位需反轉。
Ø UNSIGNED_DOUBLE: 0到1.7976931348623158 E + 308。二進位表示形式與Bytes.toBytes(double)對應。
Ø DECIMAL:具有固定精度。最大精度為18位,與java.math.BigDecimal對應。其二進位表示形式為可變長度格式。當用於rowkey中,其後會產生一個nullbyte,除非它是最後一列。
Ø BOOLEAN:二進位形式0表示false,1表示true
Ø TIME:格式為yyyy-MM-DD hh:mm:ss,具有日期和時間兩部分。與java.sql.Time對應。二進位表示形式為8個位元組的long型,代表從EPOCH開始的毫秒數
Ø DATE: 格式為yyyy-MM-DD hh:mm:ss,具有日期和時間兩部分。與java.sql.DATE對應。二進位表示形式為8個位元組的long型,代表從EPOCH開始的毫秒數。
Ø TIMESTAMP:格式為yyyy-MM-dd hh:mm:ss[.nnnnnnnnn],與java.sql.Timestamp,二進位表示為12個位元組,8個位元組表示long毫秒數,4個位元組表示int納秒數
Ø VARCHAR:具有最大位元組長度(可選)的可變長字串。當用於rowkey時,會在末尾加一個null位元組,而如果它正好位於rowkey最後部分則不加。
Ø CHAR:固定長度字串。二進位表示是UTF8形式與Bytes.toBytes(string)對應。
Ø BINARY:原始固定長度二進位位元組數組,與byte[]對應
Ø VARBINARY:原始可變長度二進位格式位元組數組。
6 參考網頁
HBase 官方:https://hbase.apache.org/
Phoenix 官方:https://github.com/forcedotcom/phoenix