HBase:NoSQL数据库(END-6.HBase的优化)

1.高可用(HA)

HA(high avaliable)的核心是避免单点故障!

在hbase中主要有两种进程:master,regionserver

regionserver通常是启动多个,在高并发的情况下及时处理客户端的请求!一旦其中的一个regionserver挂掉,master将挂掉regionserver负责的region重新分配给其他的regionserver!

唯一需要解决的就是master的故障

如果master故障了,不影响数据的读写,会影响建表,该表等操作

解决思路: 启动多个master,其中一个为active状态,其他为backup状态!当active状态的master挂掉后,可以让backup状态的master顶上!

操作: 将备用的master配置在 $HBASE_HOME/conf/backup-masters中即可!

  1. 在conf目录下创建backup-masters文件
[jaffe@hadoop102 HBase]$ touch conf/backup-masters
  1. 在backup-masters文件中配置高可用HMaster节点
[jaffe@hadoop102 HBase]$ echo hadoop103 > conf/backup-masters
  1. 将整个conf目录scp到其他节点
[jaffe@hadoop102 HBase]$ scp -r conf/ hadoop103:/opt/module/HBase/
[jaffe@hadoop102 HBase]$ scp -r conf/ hadoop104:/opt/module/HBase/
  1. 打开页面测试查看
    http://hadooo102:16010

2.预分区

2.1意义

每次在hbase中新创建一个表时,默认只有一个region!当向这个region写入大量的数据时,region的大小会增大!增大到一定程度,region会自动触发切分策略,进行自动切分!在自动切分时,通常是选择当前region所有rowkey的中间值,一分为二!

自动切分,在某些情况下可能造成切分后regioniserver依旧负载不均衡!

怎么解决: 在建表时,对数据进行抽样查询!在定义表时,提前对表进行预分区(提前划分region)

这样在建表后,就有多个region!数据在写入region时,就可以负载均衡!

2.2 实现

2.2.1 实现一

手动指定每个region的边界值

create 'staff1','info',SPLITS => ['1000','2000','3000','4000']

2.2.2 实现二

使用预分区算法,生成边界值。 只指定要生成的分区数,使用算法生成分区边界

create 'staff2','info',{NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}

此种做法,数据在插入到表中之前,需要对数据的rowkey使用16进制进行转换,转换后插入,才能负载均衡

示例:

@Test
    public void convertRowkey() throws IOException {

        String rowkey="abc";

        char[] chars = rowkey.toCharArray();

        String result="";

        for (char c : chars) {

            result+=Integer.toHexString(c);

        }

        System.out.println(result);

    }

2.2.3实现三

将边界值,写在文件中!在建表时,读取文件中的边界值,进行操作!

create 'staff3','partition3',SPLITS_FILE => 'splits.txt'

2.2.4 API实现

指定region的个数和起始终止边界,使用随机算法生成:

admin.createTable(hTableDescriptor, Bytes.toBytes("aaa"),Bytes.toBytes("bbb"),5);

regions的个数必须超过3!

自定义边界值

 byte [] [] splitKeys=new byte[4][] ;

        splitKeys[0]= Bytes.toBytes("aaaa");
        splitKeys[1]= Bytes.toBytes("bbbb");
        splitKeys[2]= Bytes.toBytes("cccc");
        splitKeys[3]= Bytes.toBytes("dddd");

        admin.createTable(hTableDescriptor,splitKeys);

3.Rowkey的设计

hbase的数据是key-value结构!因此一条数据的唯一标识就是rowkey!

region也是根据rowkey进行排序,根据rowkey进行切分!

rowkey设计的好,可以提供系统负载均衡的能力!

如何让regionserver负载均衡: 让数据可以基于rowkey排序后,均匀地分散到所有的region!防止数据倾斜!

如何实现:

①可以采取随机数,hash或散列运算,让rowkey足够散列

原本rowKey为1001的,SHA1后变成:dd01903921ea24941c26a48f2cec24e0bb0e8cc7

原本rowKey为3001的,SHA1后变成:49042c54de64a1e9bf0b33e00245660ef92dc7bd

原本rowKey为5001的,SHA1后变成:7b61dec07e02c188790670af43e717f0f46e8913

在做此操作之前,一般我们会选择从数据集中抽取样本,来决定什么样的rowKey来Hash
后作为每个分区的临界值。

②字符串反转

20170524000001转成10000042507102
20170524000002转成20000042507102
这样也可以在一定程度上散列逐步put进来的数据。

③字符串拼接

20170524000001_a12e
20170524000001_93i7

4.布隆过滤器

布隆是个人,发明布隆算法!基于布隆算法实现的组件称为布隆过滤器!

布隆过滤器的功能: 针对读(查询)的场景!

在查询时,如果使用了布隆过滤器,布隆过滤器可以快速高效的判断查询的元素是否在集合中存在!

只能判断要查询的元素在集群中是否一定不存在或可能存在!

布隆过滤器存在一定的误判: 布隆过滤器经过计算,判断元素在集合中可能存在,但是在真正扫描集合后,发现元素并不存在,这称为误判!

即便有误判,一般使用布隆过滤器,加速查询!

在hbase中,布隆过滤器在列族上配置!在hbase中布隆过滤器有两种配置:

ROW(默认)| ROWCOL

两种设置的区别在于,布隆过滤器在计算时,只使用rowkey作为参数进行运算,还是使用rowkey+col作为参数来运算!

举例: 有列族 info  info2
storefile1: (r1,info:age=20),(r2,info:age=20)
storefile2:  (r3,info2:age=20),(r4,info2:age=20)

使用的是ROW的布隆过滤器,在过滤时,只使用rowkey作为计算的参数!
get(r1),如果判断r1在storefile2中一定不存在,就无需扫描storefile2!

举例: 有列族 info  info2
storefile1: (r1,info:age=20),(r2,info:age=20)(r3,info:age=30)
storefile2:  (r3,info2:age=20),(r4,info2:age=20)

使用的是ROWCOL的布隆过滤器,在过滤时,只使用rowkey+col作为计算的参数!
get(r3,'info2'),如果判断r3-info2在storefile1中一定不存在,就无需扫描storefile1!

布隆过滤器一般只适用于get查询,scan的作用不大!

如果启动了布隆过滤器,占用额外的内存!布隆过滤器一般是在blockcache中!

5.内存优化

HBase操作过程中需要大量的内存开销,毕竟Table是可以缓存在内存中的,一般会分配整个可用内存的70%给HBase的Java堆。但是不建议分配非常大的堆内存,因为GC过程持续太久会导致RegionServer处于长期不可用状态,一般16~48G内存就可以了,如果因为框架占用内存过高导致系统内存不足,框架一样会被系统服务拖死

6.基础优化

6.1 允许在HDFS的文件中追加内容

hdfs-site.xml、HBase-site.xml
属性:dfs.support.append
解释:开启HDFS追加同步,可以优秀的配合HBase的数据同步和持久化。默认值为true。

6.2 优化DataNode允许的最大文件打开数

hdfs-site.xml
属性:dfs.datanode.max.transfer.threads
解释:HBase一般都会同一时间操作大量的文件,根据集群的数量和规模以及数据动作,设置为4096或者更高。默认值:4096

6.3 优化延迟高的数据操作的等待时间

hdfs-site.xml
属性:dfs.image.transfer.timeout
解释:如果对于某一次数据操作来讲,延迟非常高,socket需要等待更长的时间,建议把该值设置为更大的值(默认60000毫秒),以确保socket不会被timeout掉。

6.4 优化数据的写入效率

mapred-site.xml
属性:
mapreduce.map.output.compress
mapreduce.map.output.compress.codec
解释:开启这两个数据可以大大提高文件的写入效率,减少写入时间。第一个属性值修改为true,第二个属性值修改为:org.apache.hadoop.io.compress.GzipCodec或者其他压缩方式。

6.5 设置RPC监听数量

HBase-site.xml
属性:HBase.regionserver.handler.count
解释:默认值为30,用于指定RPC监听的数量,可以根据客户端的请求数进行调整,读写请求较多时,增加此值。

6.6 优化HStore文件大小

HBase-site.xml
属性:HBase.hregion.max.filesize
解释:默认值10737418240(10GB),如果需要运行HBase的MR任务,可以减小此值,因为一个region对应一个map任务,如果单个region过大,会导致map任务执行时间过长。该值的意思就是,如果HFile的大小达到这个数值,则这个region会被切分为两个Hfile。

6.7 优化HBase客户端缓存

HBase-site.xml
属性:HBase.client.write.buffer
解释:用于指定HBase客户端缓存,增大该值可以减少RPC调用次数,但是会消耗更多内存,反之则反之。一般我们需要设定一定的缓存大小,以达到减少RPC次数的目的。

6.8 指定scan.next扫描HBase所获取的行数

HBase-site.xml
属性:HBase.client.scanner.caching
解释:用于指定scan.next方法获取的默认行数,值越大,消耗内存越大。

6.9 flush、compact、split机制

当MemStore达到阈值,将Memstore中的数据Flush进Storefile;compact机制则是把flush出来的小文件合并成大的Storefile文件。split则是当Region达到阈值,会把过大的Region一分为二。
涉及属性:
即:128M就是Memstore的默认阈值
HBase.hregion.memstore.flush.size:134217728
即:这个参数的作用是当单个HRegion内所有的Memstore大小总和超过指定值时,flush该HRegion的所有memstore。RegionServer的flush是通过将请求添加一个队列,模拟生产消费模型来异步处理的。那这里就有一个问题,当队列来不及消费,产生大量积压请求时,可能会导致内存陡增,最坏的情况是触发OOM。
HBase.regionserver.global.memstore.upperLimit:0.4
HBase.regionserver.global.memstore.lowerLimit:0.38
即:当MemStore使用内存总量达到HBase.regionserver.global.memstore.upperLimit指定值时,将会有多个MemStores flush到文件中,MemStore flush 顺序是按照大小降序执行的,直到刷新到MemStore使用内存略小于lowerLimit

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值