joananjin 2017-12-13
Apache Phoenix是一个HBase的开源SQL引擎。你可以使用标准的JDBCAPI代替HBase客户端API来创建表,插入数据,查询你的HBase数据。
为了你更好更快地了解Apache Phoenix,官方给出了15分钟快速了解Apache Phoenix的文档说明:http://phoenix.apache.org/Phoenix-in-15-minutes-or-less.html
1. 不要在我的程序和HBase之间增加额外的层,它只会拖慢速度的?
事实上,不会。Phoenix通过以下方式实现了比你自己手写的方式相同或者可能是更好的性能(更不用说可以少写了很多代码):
* 编译你的SQL查询为原生HBase的scan语句
* 检测scan语句最佳的开始和结束的key
* 精心编排你的scan语句让他们并行执行
* 移动计算到数据的地方 ,而不是移动数据
* 推送你的WHERE子句的谓词到服务端过滤器处理
* 执行聚合查询通过服务端钩子(称为协同处理器)
除此之外,我们还做了一些有趣的增强功能来更多地优化性能:
* 实现了二级索引来提升非主键字段查询的性能
* 统计相关数据来提高并行化水平,并帮助选择最佳优化方案
* 跳过扫描过滤器来优化IN,LIKE,OR查询
* 可选的散布行键来均匀分布写压力
2. 好吧,它很快。但是为什么要用SQL?这已经是70年代的东西了。
一种观点是:给大伙儿一些他们已经熟悉的东西吧。什么是更好的方式去激励他们使用HBase呢?最好的方式就是使用JDBC和SQL,原因有以下几点:
* 降低用户需要写的代码数量
* 让性能优化对用户透明
* 方便利用和整合大量的已经存在的工具
3. 但是怎样才能让SQL支持我最喜爱的HBase的某些技术
不要把这(使用Phoenix后)当作是你见HBase的最后一次好吧?SQL只是一种表达你想实现的功能的方式,你不必去思考怎样用SQL去实现功能。针对目前已经存在或者正在做的Phoenix功能,看看能否支持你喜欢的HBase的特殊用法。你有自己的想法?我们很乐意听到你的想法:把问题写下来给我们同时也可以加入我们的邮件列表。
说了这么多,我只是想知道如何开始?
非常棒!只要跟随我们的安装指南(我的HBase集群环境的版本号为:hbase-1.1.5):
* 下载并解压我们的安装包 (apache-phoenix-4.8.0-HBase-1.1-bin.tar.gz)
tar -zxvf apache-phoenix-4.8.0-HBase-1.1-bin.tar.gz
* 拷贝能够与你的HBase安装兼容的phoenix的服务端jar包到每个集群节点的lib目录
cp phoenix-4.8.0-HBase-1.1-server.jar /var/lib/kylin/hbase-1.1.5/lib/
再拷贝到集群的每个HBase节点的lib目录下面:
scp phoenix-4.8.0-HBase-1.1-server.jar kylin@SZB-L0023776:/var/lib/kylin/hbase/lib
scp phoenix-4.8.0-HBase-1.1-server.jar kylin@SZB-L0023777:/var/lib/kylin/hbase/lib
scp phoenix-4.8.0-HBase-1.1-server.jar kylin@SZB-L0023778:/var/lib/kylin/hbase/lib
scp phoenix-4.8.0-HBase-1.1-server.jar kylin@SZB-L0023779:/var/lib/kylin/hbase/lib
* 重启你的集群节点
stop-hbase.sh
start-hbase.sh
* 添加phoenix的客户端jar包到你的HBase客户端的classpath下
* 下载并设置SQuirrel作为你的SQL客户端,这样你就可以发起即时查询的SQL语句来操作你的HBase集群
4. 我不想要下载安装其他东西了!
好吧,有道理。你可以创建你自己的SQL脚本并使用我们的命令行工具来执行他们(来代替前面说的下载安装软件的方案)。现在让我们来看一个例子。
定位到你安装Phoenix路径的bin目录来开始。
4.1 首先,让我们来创建一个 us_population.sql文件,包含如下建表的语句
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)
);
4.2 再创建一个us_population.csv文件,包含表的数据
NY,New York,8143197
CA,Los Angeles,3844829
IL,Chicago,2842518
TX,Houston,2016582
PA,Philadelphia,1463281
AZ,Phoenix,1461575
TX,San Antonio,1256509
CA,San Diego,1255540
TX,Dallas,1213825
CA,San Jose,912332
4.3 最后我们创建一个us_population_queries.sql文件,包含一个查询SQL
SELECT state as"State", count(city) as "City Count",sum(population) as "Population Sum"
FROM us_population
GROUP BY state
ORDER BY sum(population) DESC;
4.4 通过命令行执行具体的操作
注:我这里指定了HBase在Zookeeper上的完整连接,包括IP地址,端口号以及znodeparent,如果不指定znode parent的话,默认为/hbase节点。
[kylin@SZB-L0023780bin]$ ./psql.py SZB-L0023780:2181:/hbase114 us_population.sql us_population.csv us_population_queries.sql
no row supserted
Time: 2.845sec(s)
csv columns from database.
CSV Upsert complete. 10 rows upserted
Time: 0.129sec(s)
St City Count Population Sum
-- -------------- ------------------------- -------------------------
NY 1 8143197
CA 3 6012701
TX 3 4486916
IL 1 2842518
PA 1 1463281
AZ 1 1461575
Time: 0.077sec(s)
可以看到你已经创建了你的第一个Phoenix表了,插入数据进去,并且执行了一个只有几行数据的聚合查询SQL代码。
4.5 性能测试脚本performance.py
[kylin@SZB-L0023780 bin]$ ./performance.py
Performance script arguments notspecified. Usage: performance.sh <zookeeper> <row count>
Example: performance.sh localhost100000
我们测试1千万条数据,查看性能如下:
执行的过程中,会创建一张表名为 PERFORMANCE_10000000的HBase表,并插入1千万条记录,然后执行一些查询操作。
[kylin@SZB-L0023780 bin]$ ./performance.py SZB-L0023780:2181:/hbase114 10000000
Phoenix Performance Evaluation Script 1.0
-----------------------------------------
Creating performance table...
no rows upserted
Time: 2.343 sec(s)
Query # 1 - Count - SELECT COUNT(1) FROM PERFORMANCE_10000000;
Query # 2 - Group By First PK - SELECT HOST FROM PERFORMANCE_10000000 GROUP BY HOST;
Query # 3 - Group By Second PK - SELECT DOMAIN FROM PERFORMANCE_10000000 GROUP BY DOMAIN;
Query # 4 - Truncate + Group By - SELECT TRUNC(DATE,'DAY') DAY FROM PERFORMANCE_10000000 GROUP BY TRUNC(DATE,'DAY');
Query # 5 - Filter + Count - SELECT COUNT(1) FROM PERFORMANCE_10000000 WHERE CORE<10;
Generating and upserting data...
csv columns from database.
CSV Upsert complete. 10000000 rows upserted
Time: 565.593 sec(s)
COUNT(1)
----------------------------------------
10000000
Time: 8.206 sec(s)
HO
--
CS
EU
NA
Time: 0.416 sec(s)
DOMAIN
----------------------------------------
Apple.com
Google.com
Salesforce.com
Time: 13.134 sec(s)
DAY
-----------------------
2016-08-30 00:00:00.000
2016-08-31 00:00:00.000
2016-09-01 00:00:00.000
2016-09-02 00:00:00.000
2016-09-03 00:00:00.000
2016-09-04 00:00:00.000
……
2016-12-18 00:00:00.000
2016-12-19 00:00:00.000
2016-12-20 00:00:00.000
2016-12-21 00:00:00.000
2016-12-22 00:00:00.000
2016-12-23 00:00:00.000
2016-12-24 00:00:00.000
Time: 12.852 sec(s)
COUNT(1)
----------------------------------------
200745
Time: 11.01 sec(s)
如果你想统计HBase的表总共有多少行记录,不要使用HBase的count命令统计,单线程,性能太差;而是使用MapReduce去计算,如下:
hbase org.apache.Hadoop.hbase.mapreduce.RowCounter 'PERFORMANCE_10000000'