HBase原理和优化

1. HBase元数据

      HBase 表的元数据存储于 hbase:meta表中,HBase默认会 创建meta表,它属于系统命名空间hbase下面的表,.META. 结构如下

通过这个表可以清晰的查找表的region对应的元数据信息和服务器地址。

然而meta也是HBase里面的表,meta的数据的元数据存放在哪呢?HBase会使用ZooKeeper来存放

-ROOT-表的元数据。默认的路径是/hbase/root-region-server ,这个地址下面存放了-ROOT-表的地址的RegionServer地址,-ROOT-表的的结构和.META.表结构一致,唯一不同是,-ROOT-表存储的是.META.表的数据。-ROOT-表结构如下:

       数据定位流程 : Zookeeper ->  -ROOT- -> .META.  ->  User_Table

2. HBase HFile数据存储格式

   

    

     如果Root Block Index Chunk超出了预设大小,则输出位于Non-Scanned Block Section区域的Intermediate Index Block数据,以及生成并输出Root Index Block(记录Intermediate Index Block索引)到Load-On-Open Section部分。    

   详情可见官网

     http://hbase.apache.org/book.html#_hfile_format_2

3. HBase 框架图

        

HMaster的作用

  • 为Region server分配region。
  • 负责Region server的负载均衡。
  • 发现失效的Region server并重新分配其上的region到正常的RegionServer。
  • HDFS上的垃圾文件回收。
  • 处理schema更新请求。

HRegionServer作用

  • 维护master分配给他的region,处理对这些region的io请求.
  • 负责切分正在运行过程中变的过大的region。

上图没有提到的组件是BlockCache模块,每个RegionServer存在一个BlockCache,用户缓存查询的数据。

从上图可以看出

    1. 每个Store对应一个HBase中的一个列簇,一个列簇有一个单独的Memstore,每个列簇对应多个HFile。

    2. HBase主要通过Zookeeper来做集群监控。

 

4. HBase  HFile  Compact

      当HBase底层的HFile越来越多,就会执行Compaction从操作,可以减少HFile数量,也可以删除一些标记删除的数据,从而减轻系统存储压力。

      Compaction可以分为 minor Compaction 和 major Compaction

      轻量级压缩minor Compaction 

      将符合条件的最早生成的几个Hfile合并成一个大的HFile文件,它不会删除标记为"删除"的数据的过期的数据,并且执行一次minor合并操作后还会有多个storefile文件。

       重量级压缩major Compaction

     把所有的HFile合并成单一的HFile文件,在文件合并期间,会删除标记为删除标记的数据和过期失效的数据,同时会阻塞所有客户端对该操作所属的region的请求直到合并请求完毕。最后删除已经合并过的HFile小文件。

     参数控制:

参数名配置项默认值  解释
majorcompactionhbase.hregion.majorcompaction1天设置系统进行一次MajorCompaction的启动周期,如果设置为0,则系统不会主动触发MC过程。
minFilesToCompacthbase.hstore.compactionThreshold3表示至少需要三个满足条件的store file时,minor compaction才会启动
 hbase.hstore.compaction.max.size 

合并的文件大小最大是多少,超过此大小的文件不 能参与合并

maxFilesToCompacthbase.hstore.compaction.max10表示一次 minor compaction中最多选取10个store file
    

优化建议:

      hbase.hstore.compactionThreshold 设置不能太大,默认是 3 个;

      设置需要根据 Region 大小确定,通常可以简单的认为 hbase.hstore.compaction.max.size = RegionSize / hbase.hstore.compactionThreshold 

5.HBase HFile Spilt

HBase 触发Split

     HBase中共有3种情况会触发HBase的split,分别是:

        1.当memstore flush操作后,HRegion写入新的HFile,有可能产生较大的HFile,HBase就会调用CompactSplitThread.requestSplit判断是否需要split操作。

        2.HStore刚刚进行完compact操作后有可能产生较大的HFile,当满足HBase的某一分裂策略后就会进行split操作。

        3.当HBaseAdmin手动发起split时,也会触发split操作。

            当HFile的大小超过阈值时(hbase.hregion.max.file.size = 256M),会触发HBase的文件分裂的流程。

            hbase.regionserver.regionSplitLimit=1000 设置一个RegionServer的Region上限个数。

      注意:

        hbase.hregion.max.filesize不宜过大或过小, 生产高并发运行下,最佳大小5-10GB!关闭某些重要场景的hbase表的major_compact!

        在非高峰期的时候再去调用major_compact,这样可以减少split的同时,显著提供集群的性能,吞吐量、非常有用。

HBase Split策略

  • IncreasingToUpperBoundRegionSplitPolicy

      region split的计算公式是:regioncount^3 * 128M * 2,当region达到该size的时候进行split。

  • ConstantSizeRegionSplitPolicyo

   0.94.0之前该策略是region的默认split策略,0.94.0之后region的默认split策略为IncreasingToUpperBoundRegionSplitPolicy,当region size达到hbase.hregion.max.filesize(默认10G)配置的大小后进行split

  • DisabledRegionSplitPolicy

       该策略是直接禁用了region的自动split。

  • KeyPrefixRegionSplitPolicy

      根据rowKey的前缀对数据进行分组,这里是指定rowKey的前多少位作为前缀,比如rowKey都是16位的,指定前5位是前缀,那么前5位相同的rowKey在进行region split的时候会分到相同的region中。

  • DelimitedKeyPrefixRegionSplitPolicy

      保证相同前缀的数据在同一个region中,例如rowKey的格式为:userid_eventtype_eventid,指定的delimiter为 _ ,则split的的时候会确保userid相同的数据在同一个region中。

设置策略demo

<property>
   <name>hbase.regionserver.region.split.policy</name>
   <value>
    org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy
   </value>
   <source>hbase-default.xml</source>
</property>

 

6.HBase读写流程

        写入流程

            1.首先写入WAL日志,以防Crash

            2. 写入MemStore缓存,即写缓存,由于是内存写入所以速度比较快。

            3.立马返回客户端写入完成

            4.当Memstore满时,从Memstore刷新到HFile,磁盘的顺序读写速度非常快,并记录下最后一次最高的sequence号,这样系统能知道哪些记录已经持久化,哪些没有。

         读取流程

              1.从Memstore中读取数据

              2.读取BlockCache 中查找可能被缓存的数据

              3.访问HFile ,合并所有的数据返回客户端

7.HBase BlockCache 和 Memstore

        模块JVM堆内存默认比例

            memstore[40%]   blockcache[40%]    other[20%]

         blockcache比例设置

            hfile.block.cache.size=0.3 (堆内存的0.3)

         memstore比例设置

            hbase.regionserver.global.memstore.size (region 单个 memstore 内存占比 默认0.4)

            hbase.regionserver.global.memstore.upperLimit=0.6。

       一个Regionserver上有一个BlockCache和N个Memstore,它们的大小之和不能大于等于heapsize * 0.8,否则HBase不能正常启动。( blockcache + memstore 内存比列占堆内存比列<80% 才能启动。)

         每个Region都有自己的MemStore,当大小达到了上限(hbase.hregion.memstore.flush.size,默认128MB),会触发Memstore刷新。

    BlockCache 组成

  • Single(0.25):如果一个Block第一次被访问,则放在这一优先级队列中,占;
  • Multi(0.5):如果一个Block被多次访问,则从Single队列移到Multi队列中;
  • InMemory(0.25):如果一个Block是inMemory的,则放到这个队列中。

8.HBase WAL

     HBase的Write Ahead Log (WAL)提供了一种高并发、持久化的日志保存与回放机制。每一个业务数据的写入操作(PUT / DELETE)执行前,都会记账在WAL中。如果出现HBase服务器宕机,则可以从WAL中回放执行之前没有完成的操作。

     对于不太重要的数据,可以在Put/Delete操作时,通过调用Put.setWriteToWAL(false)Delete.setWriteToWAL(false)函数,放弃写WAL日志,以提高数据写入的性能。

9.建表属性

 (1)  BLOOMFILTER    create ‘table’,{BLOOMFILTER =>’ROW’}   

        启用布隆过滤可以节省读磁盘过程,可以有助于降低读取延迟,行键的哈希在每次插入行时将被添加到布隆
 (2)  VERSIONS           create 'table',{VERSIONS=>'2'} 

        默认是1 这个参数的意思是数据保留1个 版本,如果认为我们的老版本数据对我们毫无价值不需要保留这么多,且更新频繁,那将此参数设为1 能节约2/3的空间
 (3)  COMPRESSION    create 'table',{NAME=>'info',COMPRESSION=>'SNAPPY'} 

        这个参数意思是该列族是否采用压缩,采用什么压缩算法 
 (4)  hbase 表预分区—-手动分区  create 't1', 'f1', {NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}  

        一种可以加快批量写入速度的方法是通过预先创建一些空的regions,这样当数据写入HBase时,会按照region分区情况,在集群内做数据的负载均衡

10.客户端优化

(1)Auto Flush

通过调用HTable.setAutoFlushTo(false)方法可以将HTable写客户端自动flush关闭,这样可以批量写入数据到HBase,而不是有一条put就执行一次更新,只有当put填满客户端写缓存的时候,才会向HBase服务端发起写请求。默认情况下auto flush是开启的。

(2)Write Buffer

通过调用HTable.setWriteBufferSize(writeBufferSize)方法可以设置HTable客户端的写buffer大小,如果新设置的buffer小于当前写buffer中的数据时,buffer将会被flush到服务端。其中,writeBufferSize的单位是byte字节数,可以根基实际写入数据量的多少来设置该值。

(3)批量写
通过调用HTable.put(Put)方法可以将一个指定的row key记录写入HBase,同样HBase提供了另一个方法:通过调用HTable.put(List<Put>)方法可以将指定的row key列表,批量写入多行记录,这样做的好处是批量执行,只需要一次网络I/O开销,这对于对数据实时性要求高,网络传输RTT高的情景下可能带来明显的性能提升。

(4)多线程并发写
在客户端开启多个 HTable 写线程,每个写线程负责一个 HTable 对象的 flush 操作,这样结合定时 flush 和写 buffer(writeBufferSize),可以既保证在数据量小的时候,数据可以在较短时间内被 flush(如1秒内),同时又保证在数据量大的时候,写 buffer 一满就及时进行 flush。

(5)批量读
通过调用 HTable.get(Get) 方法可以根据一个指定的 row key 获取一行记录,同样 HBase 提供了另一个方法:通过调用 HTable.get(List) 方法可以根据一个指定的 row key 列表,批量获取多行记录,这样做的好处是批量执行,只需要一次网络 I/O 开销,这对于对数据实时性要求高而且网络传输 RTT 高的情景下可能带来明显的性能提升。
(6) 客户端缓存

  scan的扫描缓存setCaching(int caching) 设置的值为每次rpc的请求记录数.

  scan的扫描缓存 scan.setCacheBlocks(false); 设置请求的记录是否缓存到服务端的BlockCache,MR时需要设置为false

 

转载于:https://my.oschina.net/manmao/blog/1829772

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值