一、Phoenix簡介 是 HBase 的開源 SQL 中間層,它允許你使用標準 JDBC 的方式來操作 HBase 上的數據。在 之前,如果你要訪問 HBase,只能調用它的 Java API,但相比於使用一行 SQL 就能實現數據查詢,HBase 的 API 還是過於複雜。 的理念是 ,即你可以 ...
一、Phoenix簡介
Phoenix
是 HBase 的開源 SQL 中間層,它允許你使用標準 JDBC 的方式來操作 HBase 上的數據。在 Phoenix
之前,如果你要訪問 HBase,只能調用它的 Java API,但相比於使用一行 SQL 就能實現數據查詢,HBase 的 API 還是過於複雜。Phoenix
的理念是 we put sql SQL back in NOSQL
,即你可以使用標準的 SQL 就能完成對 HBase 上數據的操作。同時這也意味著你可以通過集成 Spring Data JPA
或 Mybatis
等常用的持久層框架來操作 HBase。
其次 Phoenix
的性能表現也非常優異,Phoenix
查詢引擎會將 SQL 查詢轉換為一個或多個 HBase Scan,通過並行執行來生成標準的 JDBC 結果集。它通過直接使用 HBase API 以及協處理器和自定義過濾器,可以為小型數據查詢提供毫秒級的性能,為千萬行數據的查詢提供秒級的性能。同時 Phoenix 還擁有二級索引等 HBase 不具備的特性,因為以上的優點,所以 Phoenix
成為了 HBase 最優秀的 SQL 中間層。

二、Phoenix安裝
我們可以按照官方安裝說明進行安裝,官方說明如下:
- download and expand our installation tar
- copy the phoenix server jar that is compatible with your HBase installation into the lib directory of every region server
- restart the region servers
- add the phoenix client jar to the classpath of your HBase client
- download and setup SQuirrel as your SQL client so you can issue adhoc SQL against your HBase cluster
2.1 下載並解壓
官方針對 Apache 版本和 CDH 版本的 HBase 均提供了安裝包,按需下載即可。官方下載地址: http://phoenix.apache.org/download.html
# 下載
wget http://mirror.bit.edu.cn/apache/phoenix/apache-phoenix-4.14.0-cdh5.14.2/bin/apache-phoenix-4.14.0-cdh5.14.2-bin.tar.gz
# 解壓
tar tar apache-phoenix-4.14.0-cdh5.14.2-bin.tar.gz
2.2 拷貝Jar包
按照官方文檔的說明,需要將 phoenix server jar
添加到所有 Region Servers
的安裝目錄的 lib
目錄下。
這裡由於我搭建的是 HBase 偽集群,所以只需要拷貝到當前機器的 HBase 的 lib 目錄下。如果是真實集群,則使用 scp 命令分發到所有 Region Servers
機器上。
cp /usr/app/apache-phoenix-4.14.0-cdh5.14.2-bin/phoenix-4.14.0-cdh5.14.2-server.jar /usr/app/hbase-1.2.0-cdh5.15.2/lib
2.3 重啟 Region Servers
# 停止Hbase
stop-hbase.sh
# 啟動Hbase
start-hbase.sh
2.4 啟動Phoenix
在 Phoenix 解壓目錄下的 bin
目錄下執行如下命令,需要指定 Zookeeper 的地址:
- 如果 HBase 採用 Standalone 模式或者偽集群模式搭建,則預設採用內置的 Zookeeper 服務,埠為 2181;
- 如果是 HBase 是集群模式並採用外置的 Zookeeper 集群,則按照自己的實際情況進行指定。
# ./sqlline.py hadoop001:2181
2.5 啟動結果
啟動後則進入了 Phoenix 互動式 SQL 命令行,可以使用 !table
或 !tables
查看當前所有表的信息

三、Phoenix 簡單使用
3.1 創建表
CREATE TABLE IF NOT EXISTS us_population (
state CHAR(2) NOT NULL,
city VARCHAR NOT NULL,
population BIGINT
CONSTRAINT my_pk PRIMARY KEY (state, city));

新建的表會按照特定的規則轉換為 HBase 上的表,關於表的信息,可以通過 Hbase Web UI 進行查看:

3.2 插入數據
Phoenix 中插入數據採用的是 UPSERT
而不是 INSERT
,因為 Phoenix 並沒有更新操作,插入相同主鍵的數據就視為更新,所以 UPSERT
就相當於 UPDATE
+INSERT
UPSERT INTO us_population VALUES('NY','New York',8143197);
UPSERT INTO us_population VALUES('CA','Los Angeles',3844829);
UPSERT INTO us_population VALUES('IL','Chicago',2842518);
UPSERT INTO us_population VALUES('TX','Houston',2016582);
UPSERT INTO us_population VALUES('PA','Philadelphia',1463281);
UPSERT INTO us_population VALUES('AZ','Phoenix',1461575);
UPSERT INTO us_population VALUES('TX','San Antonio',1256509);
UPSERT INTO us_population VALUES('CA','San Diego',1255540);
UPSERT INTO us_population VALUES('TX','Dallas',1213825);
UPSERT INTO us_population VALUES('CA','San Jose',912332);
3.3 修改數據
-- 插入主鍵相同的數據就視為更新
UPSERT INTO us_population VALUES('NY','New York',999999);

3.4 刪除數據
DELETE FROM us_population WHERE city='Dallas';

3.5 查詢數據
SELECT state as "州",count(city) as "市",sum(population) as "熱度"
FROM us_population
GROUP BY state
ORDER BY sum(population) DESC;

3.6 退出命令
!quit
3.7 擴展
從上面的操作中可以看出,Phoenix 支持大多數標準的 SQL 語法。關於 Phoenix 支持的語法、數據類型、函數、序列等詳細信息,因為涉及內容很多,可以參考其官方文檔,官方文檔上有詳細的說明:
語法 (Grammar) :https://phoenix.apache.org/language/index.html
函數 (Functions) :http://phoenix.apache.org/language/functions.html
數據類型 (Datatypes) :http://phoenix.apache.org/language/datatypes.html
序列 (Sequences) :http://phoenix.apache.org/sequences.html
聯結查詢 (Joins) :http://phoenix.apache.org/joins.html
四、Phoenix Java API
因為 Phoenix 遵循 JDBC 規範,並提供了對應的資料庫驅動 PhoenixDriver
,這使得採用 Java 語言對其進行操作的時候,就如同對其他關係型資料庫一樣,下麵給出基本的使用示例。
4.1 引入Phoenix core JAR包
如果是 maven 項目,直接在 maven 中央倉庫找到對應的版本,導入依賴即可:
<!-- https://mvnrepository.com/artifact/org.apache.phoenix/phoenix-core -->
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
<version>4.14.0-cdh5.14.2</version>
</dependency>
如果是普通項目,則可以從 Phoenix 解壓目錄下找到對應的 JAR 包,然後手動引入:

4.2 簡單的Java API實例
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class PhoenixJavaApi {
public static void main(String[] args) throws Exception {
// 載入資料庫驅動
Class.forName("org.apache.phoenix.jdbc.PhoenixDriver");
/*
* 指定資料庫地址,格式為 jdbc:phoenix:Zookeeper 地址
* 如果 HBase 採用 Standalone 模式或者偽集群模式搭建,則 HBase 預設使用內置的 Zookeeper,預設埠為 2181
*/
Connection connection = DriverManager.getConnection("jdbc:phoenix:192.168.200.226:2181");
PreparedStatement statement = connection.prepareStatement("SELECT * FROM us_population");
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getString("city") + " "
+ resultSet.getInt("population"));
}
statement.close();
connection.close();
}
}
結果如下:

實際的開發中我們通常都是採用第三方框架來操作資料庫,如 mybatis
,Hibernate
,Spring Data
等。關於 Phoenix 與這些框架的整合步驟參見下一篇文章:Spring/Spring Boot + Mybatis + Phoenix
參考資料
更多大數據系列文章可以參見 GitHub 開源項目: 大數據入門指南