Apache phoenix让hadoop支持oltp和业务操作分析
一、安装
1、下载
2、上传到服务器
3、解压
[root@hadoop001 software]# tar xzvf phoenix-hbase-2.4-5.1.2-bin.tar.gz -C ../servers/
4、修改HBase配置文件
<!--支持hbase的命名空间映射-->
<property>
<name>phoenix.schema.isNamespaceMappingEnabled</name>
<value>true</value>
</property>
<property>
<name>hbase.table.sanity.checks</name>
<value>false</value>
</property>
<property>
<name>hbase.coprocessor.abortonerror</name>
<value>false</value>
</property>
5、复制依赖包
复制phoenix的所有的jar包到master和worker的hbase的lib文件夹
Master底下
Worker底下
[root@hadoop001 phoenix-hbase-2.4-5.1.2-bin]# scp phoenix-server-hbase-2.4-5.1.2.jar hadoop002:/export/servers/hbase-2.4.10/lib/
[root@hadoop001 phoenix-hbase-2.4-5.1.2-bin]# scp phoenix-server-hbase-2.4-5.1.2.jar hadoop003:/export/servers/hbase-2.4.10/lib/
复制phoenix的客户端的jar包到phoenix客户端也就是hadoop001的phoenix的bin文件夹
6、分发HBase配置文件
[root@hadoop001 hbase-2.4.10]# scp conf/hbase-site.xml hadoop002:$PWD/conf
[root@hadoop001 hbase-2.4.10]# scp conf/hbase-site.xml hadoop003:$PWD/conf
7、将配置好的hbase-site.xml文件复制到phoenix的客户端,也就是hadoop001的phoenix的bin目录
[root@hadoop001 bin]# cp /export/servers/hbase-2.4.10/conf/hbase-site.xml .
8、重启HBase
启动phoenix客户端
[root@hadoop001 phoenix-hbase-2.4-5.1.2-bin]# bin/sqlline.py hadoop001:2181
二、phoenix的使用
1、需求
使用之前的订单数据,使用phoenix来创建表
2、创建表
启动客户端
[root@hadoop001 phoenix-hbase-2.4-5.1.2-bin]# bin/sqlline.py hadoop001:2181
语法:
create table if not exists 表名(
rowkey名称 类型 primary key,
列簇.列名 类型,
……
)
3、查看表
语法:
!desc ORDER_DETATL
4、删除表
语法:
drop table if exists 表名;
5、大小写问题
如果在使用列簇、列名时没有添加双引号,会自动转换为大写
如果要将列名转换为小写,需要使用双引号
6、插入数据
语法:
upsert into ORDER_DETATL values('000001','已提交',3050,1,'494419','2020-4-25 12:09:30','手机');
7、查询数据
select * from ORDER_DETATL;
8、更新数据
upsert into ORDER_DETATL(ID,C1.STATUS) values('000001','已付款');
如果
9、数据的删除
delete from ORDER_DETATL1 where ID='000002';
三、HBase的命名空间
1、简介
类似于mysql的数据库,对数据进行分类存放。按照业务域来划分类别,这些不同放入业务域就叫做命名空间(namespace)。
2、创建命名空间
语法:create_namespace 命名空间名
3、查看命名空间列表
语法:list_namespace
查看具体命名空间
语法:describe_namespace 命名空间名
4、删除命名空间
语法:drop_namespace 命名空间名
注意:删除命名空间时,在该命名空间下必须没有表,否则无法删除。
5、在指定命名空间下创建表
语法:
create "命名空间名:表名","列簇名"
注意:使用带有命名空间的表,使用冒号将命名空间与表名连接在一起
6、添加数据到命名空间
语法:
put "命名空间名:表名","rowkey","列簇:列名","values"
四、列簇设计
HBase列簇的数量应该是越少越好
- 两个及以上的列簇,hbase的性能反而并不是很好
- 一个列簇存储的数据达到flush的阈值时,表中所有的列簇将同时进行flush操作
- 这将带来不必要的I/O开销,列簇越多,对性能的影响越大
一般情况下,只设计一个列簇
五、版本设计
版本数一一般设计为1
一般情况下,如果对数据不做修改,只保留一个版本,可以节省大量的存储空间
六、数据压缩
1、压缩算法
hbase默认创建的表是不进行数据压缩的,进行数据压缩可以节省大量的存储空间,hbase可以使用多种数据压缩编码,包括LZO、SNAPPY、GZIP。
压缩算法 | 压缩后占比 | 压缩 | 解压缩 |
GZIP | 13.4% | 21MB/s | 118MB/s |
LZO | 20.5% | 135MB/s | 410MB/s |
Zippy/Snappy | 22.2% | 172MB/s | 409MB/S |
2、查看表的压缩算法
hbase创建的表默认是没有数据压缩的
3、设置数据压缩方法
1)创建新表时
语法:
create "命名空间名:表名",{NAME => '列簇名', COMPRESSION => '压缩算法名'}
示例:
create "shop:orders",{NAME => 'C1', COMPRESSION => 'GZ'}
2)修改已有表
语法:
alter "命名空间名:表名",{NAME => '列簇名', COMPRESSION => '压缩算法名'}
示例
alter "shop:goods",{NAME => 'C1', COMPRESSION => 'GZ'}
七、RROEKEY设计原则
1、避免使用递增行键/时序的数据
如果rowkey设计的都是按照顺序递增(例如:时间戳),这样当有很多的数据写入时,负载都在一台机器上。应该尽量将写入的数据均衡到各个RegionServer上。
2、避免rowkey和列的长度过大
在hbase中,要访问一个值,需要rowkey、列簇和列名,如果这些太长,就会占用较大的内存。
rowkey的最大长度是64kb,建议越短越好
3、使用long等类型比String类型更节省空间
long类型为8个字节,可以保存非常大的无符号数据,例如:174489340923423422424。如果使用字符串保存的话,是按照一个字符一个字节的方式,需要3倍多的存储空间。
4、rowkey唯一性
设计rowkey时,必须保证它的唯一性。
如果不唯一,因为hbase采用key-value的存储方式,若向hbase的一张表中插入相同rowkey的数据,则原来的数据会被新的数据覆盖
5、避免数据热点
1)热点
是指大量的客户端直接访问(可能是读,也可能是写)集群的一个或者几个节点,可能会使得某个节点超出承受能力,出现宕机或者不可用的情况,导致整个集群性能的下降。
2)预分区
默认情况下,一个hbase表只有一个分区(region),被托管在一个RegionServer中
3)Start key和end key
每个region有两个重要的属性:start key和end key,标识这个region维护的rowkey的范围。如果只有一个region,这它们都为空,没有边界。所有的数据都会存放在这个region中。但数据很大的时候,会将region通过去一个mid key来分成两个region。
4)预分区的个数
预分区的个数=节点的倍数,如果有三个节点,则预分区的个数为6。
默认region的大小为10G,假如进行预估接下来的一年时间数据的大小为10T,则需要的预分区数=10*1000G/10G=1000个region。
5)rowkey避免数据热点设计
反转策略
将rowkey翻转,或者直接将尾部的字符串提前到rowkey的开头
优点:实现简单
缺点:可以使得rowkey呈现一定的随机性,但是牺牲了rowkey的有序性,利于get操作,
不利于scan操作。
加盐策略
在原来的rowkey的前面加上固定长度的随机数,这个随机数就叫做盐,这样使得rowkey具
有随机性
优点:rowkey的随机性能保障数据在所有的regionserver之间的负载均衡
缺点:因为添加的是随机数,基于原来的rowkey查询时无法知道随机数是什么,会影响查
询速度,不适合数据的读取
八、设置预分区
1、指定startkey和endkey来分区
1)创建预分区
语法:
create_namespace "test"
create "test:t1",'C1',SPLITS=>['10','20','30','40']
2)hbase的webui查看分区的占用情况
2、指定分区的数量、分区策略
1)创建预分区
语法:
create"test:t2","C1",{NUMREGIONS=>6,SPLITALGO=>'HexStringSplit'}
2)hbase和webui查看分区的占用情况
3)分区数量
一般按照数据量来预估或者根据节点数的倍数来设定 。
4)分区策略
HexStringSplit:rowkey是采用十六进制字符串作为前缀
DecimalStringSplit:rowkey采用十进制数字字符串作为前缀
create"test:t3","C1",{NUMREGIONS=>6,SPLITALGO=>'DecimalStringSplit'}
UniformStringSplit:rowkey的前缀是随机的
create"test:t4","C1",{NUMREGIONS=>6,SPLITALGO=>'UniformSplit'}
九、Phoenix视图
1、创建视图
2、查询数据
语法:select * from "命名空间名"."表名";
十、二级索引
一般情况下,Hbase会根据rowkey建立索引,来提供查询的速度,这样的索引叫做一级索引。如果根据name进行查询,因为没有根据name建立索引,所以查询效率比较低,这是可以给name来创建二级索引
1、索引 分类
全局索引
本地索引
覆盖索引
函数索引
1)全局索引
- 全局索引适用于读多写少的业务
- 全局索引主要的负载发生在写入操作时,比如upsert、delete,Phoenix会拦截数据表的更新,构建索引更新,开销比较大
- 读取时,Phoenix会选择最快的能够查询出数据的索引。
- 全局索引一般要跟覆盖索引搭配使用
语法:
create index索引名称on表名(列名1,列名2……);
举例:
create index idxname on ORDER_DETATL1 (CATEGORY);
Phoenix中的索引,其实底层还是Hbase的表结构,这些索引表是专门用来加快查询速度。
2)本地索引
- 本地索引适合写操作频繁的场景
- 在本地索引中,索引数据和业务表数据存储在同一个服务器上,加快写入的速度
- 本地索引的数据是保存在一个影子列簇中
创建语法:
create local index索引名称on表名(列名1,列名2……);
create local index id2xname on ORDER_DETATL1 (CATEGORY);
3)覆盖索引
可以不需要在找到索引条目后返回到主表中,可以将关心的数据捆绑在索引行中,从而节省
了读取的时间开销。
创建语法:
create index索引名称on表名(列名1,列名2……) include(列名3);
create index idxcombo on ORDER_DETATL1 (CATEGORY,STATUS,PAY_MONEY) include(USER_ID);
4)函数索引
适用于高版本的phoenix,可以基于任意表达式(函数)创建索引
语法
create index索引名称on表名(函数名(列名1),列名2……);
2、创建索引
create index idxsuerid on ORDER_DETATL1(C1.USER_ID) include(ID,C1.PAY_MONEY);
3、根据索引查询数据
select USER_ID,ID,PAY_MONEY from ORDER_DETATL1 where USER_ID=" 2234456";
4、删除索引
drop index索引名on表名
drop index IDXCOMBO on ORDER_DETATL1;
5、查看索引