零:复习
1. hbase的协处理器问题
(1) 协处理器的代码逻辑有异常,可能会造成hbase的regionserver瘫痪。
解决办法:关掉hbase的所有守护进程,进入zookeeper里删除相应的表元数据,再启动hbase,删除对应的表。修改完代码逻辑后,重新维护。
(2) 代码没问题,hbase的集群缺少设置。如:....DoNotReTRYException:could not......Set hbase.table.sanity.checks to false......
解决办法:在hbase-site.xml里设置hbase.table.sanity.checks属性的值为false
一、phoenix的简介与特点
1.1 简介
1. phoenix是apache组织旗下的一款产品。相当于java中间件,可以类似jdbc访问RDBMS一样,来访问HBase
2. phoenix是可以运行在hbase上的一个sql层。可以对hbase进行增删改查和管理数据的。
3. phoenix的sql语句,在底层会被翻译成hbase的api,比如scan/get操作
4. phoenix适合做离线批处理(OLAP)操作,不适合做实时分析操作(OLTP)
2.1 特点
phoenix虽然是构建在hbase层之上,但是由于以下特点,不会影响查询性能,反而会提高性能
- 编译SQL查询为原生HBase的scan语句
- 检测scan语句最佳的开始和结束的key
- 精心编排你的scan语句让他们并行执行
- 让计算去接近数据
- 推送你的WHERE子句的谓词到服务端过滤器处理
- 执行聚合查询通过服务端钩子(称为协同处理器)
phoenix还提供了一些增强优化性能
- 实现了二级索引来提升非主键字段查询的性能
- 统计相关数据来提高并行化水平,并帮助选择最佳优化方案
- 跳过扫描过滤器来优化IN,LIKE,OR查询
- 优化主键来均匀分布写压力
phoenix不能做的事情
- 不支持事务处理
- 不支持复杂的条件
二、phoenix安装
2.1 环境需求:
1. jdk1.8.0以上
2. hadoop2.7.6
3. zookeeper-3.4.10
4. hbase-1.2.1
2.2 搭建步骤
安装phoenix,就相当于在一台机器上安装navicat工具。
1)上传,解压,更名,配置环境变量,生效,验证
[root@qianfeng01 ~]
[root@qianfeng01 ~]
[root@qianfeng01 local]
[root@qianfeng01 local]
[root@qianfeng01 local]
验证是否能补全相关指令, 输入psq然后按tab键
2)拷贝phoenix的两个jar包(core和client)到hbase的所有服务端的相关目录下(hbase的lib目录)
[root@qianfeng01 phoenix]
[root@qianfeng01 phoenix]
[root@qianfeng01 phoenix]
3)配置三台hbase的hbase-site.xml文件
<property>
<name>phoenix.schema.isNamespaceMappingEnabled</name>
<value>true</value>
</property>
<property>
<name>phoenix.schema.mapSystemTablesToNamespace</name>
<value>true</value>
</property>
<property>
<name>hbase.table.sanity.checks</name>
<value>false</value>
</property>
4)拷贝hbase的hbase-site.xml到phoenix的bin目录下,覆盖自带的文件
[root@qianfeng01 phoenix]
2.3 启动操作
1. 先启动hdfs和zookeeper (phoenix是通过zookeeper连接hbase)
2. 再启动hbase(注意:如果在配置phoenix前已经启动了hbase,需要重启),(hbase里的新配置会跟着生效)
3. 启动phoenix客户端
[root@qianfeng01 phoenix]
可以使用help查看常用指令,也可以使用!table查看是否有四张系统表。
注意:在启动时可能报以下错误
Traceback (most recent call last):
File "./sqlline.py", line 27, in <module>
import argparse
<font color=red>ImportError: No module named argparse</font>
解决办法:
在安装phoenix的服务器上安装该模块。
[root@qianfeng01 phoenix]
0: jdbc:phoenix:qianfeng01:2181> !tables
2.4 常用命令
help: 查看所有指令的帮助信息
!table | !tables 查看所有的表
!describe :查看的表的描述信息
!index: 查询表的所有索引信息
使用 !history可以查看执行的历史SQL
使用 !dbinfo 可以查看Phoenix所有的属性配置
三、Phoenix的应用
phoenix支持的数据类型
tinyint
smallint
integer
bigint
float
double
boolean
varchar
char
time
date
timestamp
3.1 Phoenix的四种连接方式
3.1.1 命令行连接
就是使用sqlline.py脚本直接连接phoenix.
语法如下:
sqlline.py [zkServer:port]
解析:zkServer 指的是zookeeper的服务端的主机名或者是ip地址
port:是zookeeper服务端的端口号,2181
[root@qianfeng01 ~]
或者
[root@qianfeng01 ~]
连接后,可以建表,可以进行增删改查操作
建表:
create table t1(id integer primary key,name varchar(1));
select * from system.catalog;
3.1.2 批处理执行脚本
需要使用psql.py批处理脚本来执行sql脚本
1)创建一个建表语句的脚本
首先创建createtable.sql文件,里面添加l两个建表语句,表名分别是us_population和ak_population
[root@qianfeng01 phoenix]
CREATE TABLE IF NOT EXISTS us_population (
state CHAR(2) NOT NULL,
city VARCHAR NOT NULL,
population BIGINT
CONSTRAINT my_pk PRIMARY KEY (state, city)
);
CREATE TABLE IF NOT EXISTS ak_population (
state CHAR(2) NOT NULL,
city VARCHAR NOT NULL,
population BIGINT
CONSTRAINT my_pk PRIMARY KEY (state, city)
);
2)维护一个us_population表的数据文件us_population.csv
[root@qianfeng01 phoenix]
NY,New York,8143197
CA,Los Angeles,3844829
IL,Chicago,2842518
TX,Houston,2016582
PA,Philadelphia,1463281
AZ,Phoenix,1461575
TX,San Antonio,1256509
CA,San Diego,1255540
TX,Dallas,1213825
CA,San Jose,912332
3)维护一个ak_population表的数据文件ak.csv
[root@qianfeng01 phoenix]# vi ./sql/ak.csv
AK,kenai,450283
AK,haines,370283
AK,fairbanks,390283
4)使用psql.py来运行脚本
执行命令为:psql.py [zkserver:port] filepath……
[root@qianfeng01 phoenix]
[root@qianfeng01 phoenix]
java.lang.IllegalArgumentException: Table AK not found
[root@qianfeng01 phoenix]
[root@qianfeng01 phoenix]
select * from us_population;
select * from ak_population;
小贴士:
1、通过Phoenix建的表都会自动转成大写,如果需要使用小写的表,请使用create table "tablename"
2、安装了Phoenix之后,系统会自动生成四张系统表
3、在Phoenix中创建的表同时会在HBase中创建一张表与之对应,并且需要使用psql.py脚本加载数据
4、能将建表语句写入脚本,那么一定可以将查询语句写入脚本
3.1.3 使用jdbcAPI连接
1)配置pom.xml
<dependencies>
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
<version>4.13.1-HBase-1.2</version>
</dependency>
</dependencies>
2)编写代码(回顾jdbc的连接步骤)
1. 加载驱动
phoenix的驱动类名: org.apache.phoenix.jdbc.PhoenixDriver
2. 获取连接对象:
Properties pro = new Properties();
pro.setProperty("phoenix.schema.isNamespaceMappingEnabled","true");
Connection conn = DriverManager.getConnection("jdbc:phoenix:qianfeng01,qianfeng02,qianfeng03:2181",Properties prop)
3. 获取预编译执行对象
4. 发送sql语句,获取结果集
5. 处理结果集
6. 关闭连接
3.1.4 使用第三方客户端连接
忽略,参考文档
3.2 Phoenix的增删改查
3.2.1 表的DDL
phoenix的建表语句,必须要有一个主键约束,表名会默认变大写,如果想要小写的表名,需要加双引号。
create table student(
id integer primary key,
name varchar(20),
age integer,
salary double
);
create table teacher(
id integer not null,
name varchar(20) not null,
age integer,
salary double,
constraint pk_id_name primary key(id,name)
)
drop table [if exists] student1;
语法:alter table tableName add colName type;
注意事项:
(1)建表语句必须有主键约束,hbase会将带有主键约束的字段映射成rowkey字段
(2)如果是联合主键,那么字段后面要有非空约束。
(3)如果不指定schame,会将表映射到hbase的default命名空间下
3.2.2 表的插入
两种方式:
第一种:可以使用psql.py批处理脚本进行加载数据
第二种:可以在phoenix的命令行上使用以下方式来插入数据
phoenix的插入关键语句是 upsert into 或者upsert into……. select ………….
案例演示:
upsert into student values(1001,'zhangsan',23,1000.0);
upsert into student (id,name,age)values(1002,'lisi',24);
upsert into student (id,name,age,salary)values(1003,'wangwu',25,1100.0);
upsert into student (id,name,age,salary)values(1004,'zhaoliu',25,1100.0);
案例演示:要插入的数据来源于另外一张表
create table student1(
id integer primary key,
name varchar(20),
age integer,
salary double
);
upsert into student1 select * from student;
upsert into student1(id,name,age) select id,name,age from student where id>1002;
注意事项:
主键约束的字段一定要有值。
多次插入操作,如果主键字段的值相同,其实是hbase的覆盖操作。
3.2.3 表的数据修改
因为phoenix是在建立hbase之上的,所以phoenix的修改就是upsert into 对应hbase的插入和修改都是put.
案例演示:修改id为1003的姓名为wangwu1,年龄为20
upsert into student1 (id,name,age) values(1003,'wangwu1',20);
3.2.4 表的查询操作
1. 基本查询语法与mysql一致。
2. 支持where子句
3. 支持group by 子句
4. 支持having 子句
5. 支持order by子句
6. 支持limit子句,但是只能有一个参数,表示从第一条查询n条。
7. 支持[not]in、like
8. 支持union all,不支持去重。
9. 支持子查询(可以在from中,where中) 在hiving中使用比较符号语法没有错误,但是条件不起作用。
10. 支持join连接
3.2.5 表的数据删除
使用delete关键字,和mysql语法一致。
3.3 Phoenix的Schema
3.3.1 说明
在phoenix4.8版本以后,引入了Schema概念,映射的是Hbase的namespace. 当然如果想要生效,那么必须在hbase框架和phoenix框架中的hbase-site.xml中配置以下两个属性:
phoenix.schema.isNamespaceMappingEnabled = true
hoenix.schema.mapSystemTablesToNamespace = true
3.3.2 schema的应用
-- 创建一个schema
create schema schemaName <--- schemaName,要么加双引号,要么不加,不加会自动转为大写。
create schema "ns2"
create schema ns2 ns2和“ns2”是两个schema,在hbase中对应两个namespace,也证明了hbase中的标识符,比如表名,namespace的名字,都是区分大小写。
-- 在schema下创建表: 在ns2下创建表名为小写的s1的表。
create table ns2."s1"(
id integer primary key,
name varchar(20)
);
create table ns2.s1(
id integer primary key,
name varchar(20)
);
create table "ns2".S1(
id integer primary key,
name varchar(20)
);
create table "ns2"."s1"(
id integer primary key,
name varchar(20)
);
注意:如果没有指定列族名,那么在hbase中对应的列族名为0. 建表时可以指定列族名
create table "ns2".s2(
id integer primary key,
base.name varchar(20)
);
upsert into "ns2".s2 values(1001,'zhangsan');
create table "ns2"."s2"(
id integer primary key,
"base".name varchar(20)
);
upsert into "ns2"."s2" values(1001,'zhangsan');
create schema "ns2";
create table "ns2"."s3"(
id integer primary key,
"base".name varchar(20),
"base"."age" INTEGER,
"f1"."province" varchar(20),
"f1"."city" varchar(20)
)
column_encoded_bytes=0;
upsert into "ns2"."s3" values(1001,'zhangsan',23,'guangdong','深圳');
注意:建表时带上column_encoded_bytes=0,在hbase中可以将key解析成字符串。
以上操作都是先在phoenix上创建schema,table。会自动映射到hbase中的namespace以及table。
3.3.3 表的映射
指先在hbase中创建的表,Phoenix中是看不到的,如果想要在phoenix看到,那么必须做映射关系操作。
如何映射表???????????
在phoenix中创建一张表
(1)表名必须相同,如果有命名空间,那么在phoenix中必须要有schema与之映射
(2)表中必须要有主键,rowkey会自动与主键字段进行映射,主键字段名可以是row,也可以是其他名称
(3)表的列名前必须要有列族名与hbase的列族名一致。
(4)字段的类型,建议使用varcharl。
(5)高版本虽然可以不加此属性column_encoded_bytes=0,但是建议在做映射时,要加上。
drop table "mydb"."student";
create table "mydb"."student"(
id varchar(10) primary key,
"f1"."name" varchar(8),
"f1"."age" integer,
"f1"."gender" varchar(10),
"f1"."birth" varchar(20),
"f3"."province" varchar(20),
"f3"."city" varchar(20)
)
column_encoded_bytes=0;
|