HBase详解(05) - HBase优化 整合Phoenix 集成Hive
HBase详解(05) - HBase优化 整合Phoenix 集成Hive
HBase优化
预分区
每一个region维护着startRow与endRowKey,如果加入的数据符合某个region维护的rowKey范围,则该数据交给这个region维护。那么依照这个原则,可以将数据所要投放的分区提前大致的规划好,以提高HBase性能。
1.手动设定预分区
hbase> create 'staff1','info',SPLITS => ['1000','2000','3000','4000']
2.生成16进制序列预分区
create 'staff2','info',{NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}
3.按照文件中设置的规则预分区
创建splits.txt文件内容如下:
aaaa bbbb cccc dddd |
然后执行:
create 'staff3','info',SPLITS_FILE => 'splits.txt'
4.使用JavaAPI创建预分区
//自定义算法,产生一系列Hash散列值存储在二维数组中 byte[][] splitKeys = 某个散列值函数 //创建HbaseAdmin实例 HBaseAdmin hAdmin = new HBaseAdmin(HbaseConfiguration.create()); //创建HTableDescriptor实例 HTableDescriptor tableDesc = new HTableDescriptor(tableName); //通过HTableDescriptor实例和散列值二维数组创建带有预分区的Hbase表 hAdmin.createTable(tableDesc, splitKeys); |
RowKey设计
一条数据的唯一标识就是rowkey,那么这条数据存储于哪个分区,取决于rowkey处于哪个一个预分区的区间内,设计rowkey的主要目的 ,就是让数据均匀的分布于所有的region中,在一定程度上防止数据倾斜。rowkey常用的设计方案:
- 生成随机数、hash、散列值
一条数据的唯一标识就是rowkey,那么这条数据存储于哪个分区,取决于rowkey处于哪个一个预分区的区间内,设计rowkey的主要目的 ,就是让数据均匀的分布于所有的region中,在一定程度上防止数据倾斜。rowkey常用的设计方案:
比如:
原本rowKey为1001的,SHA1后变成:dd01903921ea24941c26a48f2cec24e0bb0e8cc7
原本rowKey为3001的,SHA1后变成:49042c54de64a1e9bf0b33e00245660ef92dc7bd
原本rowKey为5001的,SHA1后变成:7b61dec07e02c188790670af43e717f0f46e8913
在做此操作之前,一般会选择从数据集中抽取样本,来决定什么样的rowKey来Hash后作为每个分区的临界值。
2.字符串反转
20170524000001转成10000042507102 20170524000002转成20000042507102 |
这样也可以在一定程度上散列逐步put进来的数据。
3.字符串拼接
20170524000001_a12e 20170524000001_93i7 |
内存优化
HBase操作过程中需要大量的内存开销,毕竟Table是可以缓存在内存中的,但是不建议分配非常大的堆内存,因为GC过程持续太久会导致RegionServer处于长期不可用状态,一般16~36G内存就可以了,如果因为框架占用内存过高导致系统内存不足,框架一样会被系统服务拖死。
基础优化
1.Zookeeper会话超时时间
hbase-site.xml
属性:zookeeper.session.timeout
解释:默认值为90000毫秒(90s)。当某个RegionServer挂掉,90s之后Master才能察觉到。可适当减小此值,以加快Master响应,可调整至60000毫秒。
2.设置RPC监听数量
hbase-site.xml
属性:hbase.regionserver.handler.count
解释:默认值为30,用于指定RPC监听的数量,可以根据客户端的请求数进行调整,读写请求较多时,增加此值。
3.手动控制Major Compaction
hbase-site.xml
属性:hbase.hregion.majorcompaction
解释:默认值:604800000秒(7天), Major Compaction的周期,若关闭自动Major Compaction,可将其设为0
4.优化HStore文件大小
hbase-site.xml
属性:hbase.hregion.max.filesize
解释:默认值10737418240(10GB),如果需要运行HBase的MR任务,可以减小此值,因为一个region对应一个map任务,如果单个region过大,会导致map任务执行时间过长。该值的意思就是,如果HFile的大小达到这个数值,则这个region会被切分为两个Hfile。
5.优化HBase客户端缓存
hbase-site.xml
属性:hbase.client.write.buffer
解释:默认值2097152bytes(2M)用于指定HBase客户端缓存,增大该值可以减少RPC调用次数,但是会消耗更多内存,反之则反之。一般我们需要设定一定的缓存大小,以达到减少RPC次数的目的。
6.指定scan.next扫描HBase所获取的行数
hbase-site.xml
属性:hbase.client.scanner.caching
解释:用于指定scan.next方法获取的默认行数,值越大,消耗内存越大。
7.BlockCache占用RegionServer堆内存的比例
hbase-site.xml
属性:hfile.block.cache.size
解释:默认0.4,读请求比较多的情况下,可适当调大
8.MemStore占用RegionServer堆内存的比例
hbase-site.xml
属性:hbase.regionserver.global.memstore.size
解释:默认0.4,写请求较多的情况下,可适当调大
HBase整合Phoenix
Phoenix简介
Phoenix定义:Phoenix是HBase的开源SQL皮肤。可以使用标准JDBC API代替HBase客户端API来创建表,插入数据和查询HBase数据。
Phoenix特点
1)容易集成:如Spark,Hive,Pig,Flume和Map Reduce;
2)操作简单:DML命令以及通过DDL命令创建和操作表和版本化增量更改;
3)支持HBase二级索引创建。
Phoenix架构
Phoenix 安装
1.下载
官网地址:http://phoenix.apache.org/
下载地址:https://downloads.apache.org/phoenix/
[hadoop@hadoop102 software]$ tar -zxvf apache-phoenix-5.0.0-HBase-2.0-bin.tar.gz -C /opt/module/
[hadoop@hadoop102 software]$ cd /opt/module/
[hadoop@hadoop102 module]$ mv apache-phoenix-5.0.0-HBase-2.0-bin/ phoenix
2)复制server包并拷贝到各个HBase节点的hbase/lib
export PHOENIX_HOME=/opt/module/phoenix
export PHOENIX_CLASSPATH=$PHOENIX_HOME
export PATH=$PATH:$PHOENIX_HOME/bin
[hadoop@hadoop102 ~]$ stop-hbase.sh
[hadoop@hadoop102 ~]$ start-hbase.sh
[hadoop@hadoop102 ~]$ /opt/module/phoenix/bin/sqlline.py hadoop102,hadoop103,hadoop104:2181
Phoenix Shell操作
默认情况下,在phoenix中不能直接创建schema。需要将下面的参数添加到Hbase中conf目录下的hbase-site.xml和phoenix中bin目录下的 hbase-site.xml中
<name>phoenix.schema.isNamespaceMappingEnabled</name>
[hadoop@hadoop102 ~]$ vi /opt/module/hbase/conf/hbase-site.xml
[hadoop@hadoop102 conf]$ scp hbase-site.xml hadoop103:/opt/module/hbase/conf/
[hadoop@hadoop102 conf]$ scp hbase-site.xml hadoop104:/opt/module/hbase/conf/
[hadoop@hadoop102 ~]$ vi /opt/module/phoenix/bin/hbase-site.xml
/opt/module/phoenix/bin/sqlline.py hadoop102,hadoop103,hadoop104:2181
注意:在phoenix中,schema名,表名,字段名等会自动转换为大写,若要小写,使用双引号,如"student"。
CREATE TABLE IF NOT EXISTS student(
CREATE TABLE IF NOT EXISTS us_population (
CONSTRAINT my_pk PRIMARY KEY (state, city));
upsert into student values('1001','zhangsan','beijing');
select * from student where id='1001';
delete from student where id='1001';
默认情况下,直接在HBase中创建的表,通过Phoenix是查看不到的。如果要在Phoenix中操作直接在HBase中创建的表,则需要在Phoenix中进行表的映射。映射方式有两种:视图映射和表映射。
HBase 中test的表结构如下,两个列族info1、info2。
/opt/module/hbase/bin/hbase shell
hbase(main):001:0> create 'test','info1','info2'
Phoenix创建的视图是只读的,所以只能用来做查询,无法通过视图对源数据进行修改等操作。在phoenix中创建关联test表的视图
0: jdbc:phoenix:hadoop101,hadoop102,hadoop103> drop view "test";
使用Apache Phoenix创建对HBase的表映射,有两种方法:
(2)当HBase中已经存在表时,可以以类似创建视图的方式创建关联表,只需要将create view改为create table即可。
hbase(main):001:0> create 'person','info'
hbase(main):001:0> put 'person','1001', 'info:salary',Bytes.toBytes(123456)
注意: 如果要插入数字类型,需要通过Bytes.toBytes(123456)来实现。
create table "person"(id varchar primary key,"info"."salary" integer ) column_encoded_bytes=0;
在phoenix中创建表时使用无符号的数值类型. unsigned_long
create table "person"(id varchar primary key,"info"."salary" unsigned_long ) column_encoded_bytes=0;
Phoenix JDBC操作
[hadoop@hadoop102 ~]$ cd /opt/module/phoenix/
[hadoop@hadoop102 phoenix]$ bin/queryserver.py start
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-queryserver-client</artifactId>
<version>5.0.0-HBase-2.0</version>
import org.apache.phoenix.queryserver.client.ThinClientUtil;
public static void main(String[] args) throws SQLException {
String connectionUrl = ThinClientUtil.getConnectionUrl("hadoop102", 8765);
Connection connection = DriverManager.getConnection(connectionUrl);
PreparedStatement preparedStatement = connection.prepareStatement("select * from student3");
ResultSet resultSet = preparedStatement.executeQuery();
System.out.println(resultSet.getString(1) + "\t" + resultSet.getString(2));
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
<version>5.0.0-HBase-2.0</version>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
public static void main(String[] args) throws SQLException {
String url = "jdbc:phoenix:hadoop102,hadoop103,hadoop104:2181";
Properties props = new Properties();
props.put("phoenix.schema.isNamespaceMappingEnabled","true");
Connection connection = DriverManager.getConnection(url,props);
PreparedStatement ps = connection.prepareStatement("select * from student3");
ResultSet rs = ps.executeQuery();
System.out.println(rs.getString(1)+":" +rs.getString(2));
Phoenix二级索引
添加如下配置到HBase的HRegionserver节点的hbase-site.xml
<!-- phoenix regionserver 配置参数-->
<name>hbase.regionserver.wal.codec</name>
<value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
<name>hbase.region.server.rpc.scheduler.factory.class</name>
<value>org.apache.hadoop.hbase.ipc.PhoenixRpcSchedulerFactory</value>
<name>hbase.rpc.controllerfactory.class</name>
<value>org.apache.hadoop.hbase.ipc.controller.ServerRpcControllerFactory</value>
Global Index是默认的索引格式,创建全局索引时,会在HBase中建立一张新表。也就是说索引数据和数据表是存放在不同的表中的,因此全局索引适用于多读少写的业务场景。
写数据的时候会消耗大量开销,因为索引表也要更新,而索引表是分布在不同的数据节点上的,跨节点的数据传输带来了较大的性能消耗。
在读数据的时候Phoenix会选择索引表来降低查询消耗的时间。
CREATE INDEX my_index ON my_table (my_col);
如果想查询的字段不是索引字段的话索引表不会被使用,也就是说不会带来查询速度的提升。
CREATE INDEX my_index ON my_table (v1) INCLUDE (v2);
索引数据和数据表的数据是存放在同一张表中(且是同一个Region),避免了在写操作的时候往不同服务器的索引表中写索引带来的额外开销。
CREATE LOCAL INDEX my_index ON my_table (my_column);
与Hive的集成
HBase与Hive的对比
Hive的本质其实就相当于将HDFS中已经存储的文件在Mysql中做了一个双射关系,以方便使用HQL去管理查询。
Hive存储的数据依旧在DataNode上,编写的HQL语句终将是转换为MapReduce代码执行。
适用于单表非关系型数据的存储,不适合做关联查询,类似JOIN等操作。
数据持久化存储的体现形式是HFile,存放于DataNode中,被ResionServer以region的形式进行管理。
面对大量的企业数据,HBase可以直线单表大量数据的存储,同时提供了高效的数据访问速度。
HBase与Hive集成使用
在hive-site.xml中添加zookeeper的属性,如下:
<property> <name>hive.zookeeper.quorum</name> <value>hadoop102,hadoop103,hadoop104</value> </property>
<property> <name>hive.zookeeper.client.port</name> <value>2181</value> </property> |
目标:建立Hive表,关联HBase表,插入数据到Hive表的同时能够影响HBase表。
CREATE TABLE hive_hbase_emp_table(
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
TBLPROPERTIES ("hbase.table.name" = "hbase_emp_table");
提示:完成之后,可以分别进入Hive和HBase查看,都生成了对应的表
提示:不能将数据直接load进Hive所关联HBase的那张表中
row format delimited fields terminated by '\t';
hive> load data local inpath '/home/admin/softwares/data/emp.txt' into table emp;
4.通过insert命令将中间表中的数据导入到Hive关联Hbase的那张表中
hive> insert into table hive_hbase_emp_table select * from emp;
5.查看Hive以及关联的HBase表中是否已经成功的同步插入了数据
hive> select * from hive_hbase_emp_table;
CREATE EXTERNAL TABLE relevance_hbase_emp(
'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" =
":key,info:ename,info:job,info:mgr,info:hiredate,info:sal,info:comm,info:deptno")
TBLPROPERTIES ("hbase.table.name" = "hbase_emp_table");
本文作者:莲藕淹,转载请注明原文链接:https://www.cnblogs.com/meanshift/p/15834422.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY