目录
一、phoenix的简介
Phoenix是HBase的开源SQL皮肤。可以使用标准JDBC API代替HBase客户端API来创建表,插入数据和查询HBase数据。
1)容易集成:如Spark,Hive,Pig,Flume和Map Reduce;
2)操作简单:DML命令以及通过DDL命令创建和操作表和版本化增量更改;
3)支持HBase二级索引创建。
phoenix是构建的Hbase之上的,使用标准的SQL操作Hbase,可以做联机事务处理,拥有低延迟的特性。phoenix会把SQL编译成一系列的Hbase的scan操作,然后把scan结果生成标准的JDBC结果集,其底层由于使用了Hbase的API,协处理器,过滤器,处理千万级行的数据也只用毫秒或秒级就搞定。支持有:SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY等操作。
此段原文链接:https://blog.csdn.net/nickta/article/details/79685534
二、phoenix的安装与基本操作
下载地址:Overview | Apache Phoenix
1.解压并安装
2.将server包拷贝到各个节点的hbase/lib
[example@hadoop102 phoenix]$ cp /opt/module/phoenix/phoenix-5.0.0-HBase-2.0-server.jar /opt/module/hbase/lib/
分发xsync /opt/module/hbase/lib/phoenix-5.0.0-HBase-2.0-server.jar
3.配置环境变量并重启hbase
#phoenix
export PHOENIX_HOME=/opt/module/phoenix
export PHOENIX_CLASSPATH=$PHOENIX_HOME
export PATH=$PATH:$PHOENIX_HOME/bin
4.连接phoenix
[example@hadoop101 phoenix]$ /opt/module/phoenix/bin/sqlline.py hadoop102,hadoop103,hadoop104:2181
Phoenix Shell操作
显示所有表
!tables或!table
创建表
CREATE TABLE IF NOT EXISTS student(
id VARCHAR primary key, --直接指明了RowKey
name VARCHAR,
addr VARCHAR);
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)); --指明多个列作为RowKey
注:Phoenix中建表,会在HBase中创建一张对应的表。为了减少数据对磁盘空间的占用,Phoenix默认会对HBase中的列名做编码处理。具体规则可参考官网链接:https://phoenix.apache.org/columnencoding.html,若不想对列名编码,可在建表语句末尾加上COLUMN_ENCODED_BYTES = 0;
插入数据
upsert into student values('1001','KOBE','LA');
查询
select * from student;
select * from student where id='1001';
删除
delete from student where id='1001';
drop table student;
表的映射
默认情况下, HBase中已存在的表,通过Phoenix是不可见的。如果要在Phoenix中操作HBase中已存在的表,可以在Phoenix中进行表的映射。映射方式有两种:视图映射和表映射。
操作:
在Hbase中创建表
create 'test','info1','info2'
put 'test','1001','info1:name','ls'
put 'test','1001','info2:address','JZ'
视图映射
Phoenix创建的视图是只读的,所以只能用来做查询,无法通过视图对数据进行修改等操作。在phoenix中创建关联test表的视图
create view "test"(id varchar primary key,"info1"."name" varchar, "info2"."address" varchar);
select * from "test";
drop view "test"; //删除视图表
表映射
在Pheonix创建表去映射HBase中已经存在的表,是可以修改删除HBase中已经存在的数据的。而且,删除Phoenix中的表,那么HBase中被映射的表也会被删除。
注:进行表映射时,不能使用列名编码,需将column_encoded_bytes设为0。
upsert into test values('1002','zz','SH');
select * from "test";
数字类型
HBase中的数字,底层存储为补码,而Phoenix中的数字,底层存储为在补码的基础上,将符号位反转。故当在Phoenix中建表去映射HBase中已存在的表,当HBase中有数字类型的字段时,会出现解析错误的现象。
Hbase演示:
create 'test_number','info'
put 'test_number','1001','info:number',Bytes.toBytes(1000)
scan 'test_number',{COLUMNS => 'info:number:toLong'}
phoenix演示:
create view "test_number"(id varchar primary key,"info"."number" bigint);
select * from "test_number";
解决:
Phoenix种提供了unsigned_int,unsigned_long等无符号类型,其对数字的编码解码方式和HBase是相同的,如果无需考虑负数,那在Phoenix中建表时采用无符号类型是最合适的选择。
phoenix演示:
drop view "test_number";
create view "test_number"(id varchar primary key,"info"."number" unsigned_long);
select * from "test_number";
JDBC操作
胖客户端与轻客户端的区别:Phoenix客户端进化之由重到轻-阿里云开发者社区
胖客户端
<dependencies>
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
<version>5.0.0-HBase-2.0</version>
<exclusions>
<exclusion>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.1-b06</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.8.4</version>
</dependency>
</dependencies>
public class TestThickClient {
public static void main(String[] args) throws SQLException {
// 1.添加链接
String url = "jdbc:phoenix:hadoop102,hadoop103,hadoop104:2181";
// 2.创建配置
Properties properties = new Properties();
// 3.添加配置
// 需要客户端服务端参数保存一致
// properties.put("phoenix.schema.isNamespaceMappingEnabled", "true");
// 4.获取连接
Connection connection = DriverManager.getConnection(url, properties);
// 5.编译SQL语句
PreparedStatement preparedStatement = connection.prepareStatement("select * from student");
// 6.执行语句
ResultSet resultSet = preparedStatement.executeQuery();
// 7.输出结果
while (resultSet.next()){
System.out.println(resultSet.getString(1) + ":" + resultSet.getString(2) + ":" + resultSet.getString(3));
}
// 8.关闭资源
connection.close();
}
}
瘦客户端
启动query server
[example@hadoop102 ~]$ queryserver.py start
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.phoenix/phoenix-queryserver-client -->
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-queryserver-client</artifactId>
<version>5.0.0-HBase-2.0</version>
</dependency>
</dependencies>
public class TestThinClient {
public static void main(String[] args) throws SQLException {
// 1. 直接从瘦客户端获取链接
String hadoop102 = ThinClientUtil.getConnectionUrl("hadoop102", 8765);
// 2. 获取连接
Connection connection = DriverManager.getConnection(hadoop102);
// 3.编译SQL语句
PreparedStatement preparedStatement = connection.prepareStatement("select * from student");
// 4.执行语句
ResultSet resultSet = preparedStatement.executeQuery();
// 5.输出结果
while (resultSet.next()){
System.out.println(resultSet.getString(1) + ":" + resultSet.getString(2) + ":" + resultSet.getString(3));
}
// 6.关闭资源
connection.close();
}
}
Phoenix二级索引
全局索引
Global Index是默认的索引格式,创建全局索引时,会在HBase中建立一张新表。也就是说索引数据和数据表是存放在不同的表中的,因此全局索引适用于多读少写的业务场景。
写数据的时候会消耗大量开销,因为索引表也要更新,而索引表是分布在不同的数据节点上的,跨节点的数据传输带来了较大的性能消耗。
在读数据的时候Phoenix会选择索引表来降低查询消耗的时间。
创建单个字段的全局索引
CREATE INDEX my_index ON my_table (my_col);
create index MYIN2 on "test" ("info1"."name");
包含索引
创建携带其他字段的全局索引
CREATE INDEX my_index ON my_table (v1) INCLUDE (v2);
本地索引(local index)
Local Index适用于写操作频繁的场景。
索引数据和数据表的数据是存放在同一张表中(且是同一个Region),避免了在写操作的时候往不同服务器的索引表中写索引带来的额外开销。