本文作者:林伟兵,叩丁狼高级讲师。原创文章,转载请注明出处。
1.Phoenix概述
Phoenix是一个开源的HBASE SQL层API。Phoeinx可以用标准的JDBC API替代HBASE client API来创建表,插入和查询查询HBASE中的数据。Phoenix作为应用层和HBASE之间的中间件,以下特性使它在大数据量的简单查询场景有着独有的优势:
- 支持二级索引.
- 编译SQL成为原生HBase的可并行执行的查询,并下推where过滤条件到server端的scan filter上
- 在数据层完成计算,server端的coprocessor执行聚合
- 利用统计信息优化、选择查询计划
- skip scan功能提高扫描速度
2.Phoenix&DBeaver安装
安装步骤如下:
- 不同版本的Phoenix对应不同的HBase版本,找到对应的版本下载并解压。下载地址如下:http://phoenix.apache.org/download.html
- 将 phoenix-[version]-server.jar 添加到HBase的各个节点的lib文件夹下。
- 重启 HBase.
- 配置Phoenix环境变量。
## PHOENIX PATH
export PHOENIX_HOME=/usr/local/phoenix
export PATH=$PATH:$PHOENIX_HOME/bin
3.Phoenix客户端实践
一般可以使用以下三种方式访问Phoenix:
- 使用Python编写的命令行工具(sqlline, sqlline-thin和psql等)
- JDBC API
- SQuirrel / DBeaver
3.1.命令行工具psql使用示例
psql.py主要是用来实现批量加载CSV数据的一个工具,其存放在bin目录下。用法如下:
1.创建一个建表的sql脚本文件 employee.sql:
CREATE TABLE IF NOT EXISTS t_employee (
name VARCHAR PRIMARY KEY,
age UNSIGNED_INT,
gender CHAR(1),
salary UNSIGNED_DOUBLE );
2.创建csv格式的数据文件t_employee.csv 【注意这里的文件后缀必须是csv】:
zhangsan,30,M,5600.50
lisi,35,M,4800.50
wangwu,33,M,9700.00
zhaoliu,54,M,12000.00
赵义,42,M,9200.00
郭芬芳,35,F,4200.00
3.创建一个查询sql脚本文件t_employee_queries.sql:
SELECT name as "员工姓名",gender as "性别",salary as "工资"
FROM t_employee
ORDER BY salary DESC;
4.执行psql.py工具运行sql脚本:
bin/psql.py hdp01 employee.sql t_employee.csv t_employee_queries.sql
执行结果如下:
员工姓名 性 工资
---------------------------------------- - ----------------------------------------
zhaoliu M 12000.0
wangwu M 9700.0
赵义 M 9200.0
zhangsan M 5600.5
lisi M 4800.5
郭芬芳 F 4200.0
5.通过hbase客户端查询结果如下:
hbase(main):002:0> scan "T_EMPLOYEE"
ROW COLUMN+CELL
lisi column=0:\x00\x00\x00\x00, timestamp=1546412866119, value=
x
zhangsan column=0:\x80\x0C, timestamp=1546412866119, value=M
zhangsan column=0:\x80\x0D, timestamp=1546412866119, value=@\xB5\xE
0\x80\x00\x00\x00\x00
zhaoliu column=0:\x00\x00\x00\x00, timestamp=1546412866119, value=
x
\xE8\xB5\xB5\xE4\xB9 column=0:\x80\x0B, timestamp=1546412866119, value=\x00\x00
\x89 \x00*
\xE8\xB5\xB5\xE4\xB9 column=0:\x80\x0C, timestamp=1546412866119, value=M
\x89
...(省略打印结果)
6.HBase查看表结构,通过查看发现系统创建了一个列族0,并且系统默认创建了一些协处理器。如下:
hbase(main):057:0> describe 'T_EMPLOYEE'
Table T_EMPLOYEE is ENABLED
T_EMPLOYEE, {TABLE_ATTRIBUTES => {coprocessor$1 => '|org.apache.phoenix.coproces
sor.ScanRegionObserver|805306366|', coprocessor$2 => '|org.apache.phoenix.coproc
essor.UngroupedAggregateRegionObserver|805306366|', coprocessor$3 => '|org.apach
e.phoenix.coprocessor.GroupedAggregateRegionObserver|805306366|', coprocessor$4
=> '|org.apache.phoenix.coprocessor.ServerCachingEndpointImpl|805306366|', copro
cessor$5 => '|org.apache.phoenix.hbase.index.Indexer|805306366|org.apache.hadoop
.hbase.index.codec.class=org.apache.phoenix.index.PhoenixIndexCodec,index.builde
r=org.apache.phoenix.index.PhoenixIndexBuilder'}
COLUMN FAMILIES DESCRIPTION
{NAME => '0', BLOOMFILTER => 'NONE', VERSIONS => '1', IN_MEMORY => 'false', KEEP
_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'FAST_DIFF', TTL => 'FOREVER',
COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE =>
'65536', REPLICATION_SCOPE => '0'}
在PSQL批量导入数据时,为了满足更多的需求,可以使用如下参数:
参数 | 描述 |
---|---|
-t | 提供了需要加载数据的表名,默认情况下加载数据的表名由CSV文件名来决定。 |
-h | 指定CSV数据映射到HBase的列名。默认情况下CSV数据会按照顺序映射到表的每个字段中。 |
-d | 指定CSV数据的列分隔符。 |
-a | 指定数据组的分隔符。 |
3.2.psql删除表的操作
Phoenix工具创建的表最好也使用Phoenix工具删除,否则会出现遗留的数据问题,操作遗留数据会会导致系统出现异常。如下介绍如何删除表:
- 创建删除表的sql文件 drop_employee.sql:
DROP TABLE IF EXISTS t_employee;
2.执行psql.py工具运行sql脚本:
bin/psql.py hdp01,hdp02,hdp03:2181 drop_employee.sql
3.3.看懂Phoenix数据类型
Phoenix支持6种数据类型,大致如下:
整数型 | 浮点数 | 时间类型 | 字符串 |
---|---|---|---|
INTEGER / UNSIGNED_INT | FLOAT / UNSIGNED_FLOAT | TIME / UNSIGNED_TIME | VARCHAR |
BIGINT / UNSIGNED_LONG | DOUBLE / UNSIGNED_DOUBLE | DATE / UNSIGNED_DATE | CHAR(10) |
TINYINT / UNSIGNED_TINYINT | DECIMAL / DECIMAL(10,2) | TIMESTAMP /UNSIGNED_TIMESTAMP | BINARY / VARBINARY |
SMALLINT / UNSIGNED_SMALLINT |
布尔值 | 数组 |
---|---|
BOOLEAN | VARCHAR ARRAY |
— | INTEGER [] / INTEGER [100] |
对于数字类型的数据,既支持正负级别的限制,也支持对正数的限制[前缀UNSIGNED] 数据类型的使用方式如下:http://phoenix.apache.org/language/datatypes.html#char_type
对于数组的应用,使用文档:http://phoenix.apache.org/array_type.html
- 创建建表文件 create_tscore.sql:
CREATE TABLE IF NOT EXISTS t_score(
student VARCHAR PRIMARY KEY,
scores VARCHAR ARRAY[3] );
- 导入CSV文件 score.csv:
zhangsan,75-75-89
lisi,85-79-92
wangwu,90-70-91
zhaoliu,95-100-95
- 查询表数据文件 score_querries.sql
SELECT student,scores[1] as "math" FROM t_score;
- 执行psql.py工具运行sql脚本:
bin/psql.py hdp01,hdp02,hdp03:2181 -t T_SCORE -a - create_tscore.sql score.csv score_querries.sql
注意:
- psql.py -t 指定的表名必须大写。
- 数组查询时,索引是从1开始的。
3.4 命令行工具sqlline.py使用示例
可以使用bin目录下的 sqlline.py工具进入phoenix客户端。
># sqlline.py hdp01,hdp02,hdp03:2181
0: jdbc:phoenix:hdp01,hdp02,hdp03:2181> !tables
+------------+--------------+-------------+---------------+----------+---------+
| TABLE_CAT | TABLE_SCHEM | TABLE_NAME | TABLE_TYPE | REMARKS | TYPE_NA |
+------------+--------------+-------------+---------------+----------+---------+
| | SYSTEM | CATALOG | SYSTEM TABLE | | |
| | SYSTEM | FUNCTION | SYSTEM TABLE | | |
| | SYSTEM | LOG | SYSTEM TABLE | | |
| | SYSTEM | SEQUENCE | SYSTEM TABLE | | |
| | SYSTEM | STATS | SYSTEM TABLE | | |
| | | T_SCORE | TABLE | | |
+------------+--------------+-------------+---------------+----------+---------+
0: jdbc:phoenix:hdp01,hdp02,hdp03:2181> !describe t_score
+------------+--------------+-------------+--------------+------------+--------+
| TABLE_CAT | TABLE_SCHEM | TABLE_NAME | COLUMN_NAME | DATA_TYPE | TYPE |
+------------+--------------+-------------+--------------+------------+--------+
| | | T_SCORE | STUDENT | 12 | VARCHA |
| | | T_SCORE | SCORES | 2003 | VARCHA |
+------------+--------------+-------------+--------------+------------+--------+
0: jdbc:phoenix:hdp01,hdp02,hdp03:2181> !history
2. 1: !tables
3. 2: !describe t_score
4. 3: !history
0: jdbc:phoenix:hdp01,hdp02,hdp03:2181> !help
...
0: jdbc:phoenix:hdp01,hdp02,hdp03:2181> !set key value
...
0: jdbc:phoenix:hdp01,hdp02,hdp03:2181> !exit
>#
默认情况下phoenix不支持分组,需要打开开关。
1.停止HBase集群;
2.将如下配置信息添加到hbase-site.xml文件中【其存放在HBase的conf目录中,所有集群机器都要修改,同时还要修改phoenix/bin/hbase-site.xml文件】
<!-- 指定启动分组功能 -->
<property>
<name>phoenix.schema.isNamespaceMappingEnabled</name>
<value>true</value>
</property>
3.启动集群。
操作数据库表分组:
CREATE SCHEMA IF NOT EXISTS wolfcode_mdb;
USE wolfcode_mdb;
DROP SCHEMA IF EXISTS wolfcode_mdb;
创建/删除分组下的表:
CREATE TABLE t_employee(id BIGINT primary key, name VARCHAR, salary UNSIGNED_DOUBLE, gender CHAR(1));
DROP TABLE wolfcode_mdb.employee;
插入数据:
UPSERT INTO t_employee(id,name,salary,gender) VALUES(1,'zhangsan',9800.00,'M');
UPSERT INTO t_employee(id,name,salary,gender) VALUES(2,'lisi',9900.00,'M');
UPSERT INTO t_employee VALUES(3,'wangwu',7500.00,'F');
UPSERT INTO t_employee VALUES(4,'zhaoliu',10000.00,'M');
UPSERT INTO t_employee VALUES(5,'张一刀',7700.00,'F');
除了上述的插入操作,还支持UPSERT SELECT批量插入操作,如下代码:
UPSERT INTO test.targetTable(col1, col2) SELECT col3, col4 FROM test.sourceTable WHERE col5 < 100;
更新数据:由于HBase的主键设计,相同rowkey的内容可以直接覆盖,这就变相的更新数据。
UPSERT INTO t_employee(id,salary) VALUES(1,10800.00);
删除数据:
DELETE FROM t_employee WHERE name LIKE '张一%';
查询数据:
SELECT * FROM t_employee LIMIT 2;
SELECT * FROM t_employee LIMIT 3 OFFSET 2;
更多Phoenix的语法官网:http://phoenix.apache.org/language/index.html
想获取更多技术干货,请前往叩丁狼官网:http://www.wolfcode.cn/all_article.html