背景介绍:原有的CDH集群,以Hive+Hbase+Impala进行数据处理查询,Hbase而言语法难懂,不同于寻常的SQL,Impala而言速度查询速度太慢且无法进行记录的修改。故而考虑用Phoenix来集成Hbase、Hive以解决上述问题。
前提:已经基于CM安装搭建CDH集群,本文采用parcels包的方式集成Phoenix到CDH集群。
本文采用的phoenix版本包如下:
# Parcel包
manifest.json
PHOENIX-5.0.0-cdh6.2.0.p0.1308267-el7.parcel
PHOENIX-5.0.0-cdh6.2.0.p0.1308267-el7.parcel.sha1
# Jar包
PHOENIX-1.0.jar
(1)修改.sha1文件为.sha,即去掉后缀1。将phoenix的parcel包和jar包上传到cloudera manager server节点的httpd服务下/var/www/html/phoenix,修改phoenix文件夹权限777。并可在http访问http://cdh001/pheonix。
chmod 777 -R /var/www/html/phoenix
# /var/www/html/phoenix目录结构如下
-rwxrwxrwx. 1 root root 2478 8月 1 2019 manifest.json
-rwxrwxrwx 1 root root 5306 3月 18 10:37 PHOENIX-1.0.jar
-rwxrwxrwx. 1 root root 402216960 8月 1 2019 PHOENIX-5.0.0-cdh6.2.0.p0.1308267-el7.parcel
-rwxrwxrwx. 1 root root 41 8月 1 2019 PHOENIX-5.0.0-cdh6.2.0.p0.1308267-el7.parcel.sha
(2)将parcl包复制到/opt/cloudera/parcel-repo目录(注意manifest.json要是phoenix目录中的),并修改权限777。
chmod 777 -R /opt/cloudera/parcel-repo
#/opt/cloudera/parcel-repo目录结构如下
-rwxrwxrwx. 1 root root 2478 8月 1 2019 manifest.json
-rwxrwxrwx. 1 root root 402216960 8月 1 2019 PHOENIX-5.0.0-cdh6.2.0.p0.1308267-el7.parcel
-rwxrwxrwx. 1 root root 41 8月 1 2019 PHOENIX-5.0.0-cdh6.2.0.p0.1308267-el7.parcel.sha
(3)将phoenix的jar包放到/opt/cloudera/csd目录下,并拷贝到httpd服务目录下,修改权限777。
chmod 777 *R /opt/cloudera/csd
#/opt/cloudera/csd目录结构如下
-rwxr-xr-x 1 root root 5306 3月 18 10:39 PHOENIX-1.0.jar
(4)在CM界面操作: “管理”->“设置”->输入查询"csd"->本地描述符存储库路径修改为"/opt/cloudera/csd"
(5)在CM界面操作: “主机”->“Parcel”->“配置”->远程 Parcel 存储库 URL中新增phoenix路径 “http://cdh001/phoenix/”
(6)“检查更新Parcel”->找到PHOENIX “下载”->“分配”->“激活”
(7)在CM主界面操作:集群 菜单栏"添加服务"->选择"PHOENIX"->quary server节点分配(3集群全部)->服务启动,回到CM界面可看到Phoenix。
(8)配置HBASE, “HBASE”->“配置”->搜索"hbase-site.xml"->“hbase-site.xml的HBase服务高级配置代码段”,以XML格式查看,粘贴如下内容,并保存。这一步即phoenix整合hbase。
<property>
<name>hbase.regionserver.wal.codecname>
<value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodecvalue>
property>
<property>
<name>phoenix.functions.allowUserDefinedFunctionsname>
<value>truevalue>
<description>enable UDF functionsdescription>
property>
(9)保存配置更改,重启过期服务hbase和phoenix。
(10)将Phoenix安装路径配置到系统环境变量中(所有安装Phoenix的节点执行)。
vim /etc/profile
#--------------------phoenix------------------------------------
export PHOENIX_HOME=/opt/cloudera/parcels/PHOENIX-5.0.0-cdh6.2.0.p0.1308267
export PATH=$PATH:$PHOENIX_HOME/bin
#激活生效
source /etc/profile
(11)任意节点启动phoenix,通过命令phoenix-sqlline zk节点hostname:2181/hbase 进入交互界面。
phoenix-sqlline cdh185
输入命令 !table 能看到输出表即正常运行了。
Hive-phoenix未整合前在hive中创建映射表报错
ParseException: Syntax error in line 7:undefined: STORED BY 'org.apache.phoenix.hive.PhoenixStorageHandler' ^ Encountered: BY Expected: AS CAUSED BY: Exception: Syntax error
整合方法:将phoenix安装目录下lib中phoenix-5.0.0-cdh6.2.0-hive.jar 拷贝到hive安装目录/lib中。所有安装pheonix节点都需要拷贝。
cp /opt/cloudera/parcels/PHOENIX/lib/phoenix/phoenix-5.0.0-cdh6.2.0-hive.jar /opt/cloudera/parcels/CDH/lib/hive/lib
注:在impala端不能创建hive-phoeinx映射表。
#进入hbase-shell命令:
hbase shell
#创建hbase表命令:
create 'hbase_test','user'
#插入数据命令:
put 'hbase_test','111','user:name','jack'
put 'hbase_test','111','user:age','18'
#查询hbase表命令:scan 'hbase_test'
#进入hive创建hbase关联表
create external table hbase_test1(
id int,
name string,
age int
)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,user:name,user:age")
TBLPROPERTIES("hbase.table.name" = "hbase_test");
#查看hive表数据,命令:
select * from hbase_test1
#往hive表中插入数据:
insert into hbase_test1(id,name,age) values(333,'mary',25);
#查询hive表数据 ,命令:
select * from hbase_test1
#同时查询hbase表数据,有hive中新增记录
#phoenix-shell启动命令
phoenix-sqlline.py cdh185:2181
#在phoenix中建立相同的表名实现与Hbase表的映射
create table if not exists "hbase_test"(
"id" varchar primary key,
"user"."name" varchar,
"user"."age" varchar
)
column_encoded_bytes=0;
create view if not exists "hbase_test2"(
"id" varchar primary key,
"user"."name" varchar,
"user"."age" varchar
)
column_encoded_bytes=0;
注意:
Phoneix中创建的表与HBase中映射的表名要相同
phoneix中创建表的字段名与与HBase中映射表的字段名要相同(注意大小写)
#插入数据命令:
upsert into "hbase_test"(id,"name","age") values('444','haha','33');
#在hbase中可查看到新增记录
对于内部表,Hive管理表和数据的生命周期。创建Hive表时,也会创建相应的Phoenix表。一旦Hive表被删除,Phoenix表也被删除。
#hive端创建内部表,并映射phoenix。
create table hive_phoenix_in_test (
s1 string,
i1 int,
f1 float,
d1 double
)
stored as parquetfile
STORED BY 'org.apache.phoenix.hive.PhoenixStorageHandler'
TBLPROPERTIES (
"phoenix.table.name" = "hive_phoenix_in_test",
"phoenix.zookeeper.quorum" = "cdh185,cdh186,cdh188",
"phoenix.zookeeper.znode.parent" = "/hbase",
"phoenix.zookeeper.client.port" = "2181",
"phoenix.rowkeys" = "s1, i1",
"phoenix.column.mapping" = "s1:s1, i1:i1, f1:f1, d1:d1",
"phoenix.table.options" = "SALT_BUCKETS=10, DATA_BLOCK_ENCODING='DIFF'"
);
#phoenix端表数据查询
select * from hive_phoenix_in_test
#hive端新增数据
insert into hive_phoenix_in_test values("a",1,1.0,1.0);
+-----+-----+------+------+
| s1 | i1 | f1 | d1 |
+-----+-----+------+------+
| a | 1 | 1.0 | 1.0 |
+-----+-----+------+------+
#phoenix端新增数据
upsert into hive_phoenix_in_test values ('b',5,1.85,4.4894165);
upsert into hive_phoenix_in_test values ('b',9,1.85,4.4894165);
+-----+-----+-------+------------+
| s1 | i1 | f1 | d1 |
+-----+-----+-------+------------+
| b | 5 | 1.85 | 4.4894165 |
| a | 1 | 1.0 | 1.0 |
| b | 9 | 1.85 | 4.4894165 |
+-----+-----+-------+------------+
#phoenix端更新数据,rowkey相同的进行修改
upsert into hive_phoenix_in_test values ('b',5,1.85,4.54);
+-----+-----+-------+------------+
| s1 | i1 | f1 | d1 |
+-----+-----+-------+------------+
| b | 5 | 1.85 | 4.54 |
| a | 1 | 1.0 | 1.0 |
| b | 9 | 1.85 | 4.4894165 |
+-----+-----+-------+------------+
#pheonix端删除数据
delete from hive_phoenix_in_test where "s1"='b' and "i1"=9;
+-----+-----+-------+-------+
| s1 | i1 | f1 | d1 |
+-----+-----+-------+-------+
| b | 5 | 1.85 | 4.54 |
| a | 1 | 1.0 | 1.0 |
+-----+-----+-------+-------+
对于外部表,Hive与**已有的Phoenix表**一起使用,仅管理Hive元数据。从Hive中删除EXTERNAL表只会删除Hive元数据,但不会删除Phoenix表。
create external table hive_phoenix_out_test (
i1 int,
s1 string,
f1 float,
d1 decimal
)
STORED BY 'org.apache.phoenix.hive.PhoenixStorageHandler'
TBLPROPERTIES (
"phoenix.table.name" = "hive_phoenix_out_test",
"phoenix.zookeeper.quorum" = "cdh185,cdh186,cdh188",
"phoenix.zookeeper.znode.parent" = "/hbase",
"phoenix.zookeeper.client.port" = "2181",
"phoenix.rowkeys" = "i1",
"phoenix.column.mapping" = "i1:i1, s1:s1, f1:f1, d1:d1"
);
phoenix.table.name # 指定映射的phoenix表名,默认与hive表相同
phoenix.zookeeper.quorum # hbase的zk管理集群,默认localhost
phoenix.zookeeper.znode.parent # 指定HBase的Zookeeper父节点,默认/hbase
phoenix.zookeeper.client.port # 定zookeeper端口,默认2181
phoenix.rowkeys # phoenix列表中的主列,必填
phoenix.column.mapping # hive和phoenix列名之间的映射
**注意:**所有删除和更新操作都应在phoenix方面执行。
其他配置项,可以再Hive-CLI中设置。
Performance Tuning性能调整
Parameter | Default Value | Description |
---|---|---|
phoenix.upsert.batch.size | 100 | 批量更新的数据条数 |
[phoenix-table-name].disable.wal | false | 临时设置表格属性disable_wal为true,即关闭预写功能,有时可以提高性能 |
[phoenix-table-name].auto.flush | false | 当预写功能禁用且自动刷写设置为true时,memstore刷新为hfile。hbase组件架构 |
Query Data查询数据
可以使用hivesql查询phoenix表中数据,单个表上的hive查询可以像运行phoenix中的查询一样快,并具有如下属性设置:hive.fetch.task.conversion=more和hive.exec.parallel=true。
Parameter | Default Value | Description |
---|---|---|
hbase.scan.cache | 100 | 读取单位请求的行大小 |
hbase.scan.cacheblock | false | 是否缓存块 |
split.by.stats | false | 设置为true时,映射器使用表统计信息,每个mapper对应一个指南 |
[hive-table-name].reducer.count | 1 | reducer个数。在Tez模式下,只影响单表的查询。 |
[phoenix-table-name].query.hint | 查询提示 |
限制:hive更新和删除操作需要hive和phoenix两方的事物管理器支持。
列映射无法正确使用映射行键列。
mapreduce和tez作业总是只有一个reducer。
phoenix交互界面启用命令:./phoenix-sqlline hbase节点列表
phoenix的DLL中建议为所有表名和列名加上双引号,否则phoenix会全部转为大写进行识别,同样的执行phoenix的查询命令时要给字符串用单引号,因为双引号里面的会被识别为列或表或列族。
其中row是主键,对应hbase的rowkey,其他字段使用"列族".“列名"作为字段名。若hbase表中的列名包含小数点,如列族为’cf’,列名为’root.a.b’,则在Phoenix的DDL中对应应为"cf”.“root.a.b” varchar。
command | 功能 | 样例 |
---|---|---|
!tables | 查看当前所有数据表名(等同于show tables) | !tables |
select | 查询表数据 | select…from… |
upsert | 新增或更改数据 | upsert into tname values(xx) |
delete | 删除表记录 | delete from tname |