版本:
* hadoop:2.7.5
* hbase:1.4.13
* phoenix:4.15.0
* zookeeper:3.6.0
准备工作
明确自己是要将hbase中的数据加载到phoenix中
如果表命名空间不是默认的,要配置一些属性。这里检查两个事情:
- 检查hbase服务中的hbase-site.xml配置文件是否有:
<property>
<name>phoenix.schema.isNamespaceMappingEnabled</name>
<value>true</value>
</property>
<property>
<name>phoenix.schema.mapSystemTablesToNamespace</name>
<value>true</value>
</property>
- 检查phoenix中hbase-site.xml配置文件是否也有
<property>
<name>phoenix.schema.isNamespaceMappingEnabled</name>
<value>true</value>
</property>
<property>
<name>phoenix.schema.mapSystemTablesToNamespace</name>
<value>true</value>
</property>
ok!如果是默认的就请忽略!
一.为什么要做映射?
本地安装好 Phoenix 之后,用 phoenix 的 !talblse 命令列出所有表,会发现 HBase 原有的表没有被列出来。而使用 Phoenix sql 的 CREATE 语句创建的一张新表,则可以通过 !tables 命令展示出来。
这是因为 Phoenix 无法自动识别 HBase 中原有的表,所以需要将 HBase 中已有的做映射,才能够被 Phoenix 识别并操作。说白了就是要需要告诉 Phoenix 一声 xx 表的 xx 列是主键,xx 列的数据类型。
二.如何进行映射呢?
这里我从用 hbase shell 创建一个表开始,来展示如何做映射。
create 'test_table','0'
put 'test_table', 'row001','0:name','Jane'
put 'test_table', 'row002','0:name','Tom'
put 'test_table', 'row003','0:name','Bill'
1.创建一个 HBase 表并插入一定量数据
2.使用 CREATE 语句在 Phoenix 中创建映射表
CREATE TABLE "test_table" ( "ROW" varchar primary key, "0"."name" varchar) column_encoded_bytes=0;
创建过程会有几秒钟卡顿,请耐心等待。
这里有几点需要注意:
a) Phoenix 对表名和列名都是区分大小写的。 但是,如果不加双引号,则默认为大写。例如上面这条语句,如果 test_table 不加双引号,则创建后的表名则是 TEST_TABLE。
b) 表名要和 HBase 中建立的表名一致。 HBase 默认的主列名是 ROW,所以要将“ROW”设置为主键。列簇和列名也要用双引号括起来,要不然小写会自动变成大写。
3.使用 SELECT 语句查询
SELECT * FROM "test_table";
查得结果如图所示:
4.特殊强调
如果你使用的是 Phoenix 4.10 及以上的版本,可能会遇到查不出数据的情况,如下图所示:
这是因为在 4.10 版本之后,Phoenix 对列的编码方式有所改变(官方文档地址:http://phoenix.apache.org/columnencoding.html)。就拿上面的例子来说,同样是"name"这个列,看起来列名是一样的,但是 Phoenix 对这个列名进行了编码,也就是说 Phoenix 创建的 name 列实际上和 HBase 里的 name 列不是一个列了,所以查不出来数据。
那么如何解决这个问题呢?
在使用 Phoenix 创建表的时候,需要设置 COLUMN_ENCODED_BYTES 属性为 0,即不让 Phoenix 对 column family 进行编码。
CREATE TABLE "test_table" ( "ROW" varchar primary key, "0"."name" varchar) column_encoded_bytes=0;
这样就能查出数据了。
另外,根据官方文档的内容,“One can set the column mapping property only at the time of creating the table. ”,也就是说只有在创建表的时候才能够设置属性。如果在创建的时候没有设置,之后怎么去设置就不太清楚了,可能是无法改变,至少目前我还没有找到相关方法。所以大家在创建映射表的时候一定要注意设置属性。
补充区域
如果是有命名空间的表语句:
在phoenix中创建该表或者试图前,要先创建对应的schema:
create schema if not exists "events_db";
然后才能创建表或者视图
#建表
CREATE VIEW "events_db"."event_attendee" ( "ROW" varchar primary key, "euat"."event_id" varchar,"euat"."user_id" varchar,"euat"."attend_type" varchar) column_encoded_bytes=0;
#建试图
CREATE TABLE "events_db"."event_attendee" ( "ROW" varchar primary key, "euat"."event_id" varchar,"euat"."user_id" varchar,"euat"."attend_type" varchar) column_encoded_bytes=0;
hbase严格区分大小写,表名和列族以及列名需要用双引号括起来,并且需要加上命名空间
create view “events_db”.“event_attendee” ( “ROW” varchar primary key, “euat”.“event_id” varchar,“euat”.“user_id” varchar,“euat”.“attend_type” varchar) column_encoded_bytes=0;as select * from “event_db”.“event_attendee”;
3.在Phoenix中查询时需要加上命名空间和双引号
select * from “event_db”.“event_attendee” limit 5;
补充完…
三.视图映射
如果只做查询操作的话,建议大家使用视图映射的方式,而非表映射。因为一旦出现问题,例如上面提到的,在创建映射表时如果忘记设置属性(4.10版之后),那么想要删除映射表的话,HBase 中该表也会被删除,导致数据的丢失。而如果是用视图映射,则删除视图不会影响原有表的数据。
四.总结
- 需要将原有 HBase 中的表做映射才能后使用 Phoenix 操作。
- Phoenix 区分大小写,切默认情况下会将小写转成大写,所以表名、列簇、列名需要用双引号。
- Phoenix 4.10 版本之后,在创建表映射时需要将 COLUMN_ENCODED_BYTES 置为 0。
- 删除映射表,会同时删除原有 HBase 表。所以如果只做查询操作,建议做视图映射。