Phoenix

database

Phoenix

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

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

目录

  • Phoenix
  • 1、Phoenix搭建
    • 1、关闭hbase集群,在master中执行
    • 2、上传解压配置环境变量
    • 3、将phoenix-4.15.0-HBase-1.4-server.jar复制到所有节点的hbase lib目录下
    • 4、启动hbase , 在master中执行
    • 5、配置环境变量
  • 2、Phoenix使用
    • 1、连接sqlline
    • 2、常用命令
    • 3、phoenix表映射
      • 3.1、视图映射
      • 3.2、表映射
  • 3、Phoenix二级索引
    • 1、开启索引支持
    • 2、创建索引
      • 2.1、全局索引
      • 2.2、本地索引
      • 2.3、覆盖索引
  • 4、Phoenix JDBC

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 + " " + start_date + " " + end_date + " " + x + " " + y + " " + county);

}

ps.close();

conn.close();

以上是 Phoenix 的全部内容, 来源链接: utcz.com/z/536012.html

回到顶部