1.概述
在《Hadoop-Drill深度剖析》一文當中,給大家介紹了Drill的相關內容,就實時查詢來說,Drill基本能夠滿足要求,同時還可以做一個簡單業務上的聚合,如果在使用Hive做一些簡單的業務統計(不涉及多維度,比如CUBE,ROLLUP之類的函數),只是用一些基本的聚合函數或是JOIN ON之類的,Drill基本滿足要求,而且響應速度可比OLTP。今天給大家剖析的是另外一種工具,由於目前Drill官方不支持對表的插入,更新操作。所以,在操作HBase的時候,若遇到這些需求,Drill就有點力不從心。那么,Phoenix可以滿足以上需求。它更接近與標准的SQL。
2.Architecture
在Phoenix中SQL Query Plan的執行,基本上是通過構建一系列的HBase Scan來完成。為了盡可能減少數據的傳輸,在Region Server使用Coprocessor來盡可能的執行Aggregate相關的工作,基本實現的思路是使用RegionObserver在PostScannerOpen Hook中將RegionScanner替換成支持Aggregation工作的定制化的Scanner,具體的Aggregate操作通過Custom的Scan屬性傳遞給RegionScanner。然與基於MapReduce的框架執行Plan的思想比較,基本上就是通過Coprocessor,使用RegionServer自身來在各個節點上執行Aggregation。另外,通過各種定制的Filter在HBase的RegionScanner Scan過程中,盡早的將不相關的數據過濾掉。采用JDBC接口和應用程序交互。
3.Grammar
本篇博客所對應的軟件版本號,如下所示:
- HBase:0.98
- Phoenix:4.6-HBase-0.98
這里需要注意的是,Phoenix的版本是和HBase版本相匹配的,可以在Phoenix的官網選擇對應的HBase版本。就本篇博客截止,官方所支持的語法如下圖所示:

3.How to use
如何將Phoenix嵌入到現有業務當中,其實,Phoenix只是一個中間件(或是一個HBase的SQL插件),它的使用較為簡單,首先,我們准備好對應的安裝包,下載地址如下所示:
- [Phoenix-HBase-0.98][下載地址]
然后,將Phoenix目錄下的phoenix-*.jar拷貝到HBase的lib目錄,這里面是將所有的插件均拷貝到HBase了,若是只使用個別插件,大家可按需選擇即可。然后重啟HBase集群即可。
3.1 Shell Client
這里,我們可以驗證Phoenix是否可用,可以通過終端來驗證,在Phoenix的bin目錄當中有一個sqlline.py腳本,可以通過該腳本來操作HBase中的表,命令如下所示:
./sqlline.py zk01,zk02,zk03:2181
通過英文感嘆號可以獲取幫助命令,如下圖所示:

然后,我們可以做一些測試來,驗證起可用性。如下圖所示:

腳本如下所示:
create table test3 (mykey integer not null primary key, mycolumn varchar); upsert into test3 values (1,'Hello'); upsert into test3 values (2,'World2'); upsert into test3 values (3,'World3'); upsert into test3 values (4,'World4'); upsert into test3 values (5,'World5'); select * from test3;
3.2 JDBC
另外,Phoenix也支持JDBC去訪問,這里筆者給大家寫了一個示例代碼,如下所示:
package cn.smrtloli.phoenix.demo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* @Date Dec 14, 2015
*
* @Author dengjie
*
* @Note TODO
*/
public class PhoenixDemo {
private static String driver = "org.apache.phoenix.jdbc.PhoenixDriver";
public static void main(String[] args) throws SQLException {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Statement stmt = null;
ResultSet rset = null;
Connection con = DriverManager.getConnection("jdbc:phoenix:zk01,zk02,zk03:2181");
stmt = con.createStatement();
String sql = "select * from test3";
rset = stmt.executeQuery(sql);
while (rset.next()) {
System.out.println(rset.getString("mycolumn"));
}
stmt.close();
con.close();
}
}
另外,在pom.xml中添加如下依賴JAR文件,內容如下所示:
<dependency> <groupId>org.apache.phoenix</groupId> <artifactId>phoenix-core</artifactId> <version>4.6.0-HBase-0.98</version> </dependency>
運行結果,如下所示:

4.總結
就使用的結果來看,雖然滿足了一些CRUD的操作,然其在HBase的基礎上完成,過於依賴HBase,對其他存儲介質的支持有限。總體來說,對於HBase中已有數據,做標准的SQL操作來說,是足夠了。另外,時延要求較高的業務,還是用HBase的API來完成,Phoenix雖說速度、性能較快,畢竟不能嚴格意義上達到OLTP。
5.結束語
這篇博客就和大家分享到這里,如果大家在研究學習的過程當中有什么問題,可以加群進行討論或發送郵件給我,我會盡我所能為您解答,與君共勉!
