预分区
每一个region维护着startRow与endRowKey,如果加入的数据符合某个region维护的rowKey范围,则该数据交给这个region维护。那么依照这个原则,我们可以将数据所要投放的分区提前大致的规划好,以提高HBase性能。
1.手动设定预分区
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创建预分区
package com.gm.hbase;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
/**
* @author Gm
* @create 2021-02-01 16:29
*/
public class HBaseConnect {
public static void main(String[] args) throws IOException {
// 1.获取配置类
Configuration conf = HBaseConfiguration.create();
// 2.给配置类添加配置
conf.set("hbase.zookeeper.quorum","hadoop102,hadoop103,hadoop104");
// 3.获取连接
Connection connection = ConnectionFactory.createConnection(conf);
// 4.获取admin
Admin admin = connection.getAdmin();
// 5.获取descriptor的builder
TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(TableName.valueOf("bigdata", "staff4"));
// 6. 添加列族
builder.setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("info")).build());
// 7.创建对应的切分
byte[][] splits = new byte[3][];
splits[0] = Bytes.toBytes("aaa");
splits[1] = Bytes.toBytes("bbb");
splits[2] = Bytes.toBytes("ccc");
// 8.创建表
admin.createTable(builder.build(),splits);
// 9.关闭资源
admin.close();
connection.close();
}
}
RowKey设计
一条数据的唯一标识就是rowkey,那么这条数据存储与那个分区,取决于rowkey处于哪一个预分区的区间内,设计rowkey的主要目的,就是让数据均匀的分布于所有的region中,在一定程度上方式数据倾斜。常用的设计方案如下
**1.生成随机数、hash、散列值**
在做此操作之前,一般我们会选择从数据集中抽取样本,来决定什么样的rowKey来Hash后作为每个分区的临界值。
**2.字符串反转**
> 20170524000001转成10000042507102
> 20170524000002转成20000042507102
**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,写请求较多的情况下,可适当调大