Hbase 优化

关于Hbase的优化

    • 高可用
    • 预分区
      • 手动设定预分区
      • 生成16进制序列预分区
      • 按照文件中设置的规则预分区
      • 使用JavaAPI创建预分区
    • Rowkey设计
    • 内存优化
    • 基础优化

高可用

在HBase中Hmaster负责监控RegionServer的生命周期,均衡RegionServer的负载,如果Hmaster挂掉了,那么整个HBase集群将陷入不健康的状态,并且此时的工作状态并不会维持太久。所以HBase支持对Hmaster的高可用配置。
Hbase的高可用很简单,直接在别的节点上启动一个HMaster进程就可以了,没Namenode那么复杂
比如hadoop1,hadoop2,hadoop3这三台机器构成了一个Hbase集群,首先在hadoop1上用start-hbase.sh就可以直接启动三个RegionServer,另外还会在hadoop1上启动一个HMaster。为了高可用,直接在hadoop2或者hadoop3上用命令hbase-daemon.sh start master 再启动一个(或者hadoop2和hadoop3都启动)HMaster即可。
为了方便,可以直接在hadoop1的hbase安装目录配置文件下创建一个backup-masters(名字不能改变)文件,将要额外启动HMaster的节点写进去即可。这样以后直接在hadoop1上start-hbase.sh一键启动即可。

预分区

在之前文章region的split里面说过如果生产环境上不做表的预分区,那么很有可能会发生数据倾斜或者数据热点的问题,这样某一个region的负载就会很大,带来性能问题。所以,我们可以将数据所要投放的分区提前大致的规划好,以提高HBase性能。

生产环境下,需要和数据量(考虑生产环境下半年内或者一年内的数据量)、业务场景以及服务器规模去进行预分区。这里只是阐述一下几种常见的预分区手段:

手动设定预分区

手动设定预分区
这样一条命令会将表分成6个分区。
Hbase 优化_第1张图片
StartKey和EndKey称为分区键,数据需要根据rowkey判断需要进哪个分区。rowkey都是按照字典顺序排的。举例:rowkey为300的会进入slave7,rowkey为3001的会进入slave6。所以这样分也并不合理5000以后的都会进入最后一个分区,还需结合实际环境考虑(和rowkey的设计)。

生成16进制序列预分区

命令
Hbase 优化_第2张图片
Hbase 优化_第3张图片

按照文件中设置的规则预分区

创建splits.txt文件内容如下:

aaaa
bbbb
cccc
dddd
ffff

Hbase 优化_第4张图片
Hbase 优化_第5张图片

使用JavaAPI创建预分区

//自定义算法,产生一系列Hash散列值存储在二维数组中
byte[][] splitKeys = 某个散列值函数
//创建HBaseAdmin实例
HBaseAdmin hAdmin = new HBaseAdmin(HBaseConfiguration.create());
//创建HTableDescriptor实例
HTableDescriptor tableDesc = new HTableDescriptor(tableName);
//通过HTableDescriptor实例和散列值二维数组创建带有预分区的HBase表
hAdmin.createTable(tableDesc, splitKeys);

需要注意的是:即使做了预分区,当数据达到一定大小的时候,系统默认还是会按照region的split来继续做切分。

Rowkey设计

设计rowkey的时候,一定要考虑预分区!

  • 长度原则:
    Rowkey 是一个二进制码,Rowkey 的长度被很多开发者建议说设计在 10~100 个字节,不过建议是越短越好。
  1. 数据的持久化文件 HFile 中是按照 KeyValue 存储的,如果 Rowkey 过长比如 100 个字节,1000 万列数据光 Rowkey 就要占用 100*1000 万=10 亿个字节,将近 1G 数据,这会极大影响 HFile 的存储效率。
  2. MemStore 将缓存部分数据到内存,如果 Rowkey 字段过长内存的有效利用率会降低,系统将无法缓存更多的数据,这会降低检索效率。因此 Rowkey 的字节长度越短越好。
  • 散列原则
    避免数据都在一个RegionServer 上堆积的热点现象,这样在做数据检索的时候负载将会集中在个别 RegionServer,降低查询效率。
    可以采用生成随机数、hash、散列值、字符串反转、拼接等。

  • 唯一原则
    必须在设计上保证其唯一性。rowkey 是按照字典顺序排序存储的,因此,设计 rowkey的时候,要充分利用这个排序的特点,将经常读取的数据存储到一块,将最近可能会被访问的数据放到一块。

内存优化

HBase操作过程中需要大量的内存开销,毕竟Table是可以缓存在内存中的,一般会分配整个可用内存的70%给HBase的Java堆。但是不建议分配非常大的堆内存,因为GC过程持续太久会导致RegionServer处于长期不可用状态。另外,flush的时候有个RegionServer级别的参数,如果堆内存太大,堆内存 * 0.4的时候才会去flush,一次性flush的时长就会变长。也会导致hbase.regionserver.global.memstore.size和hbase.regionserver.global.memstore.size.lower.limit这两个参数的差值变的很大,高负载时,影响客户端操作。(以上两个参数详情见memstory的Flush时机)

基础优化

参数 解释
属性:dfs.support.append(位置:hdfs-site.xml、hbase-site.xml) 允许在HDFS的文件中追加内容:开启HDFS追加同步,可以优秀的配合HBase的数据同步和持久化。默认值为true。
属性:dfs.datanode.max.transfer.threads(位置:hdfs-site.xml) 优化DataNode允许的最大文件打开数:HBase一般都会同一时间操作大量的文件,根据集群的数量和规模以及数据动作,设置为4096或者更高。默认值:4096
属性:dfs.image.transfer.timeout(位置:hdfs-site.xml) 优化延迟高的数据操作的等待时间:如果对于某一次数据操作来讲,延迟非常高,socket需要等待更长的时间,建议把该值设置为更大的值(默认60000毫秒),以确保socket不会被timeout掉。
属性:mapreduce.map.output.compress,mapreduce.map.output.compress.codec(位置:mapred-site.xml) 优化数据的写入效率:开启这两个数据可以大大提高文件的写入效率,减少写入时间。第一个属性值修改为true,第二个属性值修改为:org.apache.hadoop.io.compress.GzipCodec或者其他压缩方式。
属性:hbase.regionserver.handler.count(位置:hbase-site.xml) 设置RPC监听数量:默认值为30,用于指定RPC监听的数量,可以根据客户端的请求数进行调整,读写请求较多时,增加此值。
属性:hbase.hregion.max.filesize(位置:hbase-site.xml) 优化StoreFile文件大小 :默认值10737418240(10GB),如果需要运行HBase的MR任务,可以减小此值,因为一个region对应一个map任务,如果单个region过大,会导致map任务执行时间过长。该值的意思就是,如果StoreFileFile的大小达到这个数值,则这个region会被切分为两个StoreFileFile。
属性:hbase.client.write.buffer(位置:hbase-site.xml) 优化hbase客户端缓存:用于指定HBase客户端缓存,增大该值可以减少RPC调用次数,但是会消耗更多内存,反之则反之。一般我们需要设定一定的缓存大小,以达到减少RPC次数的目的。
属性:hbase.client.scanner.caching(位置:hbase-site.xml) 指定scan.next扫描HBase所获取的行数:用于指定scan.next方法获取的默认行数,值越大,消耗内存越大。
flush、compact、split机制 当MemStore达到阈值,将Memstore中的数据Flush进Storefile;compact机制则是把flush出来的小文件合并成大的Storefile文件。split则是当Region达到阈值,会把过大的Region一分为二。(详情见Hbase篇章flush、compact、split)

你可能感兴趣的:(大数据-Hbase,hbase)