Phoenix

Posted lmandcc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Phoenix相关的知识,希望对你有一定的参考价值。

Phoenix

Hbase适合存储大量的对关系运算要求低的NOSQL数据,受Hbase 设计上的限制不能直接使用原生的API执行在关系数据库中普遍使用的条件判断和聚合等操作。Hbase很优秀,一些团队寻求在Hbase之上提供一种更面向普通开发人员的操作方式,Apache Phoenix即是。

Phoenix 基于Hbase给面向业务的开发人员提供了以标准SQL的方式对Hbase进行查询操作,并支持标准SQL中大部分特性:条件运算,分组,分页,等高级查询语法。

1、Phoenix搭建

Phoenix 4.15 HBase 1.4.6 hadoop 2.7.6

1、关闭hbase集群,在master中执行

stop-hbase.sh

2、上传解压配置环境变量

解压

tar -xvf apache-phoenix-4.15.0-HBase-1.4-bin.tar.gz -C /usr/local/soft/

改名

mv apache-phoenix-4.15.0-HBase-1.4-bin phoenix-4.15.0

3、将phoenix-4.15.0-HBase-1.4-server.jar复制到所有节点的hbase lib目录下

scp /usr/local/soft/phoenix-4.15.0/phoenix-4.15.0-HBase-1.4-server.jar master:/usr/local/soft/hbase-1.4.6/lib/

scp /usr/local/soft/phoenix-4.15.0/phoenix-4.15.0-HBase-1.4-server.jar node1:/usr/local/soft/hbase-1.4.6/lib/

scp /usr/local/soft/phoenix-4.15.0/phoenix-4.15.0-HBase-1.4-server.jar node2:/usr/local/soft/hbase-1.4.6/lib/

4、启动hbase , 在master中执行

start-hbase.sh

5、配置环境变量

vim /etc/profile

2、Phoenix使用

1、连接sqlline

sqlline.py master,node1,node2

# 出现
163/163 (100%) Done
Done
sqlline version 1.5.0
0: jdbc:phoenix:master,node1,node2> 


2、常用命令

# 1、创建表

CREATE TABLE IF NOT EXISTS STUDENT (
 id VARCHAR NOT NULL PRIMARY KEY, 
 name VARCHAR,
 age BIGINT, 
 gender VARCHAR ,
 clazz VARCHAR
);

# 2、显示所有表
 !table

# 3、插入数据
upsert into STUDENT values(\'1500100004\',\'葛德曜\',24,\'男\',\'理科三班\');
upsert into STUDENT values(\'1500100005\',\'宣谷芹\',24,\'男\',\'理科六班\');
upsert into STUDENT values(\'1500100006\',\'羿彦昌\',24,\'女\',\'理科三班\');


# 4、查询数据,支持大部分sql语法,
select * from STUDENT ;
select * from STUDENT where age=24;
select gender ,count(*) from STUDENT group by gender;
select * from student order by gender;

# 5、删除数据
delete from STUDENT where id=\'1500100004\';


# 6、删除表
drop table STUDENT;
 
 
# 7、退出命令行
!quit

更多语法参照官网
https://phoenix.apache.org/language/index.html#upsert_select

3、phoenix表映射

默认情况下,直接在hbase中创建的表,通过phoenix是查看不到的

如果需要在phoenix中操作直接在hbase中创建的表,则需要在phoenix中进行表的映射。映射方式有两种:视图映射和表映射

3.1、视图映射

Phoenix创建的视图是只读的,所以只能用来做查询,无法通过视图对源数据进行修改等操作

# hbase shell 进入hbase命令行
hbase shell 

# 创建hbase表
create \'test\',\'name\',\'company\' 

# 插入数据
put \'test\',\'001\',\'name:firstname\',\'zhangsan1\'
put \'test\',\'001\',\'name:lastname\',\'zhangsan2\'
put \'test\',\'001\',\'company:name\',\'数加\'
put \'test\',\'001\',\'company:address\',\'合肥\'


# 在phoenix创建视图, primary key 对应到hbase中的rowkey

create view "test"(
empid varchar primary key,
"name"."firstname" varchar,
"name"."lastname"  varchar,
"company"."name"  varchar,
"company"."address" varchar
);

CREATE view "students" (
 id VARCHAR NOT NULL PRIMARY KEY, 
 "info"."name" VARCHAR,
 "info"."age" VARCHAR, 
 "info"."gender" VARCHAR ,
 "info"."clazz" VARCHAR
) column_encoded_bytes=0;

# 在phoenix查询数据,表名通过双引号引起来
select * from "test";

# 删除视图
drop view "test";

3.2、表映射

使用Apache Phoenix创建对HBase的表映射,有两类:

1) 当HBase中已经存在表时,可以以类似创建视图的方式创建关联表,只需要将create view改为create table即可。

2)当HBase中不存在表时,可以直接使用create table指令创建需要的表,并且在创建指令中可以根据需要对HBase表结构进行显示的说明。

第1)种情况下,如在之前的基础上已经存在了test表,则表映射的语句如下:

create table "test" (
empid varchar primary key,
"name"."firstname" varchar,
"name"."lastname"varchar,
"company"."name"  varchar,
"company"."address" varchar
)column_encoded_bytes=0;

upsert into  "test"  values(\'1\',\'2\',\'3\',\'4\',\'5\');

CREATE table  "students" (
 id VARCHAR NOT NULL PRIMARY KEY, 
 "info"."name" VARCHAR,
 "info"."age" VARCHAR, 
 "info"."gender" VARCHAR ,
 "info"."clazz" VARCHAR
) column_encoded_bytes=0;

upsert into "students" values(\'1500110004\',\'葛德曜\',\'24\',\'n ü\',\'理科三班\');

使用create table创建的关联表,如果对表进行了修改,源数据也会改变,同时如果关联表被删除,源表也会被删除。但是视图就不会,如果删除视图,源数据不会发生改变。

3、Phoenix二级索引

对于Hbase,如果想精确定位到某行记录,唯一的办法就是通过rowkey查询。如果不通过rowkey查找数据,就必须逐行比较每一行的值,对于较大的表,全表扫描的代价是不可接受的。

1、开启索引支持

# 关闭hbase集群
stop-hbase.sh

# 在/usr/local/soft/hbase-1.4.6/conf/hbase-site.xml中增加如下配置

<property>
  <name>hbase.regionserver.wal.codec</name>
  <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
</property>
<property>
    <name>hbase.rpc.timeout</name>
    <value>60000000</value>
</property>
<property>
    <name>hbase.client.scanner.timeout.period</name>
    <value>60000000</value>
</property>
<property>
    <name>phoenix.query.timeoutMs</name>
    <value>60000000</value>
</property>


# 同步到所有节点
scp hbase-site.xml node1:`pwd`
scp hbase-site.xml node2:`pwd`

# 修改phoenix目录下的bin目录中的hbase-site.xml
<property>
    <name>hbase.rpc.timeout</name>
    <value>60000000</value>
</property>
<property>
    <name>hbase.client.scanner.timeout.period</name>
    <value>60000000</value>
</property>
<property>
    <name>phoenix.query.timeoutMs</name>
    <value>60000000</value>
</property>


# 启动hbase
start-hbase.sh
# 重新进入phoenix客户端
sqlline.sql master,node1,node2

2、创建索引

2.1、全局索引

全局索引适合读多写少的场景。如果使用全局索引,读数据基本不损耗性能,所有的性能损耗都来源于写数据。数据表的添加、删除和修改都会更新相关的索引表(数据删除了,索引表中的数据也会删除;数据增加了,索引表的数据也会增加)

注意: 对于全局索引在默认情况下,在查询语句中检索的列如果不在索引表中,Phoenix不会使用索引表将,除非使用hint。

# 创建DIANXIN.sql
CREATE TABLE IF NOT EXISTS DIANXIN (
     mdn VARCHAR ,
     start_date VARCHAR ,
     end_date VARCHAR ,
     county VARCHAR,
     x DOUBLE ,
     y  DOUBLE,
     bsid VARCHAR,
     grid_id  VARCHAR,
     biz_type VARCHAR, 
     event_type VARCHAR , 
     data_source VARCHAR ,
     CONSTRAINT PK PRIMARY KEY (mdn,start_date)
) column_encoded_bytes=0;

# 上传数据DIANXIN.csv

# 导入数据
psql.py master,node1,node2 DIANXIN.sql DIANXIN.csv

# 创建全局索引
CREATE INDEX DIANXIN_INDEX ON DIANXIN ( end_date );

# 查询数据 ( 索引未生效)
select * from DIANXIN where end_date = \'20180503154014\';

# 强制使用索引 (索引生效) hint
select /*+ INDEX(DIANXIN DIANXIN_INDEX) */  * from DIANXIN where end_date = \'20180503154014\';

select /*+ INDEX(DIANXIN DIANXIN_INDEX) */  * from DIANXIN where end_date = \'20180503154014\'  and start_date = \'20180503154614\';

# 取索引列,(索引生效)
select end_date from DIANXIN where end_date = \'20180503154014\';

# 创建多列索引
CREATE INDEX DIANXIN_INDEX1 ON DIANXIN ( end_date,COUNTY );

# 多条件查询 (索引生效)
select end_date,MDN,COUNTY from DIANXIN where end_date = \'20180503154014\' and COUNTY = \'8340104\';

# 查询所有列 (索引未生效)
select  * from DIANXIN where end_date = \'20180503154014\'  and COUNTY = \'8340104\';

# 查询所有列 (索引生效)
select /*+ INDEX(DIANXIN DIANXIN_INDEX1) */ * from DIANXIN where end_date = \'20180503154014\' and COUNTY = \'8340104\';

# 单条件  (索引未生效)
select end_date from DIANXIN where  COUNTY = \'8340103\';

select COUNTY from DIANXIN where end_date = \'20180503154014\';

# 删除索引
drop index DIANXIN_INDEX on DIANXIN;

2.2、本地索引

本地索引适合写多读少的场景,或者存储空间有限的场景。和全局索引一样,Phoenix也会在查询的时候自动选择是否使用本地索引。本地索引因为索引数据和原数据存储在同一台机器上,避免网络数据传输的开销,所以更适合写多的场景。由于无法提前确定数据在哪个Region上,所以在读数据的时候,需要检查每个Region上的数据从而带来一些性能损耗。

注意:对于本地索引,查询中无论是否指定hint或者是查询的列是否都在索引表中,都会使用索引表。

# 创建本地索引
CREATE LOCAL INDEX DIANXIN_LOCAL_IDEX ON DIANXIN(grid_id);

# 索引生效
select grid_id from dianxin where grid_id=\'117285031820040\';

# 索引生效
select * from dianxin where grid_id=\'117285031820040\';

2.3、覆盖索引

覆盖索引是把原数据存储在索引数据表中,这样在查询时不需要再去HBase的原表获取数据就,直接返回查询结果。

注意:查询是 select 的列和 where 的列都需要在索引中出现。

# 创建覆盖索引
CREATE INDEX DIANXIN_INDEX_COVER ON DIANXIN ( x,y ) INCLUDE ( county );

# 查询所有列 (索引未生效)
select * from dianxin where x=117.288 and y =31.822;

# 强制使用索引 (索引生效)
select /*+ INDEX(DIANXIN DIANXIN_INDEX_COVER) */ * from dianxin where x=117.288 and y =31.822;

# 查询索引中的列 (索引生效) mdn是DIANXIN表的RowKey中的一部分
select x,y,county from dianxin where x=117.288 and y =31.822;
select mdn,x,y,county from dianxin where x=117.288 and y =31.822;

# 查询条件必须放在索引中  select 中的列可以放在INCLUDE (将数据保存在索引中)
select /*+ INDEX(DIANXIN DIANXIN_INDEX_COVER) */ x,y,count(*) from dianxin group by x,y;

4、Phoenix JDBC

# 导入依赖

<dependency>
    <groupId>org.apache.phoenix</groupId>
    <artifactId>phoenix-core</artifactId>
    <version>4.15.0-HBase-1.4</version>
</dependency>


Connection conn = DriverManager.getConnection("jdbc:phoenix:master,node1,node2:2181");
        PreparedStatement ps = conn.prepareStatement("select /*+ INDEX(DIANXIN DIANXIN_INDEX) */ * from DIANXIN where end_date=?");
        ps.setString(1, "20180503212649");
        ResultSet rs = ps.executeQuery();
        while (rs.next()) {
            String mdn = rs.getString("mdn");
            String start_date = rs.getString("start_date");
            String end_date = rs.getString("end_date");
            String x = rs.getString("x");
            String y = rs.getString("y");
            String county = rs.getString("county");
            System.out.println(mdn + "\\t" + start_date + "\\t" + end_date + "\\t" + x + "\\t" + y + "\\t" + county);
        }
        ps.close();
        conn.close();


Phoenix入门

Phoenix入门

Hive on HBASE

Phoenix概述

虽然Hive on SQL对SQL的支持更加全面,但是其不支持二级索引,底层是通过MapReduce实现的。Phoenix是专门为HBASE设计的SQL on HBASE工具,使用Phoenix可以实现基于SQL操作HBASE,使用Phoenix也可以自动构建二级索引并维护二级索引。

Phoenix官网
官网这么介绍它:
Apache Phoenix enables OLTP and operational analytics in Hadoop for low latency applications by combining the best of both worlds:

the power of standard SQL and JDBC APIs with full ACID transaction capabilities and the flexibility of late-bound, schema-on-read capabilities from the NoSQL world by leveraging HBase as its backing store.

Apache Phoenix is fully integrated with other Hadoop products such as Spark, Hive, Pig, Flume, and Map Reduce.

翻译过来是:
Apache Phoenix通过结合两个方面的优点,在Hadoop中为低延迟应用程序提供OLTP和操作分析:

标准SQL和jdbcapis的强大功能,以及完整的ACID事务处理功能和通过利用HBase作为其后台存储,NoSQL世界中后期绑定的模式读取功能的灵活性。

Apache Phoenix与其他Hadoop产品(如Spark、Hive、Pig、Flume和Map Reduce)完全集成。

Phoenix官方下载

翻到最下边还有:

Phoenix官方15分钟快速入门

Phoenix官方功能介绍

Phoenix官方语法介绍 这里可以查看Phoenix各种命令的语法。

简言之,Phoenix上层提供了SQL接口,底层通过HBASE的Java API实现,通过构建一系列Scan和Put实现对HBASE数据的读写。

由于底层封装了大量的内置协处理器,Phoenix可以实现各种复杂的处理需求,如:二级索引。Phoenix 对 SQL 相对支持不全面,但是性能比较好,直接使用HbaseAPI,支持索引实现。故Phoenix适用于任何需要使用SQL或者JDBC来快速的读写Hbase的场景,尤其是需要构建/维护二级索引的场景。

Phoenix部署

cd /export/software/

使用rz上传安装包(选用5.0.0版本)后解压及改名:

tar -zxvf apache-phoenix-5.0.0-HBase-2.0-bin.tar.gz -C /export/server/
cd /export/server/
mv apache-phoenix-5.0.0-HBase-2.0-bin phoenix-5.0.0-HBase-2.0-bin

Linux有文件句柄限制,默认是1024,可能不够用,先在3台node的尾部插入这些内容来修改Linux文件句柄数:

vim /etc/security/limits.conf

* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096

【*】这个标号必须有,代表所有用户。记得保存。

切换目录并查看:

cd /export/server/phoenix-5.0.0-HBase-2.0-bin/
ll -ah

东西还挺多:

[root@node1 phoenix-5.0.0-HBase-2.0-bin]# ll -ah
总用量 464M
drwxr-xr-x  5  502 games 4.0K 627 2018 .
drwxr-xr-x. 9 root root   178 527 17:37 ..
drwxr-xr-x  4  502 games 4.0K 527 17:37 bin
drwxr-xr-x  3  502 games  133 527 17:37 examples
-rw-r--r--  1  502 games 141K 627 2018 LICENSE
-rw-r--r--  1  502 games  11K 627 2018 NOTICE
-rw-r--r--  1  502 games 129M 627 2018 phoenix-5.0.0-HBase-2.0-client.jar
-rw-r--r--  1  502 games 106M 627 2018 phoenix-5.0.0-HBase-2.0-hive.jar
-rw-r--r--  1  502 games 132M 627 2018 phoenix-5.0.0-HBase-2.0-pig.jar
-rw-r--r--  1  502 games 7.6M 627 2018 phoenix-5.0.0-HBase-2.0-queryserver.jar
-rw-r--r--  1  502 games  40M 627 2018 phoenix-5.0.0-HBase-2.0-server.jar
-rw-r--r--  1  502 games  33M 627 2018 phoenix-5.0.0-HBase-2.0-thin-client.jar
-rw-r--r--  1  502 games 4.2M 627 2018 phoenix-core-5.0.0-HBase-2.0.jar
-rw-r--r--  1  502 games 2.5M 627 2018 phoenix-core-5.0.0-HBase-2.0-sources.jar
-rw-r--r--  1  502 games 2.4M 627 2018 phoenix-core-5.0.0-HBase-2.0-tests.jar
-rw-r--r--  1  502 games  47K 627 2018 phoenix-flume-5.0.0-HBase-2.0.jar
-rw-r--r--  1  502 games  30K 627 2018 phoenix-flume-5.0.0-HBase-2.0-sources.jar
-rw-r--r--  1  502 games  37K 627 2018 phoenix-flume-5.0.0-HBase-2.0-tests.jar
-rw-r--r--  1  502 games 137K 627 2018 phoenix-hive-5.0.0-HBase-2.0.jar
-rw-r--r--  1  502 games  84K 627 2018 phoenix-hive-5.0.0-HBase-2.0-sources.jar
-rw-r--r--  1  502 games  77K 627 2018 phoenix-hive-5.0.0-HBase-2.0-tests.jar
-rw-r--r--  1  502 games  27K 627 2018 phoenix-kafka-5.0.0-HBase-2.0.jar
-rw-r--r--  1  502 games 686K 627 2018 phoenix-kafka-5.0.0-HBase-2.0-minimal.jar
-rw-r--r--  1  502 games  17K 627 2018 phoenix-kafka-5.0.0-HBase-2.0-sources.jar
-rw-r--r--  1  502 games  24K 627 2018 phoenix-kafka-5.0.0-HBase-2.0-tests.jar
-rw-r--r--  1  502 games  23K 627 2018 phoenix-load-balancer-5.0.0-HBase-2.0.jar
-rw-r--r--  1  502 games  13K 627 2018 phoenix-load-balancer-5.0.0-HBase-2.0-tests.jar
-rw-r--r--  1  502 games 164K 627 2018 phoenix-pherf-5.0.0-HBase-2.0.jar
-rw-r--r--  1  502 games 3.5M 627 2018 phoenix-pherf-5.0.0-HBase-2.0-minimal.jar
-rw-r--r--  1  502 games 116K 627 2018 phoenix-pherf-5.0.0-HBase-2.0-sources.jar
-rw-r--r--  1  502 games  70K 627 2018 phoenix-pherf-5.0.0-HBase-2.0-tests.jar
-rw-r--r--  1  502 games  45K 627 2018 phoenix-pig-5.0.0-HBase-2.0.jar
-rw-r--r--  1  502 games  30K 627 2018 phoenix-pig-5.0.0-HBase-2.0-sources.jar
-rw-r--r--  1  502 games  46K 627 2018 phoenix-pig-5.0.0-HBase-2.0-tests.jar
-rw-r--r--  1  502 games  31K 627 2018 phoenix-queryserver-5.0.0-HBase-2.0.jar
-rw-r--r--  1  502 games  23K 627 2018 phoenix-queryserver-5.0.0-HBase-2.0-sources.jar
-rw-r--r--  1  502 games  59K 627 2018 phoenix-queryserver-5.0.0-HBase-2.0-tests.jar
-rw-r--r--  1  502 games  17K 627 2018 phoenix-queryserver-client-5.0.0-HBase-2.0.jar
-rw-r--r--  1  502 games  14K 627 2018 phoenix-queryserver-client-5.0.0-HBase-2.0-sources.jar
-rw-r--r--  1  502 games  11K 627 2018 phoenix-queryserver-client-5.0.0-HBase-2.0-tests.jar
-rw-r--r--  1  502 games  87K 627 2018 phoenix-spark-5.0.0-HBase-2.0.jar
-rw-r--r--  1  502 games 3.5K 627 2018 phoenix-spark-5.0.0-HBase-2.0-javadoc.jar
-rw-r--r--  1  502 games  25K 627 2018 phoenix-spark-5.0.0-HBase-2.0-sources.jar
-rw-r--r--  1  502 games 125K 627 2018 phoenix-spark-5.0.0-HBase-2.0-tests.jar
-rw-r--r--  1  502 games  16K 627 2018 phoenix-tracing-webapp-5.0.0-HBase-2.0.jar
-rw-r--r--  1  502 games 2.7M 627 2018 phoenix-tracing-webapp-5.0.0-HBase-2.0-runnable.jar
-rw-r--r--  1  502 games  12K 627 2018 phoenix-tracing-webapp-5.0.0-HBase-2.0-sources.jar
-rw-r--r--  1  502 games 7.9K 627 2018 phoenix-tracing-webapp-5.0.0-HBase-2.0-tests.jar
drwxr-xr-x  6  502 games  236 527 17:37 python
-rw-r--r--  1  502 games 1.2K 627 2018 README.md

这些jar包可以作为HBASE的依赖库,先:

cp phoenix-* /export/server/hbase-2.1.0/lib/
cd /export/server/hbase-2.1.0/lib/

再分发给node2和node3:

scp phoenix-* node2:$PWD
scp phoenix-* node3:$PWD

修改node1的hbase-site.xml:

cd /export/server/hbase-2.1.0/conf/
vim hbase-site.xml

在configuration之间插入:

<!-- 关闭流检查,从2.x开始使用async -->
<property>
    <name>hbase.unsafe.stream.capability.enforce</name>
    <value>false</value>
  </property>
<!-- 支持HBase命名空间映射 -->
<property>
    <name>phoenix.schema.isNamespaceMappingEnabled</name>
    <value>true</value>
</property>
<!-- 支持索引预写日志编码 -->
<property>
  <name>hbase.regionserver.wal.codec</name>
  <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
</property>

保存后同步给node2和node3:

scp hbase-site.xml node2:$PWD
scp hbase-site.xml node3:$PWD

PWD是大写!!!

由于Phoenix也需要加载配置文件:

[root@node1 conf]# cp hbase-site.xml /export/server/phoenix-5.0.0-HBase-2.0-bin/bin/
cp:是否覆盖"/export/server/phoenix-5.0.0-HBase-2.0-bin/bin/hbase-site.xml"yes

直接yes覆盖。安全起见再查看下:

cat /export/server/phoenix-5.0.0-HBase-2.0-bin/bin/hbase-site.xml

如果启动了HBASE需要重启HBASE才能刷新配置。。。笔者故意先不启动就是为了省去重启这一步。。。机智如我。。。按顺序启动HBASE即可(启动HDFS+YARN+Zookeeper→启动HBASE服务端→启动hbase shell)。

Phoenix启动

新建立node1会话:

cd /export/server/phoenix-5.0.0-HBase-2.0-bin/
[root@node1 phoenix-5.0.0-HBase-2.0-bin]# ll ./bin -ah
总用量 152K
drwxr-xr-x 4 502 games 4.0K 527 17:37 .
drwxr-xr-x 5 502 games 4.0K 627 2018 ..
drwxr-xr-x 2 502 games   25 527 17:37 argparse-1.4.0
drwxr-xr-x 4 502 games  101 527 17:37 config
-rw-r--r-- 1 502 games  33K 627 2018 daemon.py
-rwxr-xr-x 1 502 games 1.9K 627 2018 end2endTest.py
-rw-r--r-- 1 502 games 1.6K 627 2018 hadoop-metrics2-hbase.properties
-rw-r--r-- 1 502 games 3.0K 627 2018 hadoop-metrics2-phoenix.properties
-rw-r--r-- 1 502 games 1.9K 527 19:39 hbase-site.xml
-rw-r--r-- 1 502 games 2.6K 627 2018 log4j.properties
-rwxr-xr-x 1 502 games 5.1K 627 2018 performance.py
-rwxr-xr-x 1 502 games 3.2K 627 2018 pherf-cluster.py
-rwxr-xr-x 1 502 games 2.7K 627 2018 pherf-standalone.py
-rwxr-xr-x 1 502 games 2.1K 627 2018 phoenix_sandbox.py
-rwxr-xr-x 1 502 games 9.5K 627 2018 phoenix_utils.py
-rwxr-xr-x 1 502 games 2.7K 627 2018 psql.py
-rwxr-xr-x 1 502 games 7.6K 627 2018 queryserver.py
-rw-r--r-- 1 502 games 1.8K 627 2018 readme.txt
-rw-r--r-- 1 502 games 1.7K 627 2018 sandbox-log4j.properties
-rwxr-xr-x 1 502 games 4.7K 627 2018 sqlline.py
-rwxr-xr-x 1 502 games 6.6K 627 2018 sqlline-thin.py
-rwxr-xr-x 1 502 games 6.8K 627 2018 tephra
-rw-r--r-- 1 502 games 2.0K 627 2018 tephra-env.sh
-rwxr-xr-x 1 502 games 6.8K 627 2018 traceserver.py

在bin目录内有个sqlline.py,这货是个Python写的启动脚本,运行它就能启动Phoenix:

bin/sqlline.py node1:2181

node1:16010查看HBASE的表:

比之前多了几个表,肯定不是笔者自己建立的。。。正好Phoenix也启动了,使用!tables看看:

0: jdbc:phoenix:node1:2181> !tables 
+------------+--------------+-------------+---------------+----------+------------+----------------------------+-----------------+-+
| TABLE_CAT  | TABLE_SCHEM  | TABLE_NAME  |  TABLE_TYPE   | REMARKS  | TYPE_NAME  | SELF_REFERENCING_COL_NAME  | REF_GENERATION  | |
+------------+--------------+-------------+---------------+----------+------------+----------------------------+-----------------+-+
|            | SYSTEM       | CATALOG     | SYSTEM TABLE  |          |            |                            |                 | |
|            | SYSTEM       | FUNCTION    | SYSTEM TABLE  |          |            |                            |                 | |
|            | SYSTEM       | LOG         | SYSTEM TABLE  |          |            |                            |                 | |
|            | SYSTEM       | SEQUENCE    | SYSTEM TABLE  |          |            |                            |                 | |
|            | SYSTEM       | STATS       | SYSTEM TABLE  |          |            |                            |                 | |
+------------+--------------+-------------+---------------+----------+------------+----------------------------+-----------------+-+
0: jdbc:phoenix:node1:2181> 

是它创建的。。。那么Phoenix也就部署完毕。使用!quit即可退出。

命令行使用

可以在上文中的官网指导手册查看帮助。使用!help也可查看一些帮助。

DDL

操作NameSpace

创建NameSpace

在Phoenix的命令行:

0: jdbc:phoenix:node1:2181> create schema if not exists student;
No rows affected (0.274 seconds)

在hbase shell:

hbase(main):001:0> list_namespace
NAMESPACE                                                                                                                           
STUDENT                                                                                                                             
SYSTEM                                                                                                                              
default                                                                                                                             
hbase                                                                                                                               
test210524                                                                                                                          
test210525                                                                                                                          
6 row(s)
Took 0.5744 seconds  

好吧。。。全是大写字母!!!如果要使用小写字母需要+""双引号。

切换NameSpace

0: jdbc:phoenix:node1:2181> use student;
No rows affected (0.02 seconds)

删除NameSpace

0: jdbc:phoenix:node1:2181> drop schema if exists student;
No rows affected (0.274 seconds)

操作Table

列举

上方使用!table列举过了。

创建


官网给的还比较全面。。。也可以自己试试:

CREATE TABLE my_schema.my_table (
    id BIGINT not null primary key, 
    date Date
);

HBASE当然是没有主键的,这个主键就是HBASE的Rowkey。

CREATE TABLE my_table ( 
    id INTEGER not null primary key desc, 
    m.date DATE not null,
    m.db_utilization DECIMAL, 
    i.db_utilization
) m.VERSIONS='3';

这种写法就是指定了列族(此处m和i)的列。

CREATE TABLE stats.prod_metrics ( 
      host char(50) not null, 
      created_date date not null,
      txn_count bigint 
      CONSTRAINT pk PRIMARY KEY (host, created_date) 
  );

HBASE必须有Rowkey,∴无论如何也得指定一个(此处构建主键,其实就是用多个字段组合出Rowkey)。

CREATE TABLE IF NOT EXISTS "my_case_sensitive_table"( 
    "id" char(10) not null primary key, 
    "value" integer
) DATA_BLOCK_ENCODING='NONE',VERSIONS=5,MAX_FILESIZE=2000000 
split on (?, ?, ?);

还可以使用split on来指定预分区。

 CREATE TABLE IF NOT EXISTS my_schema.my_table (
    org_id CHAR(15), 
    entity_id CHAR(15), 
    payload binary(1000),
    CONSTRAINT pk PRIMARY KEY (org_id, entity_id) 
) TTL=86400

这种写法是指定有效期为86400ms。

如果HBASE中没有同名表,就会自动创建一个,例如上文中看到的只有5个表,在Phoenix命令行中执行:

use default;
create table if not exists ORDER_DTL(
    ID varchar primary key,
    C1.STATUS varchar,
    C1.PAY_MONEY float,
    C1.PAYWAY integer,
    C1.USER_ID varchar,
    C1.OPERATION_DATE varchar,
    C1.CATEGORY varchar
);

执行后:

0: jdbc:phoenix:node1:2181> !tables
+------------+--------------+-------------+---------------+----------+------------+----------------------------+-----------------+-+
| TABLE_CAT  | TABLE_SCHEM  | TABLE_NAME  |  TABLE_TYPE   | REMARKS  | TYPE_NAME  | SELF_REFERENCING_COL_NAME  | REF_GENERATION  | |
+------------+--------------+-------------+---------------+----------+------------+----------------------------+-----------------+-+
|            | SYSTEM       | CATALOG     | SYSTEM TABLE  |          |            |                            |                 | |
|            | SYSTEM       | FUNCTION    | SYSTEM TABLE  |          |            |                            |                 | |
|            | SYSTEM       | LOG         | SYSTEM TABLE  |          |            |                            |                 | |
|            | SYSTEM       | SEQUENCE    | SYSTEM TABLE  |          |            |                            |                 | |
|            | SYSTEM       | STATS       | SYSTEM TABLE  |          |            |                            |                 | |
|            |              | ORDER_DTL   | TABLE         |          |            |                            |                 | |
+------------+--------------+-------------+---------------+----------+------------+----------------------------+-----------------+-+
0: jdbc:phoenix:node1:2181> 

一般不会有人这么做。。。Phoenix的主要用途是查询。。。想要查询就得事先有表和数据。。。那么,先准备一个表和数据再说。。。使用shell脚本来做这件事:

cd /export/data/
rz上传数据
vim /export/data/hbasedata20210527.sh

插入:

#!/bin/bash
hbase shell /export/data/ORDER_INFO.txt

保存后+运行权限:

chmod u+x hbasedata20210527.sh 

执行:

hbasedata20210527.sh

Java API的DDL利用之前写的程序读取:

tableDescriptor.getTableName().getNameAsString() = ORDER_DTL
tableDescriptor.getTableName().getNameAsString() = ORDER_INFO
tableDescriptor.getTableName().getNameAsString() = SYSTEM:CATALOG
tableDescriptor.getTableName().getNameAsString() = SYSTEM:FUNCTION
tableDescriptor.getTableName().getNameAsString() = SYSTEM:LOG
tableDescriptor.getTableName().getNameAsString() = SYSTEM:MUTEX
tableDescriptor.getTableName().getNameAsString() = SYSTEM:SEQUENCE
tableDescriptor.getTableName().getNameAsString() = SYSTEM:STATS
tableDescriptor.getTableName().getNameAsString() = test210524:t1
tableDescriptor.getTableName().getNameAsString() = test210525:testTable1

居然没有命名空间!!!其实也无妨:

hbase(main):010:0> list
TABLE                                                                                                                               
ORDER_DTL                                                                                                                           
ORDER_INFO                                                                                                                          
SYSTEM:CATALOG                                                                                                                      
SYSTEM:FUNCTION                                                                                                                     
SYSTEM:LOG                                                                                                                          
SYSTEM:MUTEX                                                                                                                        
SYSTEM:SEQUENCE                                                                                                                     
SYSTEM:STATS                                                                                                                        
test210524:t1                                                                                                                       
test210525:testTable1                                                                                                               
10 row(s)
Took 0.0524 seconds                                                                                                                 
=> ["ORDER_DTL", "ORDER_INFO", "SYSTEM:CATALOG", "SYSTEM:FUNCTION", "SYSTEM:LOG", "SYSTEM:MUTEX", "SYSTEM:SEQUENCE", "SYSTEM:STATS", "test210524:t1", "test210525:testTable1"]
hbase(main):011:0> 

虽然这2张表并没有命名空间,但是看样子已经成功创建了表。更神奇的是:

0: jdbc:phoenix:node1:2181> create table if not exists ORDER_INFO(
. . . . . . . . . . . . . >     "ROW" varchar primary key,
. . . . . . . . . . . . . >     "C1"."USER_ID" varchar,
. . . . . . . . . . . . . >     "C1"."OPERATION_DATE" varchar,
. . . . . . . . . . . . . >     "C1"."PAYWAY" varchar,
. . . . . . . . . . . . . >     "C1"."PAY_MONEY" varchar,
. . . . . . . . . . . . . >     "

以上是关于Phoenix的主要内容,如果未能解决你的问题,请参考以下文章

凤凰框架phoenix.js websocket客户端有什么特定的框架吗?

如何安排代码在 Elixir 或 Phoenix 框架中每隔几个小时运行一次?

spark操作操作Phoenix

Spark 实战系列Phoenix 整合 spark 进行查询分析

Spark 实战系列Phoenix 整合 spark 进行查询分析

JAVA 实现数据导入Phoenix