• Hbase参数调优


    这里的参数调优,一般来说是针对memStore的flush过程进行调优

    触发 MemStore 的flush过程的时机(条件)

    Region 中任意一个 MemStore 占用的内存超过相关阈值 或者 Region的全部memStore占用内存总和达到相关阈值

    Memstore级别限制:Region中任意一个MemStore的大小达到了上限,会触发flush操作

    Region级别限制:当一个Region里面的全部memStore占用的内存大小超过阈值的时候会触发一次flush操作(一个Region对应多个Store,一个Store对应一个memStore,因此一个Region里面会有多个memStore)

    涉及到的参数有:

    1. hbase.hregion.memstore.flush.size

    默认值是128M,单位是字节,单个memStore占用内存超过这个参数的值将被flush到storeFile

    1. hbase.hregion.memstore.block.multiplier

    默认值为4,这个参数主要用来和hbase.hregion.memstore.flush.size相乘,如果memstore的内存大小大于这两个参数相乘的结果,比如 128 * 4 M,则会阻塞memstore的写操作,直到降至该值以下

    注:上面主要涉及了两个参数,hbase.hregion.memstore.flush.size为128M,一旦memStore里面的数据达到128M,那么就会触发flush操作。但是有一种情况,那就是写入memStore的速度太快,快到memStore达到128M后,还没来得及把这128M写完,就达到了128*4M,这样就会触发阻塞状态,此时Store会拒绝所有写请求,也就是不能再往memStore中写入数据,直到将memStore里面的全部数据都flush到storeFile里面为止。

    因此,如果写操作非常频繁的话,可以考虑调大hbase.hregion.memstore.block.multiplier的值,让触发Store阻塞的值变大。

    但是也不能过大,因为太大可能会导致一个RegionServer里面的memStore占用内存总和超过hbase.regionserver.global.memstore.size,进而导致全部的memStore阻塞写操作。

    整个 RegionServer 的 MemStore 占用内存总和大于相关阈值

    这里指的是一个RegionServer里面的全部memStore的占用内存,加在一起超过了阈值,这个阈值一般是RegionServer全部内存的40%。一旦超过了阈值,那么当前RegionServer的全部写操作都会被阻塞。

    注意:这里说的是一个RegionServer里面的全部memStore的内存相加超过阈值(RegionServer级别限制),而上一个情况是一个Region里面的全部memStore占用内存达到阈值

    这里涉及到了两个参数,分别是hbase.regionserver.global.memstore.sizehbase.regionserver.global.memstore.size.lower.limit

    1. hbase.regionserver.global.memstore.size

    默认值为0.4,是RegionServer中所有memstore占用内存在总内存中的比例,当达到该值,则会从整个RegionServer里面找到占用内存最大的memStore,让其进行flush操作,直到总内存比例降至这个参数的阈值以下,并且在低于阈值之前,阻塞memstore的所有写操作

    注:如果写操作频繁,就可以提高当前参数memstore.size的值,避免频繁的触发flush过程。但是这个数值不能设定的过高,因为在RegionServer中还有一个block cache在占用内存。block cache的作用是存储会被频繁访问的数据,提高了数据查询的效率,占用的内存空间比例默认也是0.4

    memStore对应写操作,block cache对应读操作。

    因此写操作频繁的时候就应该提高memStore的内存,降低block cache的内存

    读操作频繁的时候就应该提高block cache的内存,降低memstore的内存

    1. hbase.regionserver.global.memstore.size.lower.limit

    默认值0.95,相当于上一个参数的0.95

    如果有 16G 堆内存,默认情况下:

      # 达到该值会触发刷写
      16 * 0.4 * 0.95 = 6.08
      # 达到该值会触发阻塞
      16 * 0.4 = 6.4
    
       
    • 1
    • 2
    • 3
    • 4
    • 1
    • 2
    • 3
    • 4

    注:上一个参数介绍里面有说,当一个RegionServer里面全部的memStore内存加一起,占到当前RegionServer内存的40%,就会触发flush操作,并且阻塞所有的memStore的写操作。但这样做有些不合理,在达到阈值前应该给一个缓冲的余地,避免直接进入阻塞状态。

    这就是当前这个参数的作用,这个参数设置了一个比例,默认为0.95,假设一个RegionServer的内存总共有16G,那么触发memStore的flush的阈值为16*0.4,而这个参数就会在此基础上再乘0.95,得出的值为6.08G,当全部的memStore占用内存达到这个数值时,就会开始flush操作,并且不会阻塞。如果在原先的阈值16 * 0.4=6.4G之前flush完成,则不会阻塞,如果没有完成就会进入阻塞状态。

    注2:因此如果写操作很频繁的话,就可以将当前参数lower.limit的值调小,这样就会提前触发flush过程,留下的缓冲空间更多,尽量避免阻塞。

    WAL数量大于相关阈值或WAL的大小超过一定阈值

    假设单个memStore的占用内存没有达到内存,而一个RegionServer里面全部的memStore加一起内存也没有达到阈值,正常来说不会触发flush操作,但这里又多了一个新的情况,那就是HLog。当HLog的数量过多时,同样会触发memStore的flush操作,因为HLog的数量太多会影响容灾后的数据恢复效率,而当memStore里面的数据都flush到磁盘后,HLog会被清空。

    这里涉及到的参数是hbase.regionserver.maxlogs,含义是HLog文件的最大数量,超过这个数量则触发flush操作。这个参数的值如果给定,那么就是给定的值,如果没有给定,那么就是max(32, hbase_heapsize * hbase.regionserver.global.memstore.size * 2 / logRollSize),从两个值里面选一个最大值。max()里面的第二个参数是根据当前的内存情况计算出的HLog文件数量的最大值

    不止HLog数量过多会触发,当HLog文件占用的内存空间达到阈值时,也会触发memStore的flush操作。需要注意的是,如果增大了memStore的内存,那么也要增大HLog文件的内存占用阈值,否则HLog文件达到阈值直接触发flush,而memStore还远没有达到阈值,这样增大memStroe的内存就没有意义了。

    定期自动刷写

    定期自动刷写就是启动一个专门的线程,每隔一个固定的时间,就去查看RegionServer里面的Region距离上次flush操作过去的时间,如果达到hbase.regionserver.optionalcacheflushinterval参数的值,还没有flush,就会触发一次flush刷写操作,这个参数的值一般是一个小时。

    另外考虑到可能会有多个memStore同时达到了一小时的时间阈值,都需要进行flush操作,为了避免同时进行,导致资源被大量占用。定期自动刷写策略里面有一个延迟机制,memStore不会立刻开始flush,而是随机等待0到5分钟之后才会开始flush操作

    数据更新超过一定阈值

    在HBase中对数据的删除,更新等操作实际上并不会立即执行,而是打上一个标记,像这种操作很频繁时,同样会触发flush操作,这样数据写入storeFile里面,会触发合并,合并操作时会真正对数据进行删除,更新。

    手动触发刷写

    手动执行flush命令,指定某张表的某个region里面的memStore进行flush刷写操作

    触发 MemStore 的flush过程的操作

    常见的 put、delete、append、incr、调用 flush 命令、Region 分裂、Region Merge、bulkLoad HFiles 以及给表做快照操作都会对上面的相关条件做检查,以便判断要不要做刷写操作。

    MemStore 刷写策略(FlushPolicy)

    注:前面说过触发memStore的flush操作的时机,只要满足了上面的那些条件就会触发flush操作。这里说的是触发了flush操作后,具体哪些memStore会执行flush过程,具体执行的策略

    FlushAllStoresPolicy

    这种刷写策略与HBase1.1之前的策略一样,都是不去区分具体哪个memStore执行flush操作,只要触发了flush操作,就是把当前Region里面的全部memStore都进行flush操作

    FlushAllLargeStoresPolicy

    当满足了flush操作条件后,根据这个策略,会先判断Region里面的每个memStore的使用内存是否超过了某个bound阈值,如果超过了则进行flush刷写操作,如果没有则不会进行flush刷写操作

    但是如果触发了flush操作,也就是满足了之前说的时机条件里面的任何一条,却发现Region里面的所有memStore都没有超过bound阈值,此时当前策略就会退化为FlushAllStoresPolicy,即对region里面的全部memStore进行flush过程。

    这个bound阈值的计算涉及两个参数:

    1. hbase.hregion.percolumnfamilyflush.size.lower.bound.min
      默认值为16MB
    2. hbase.hregion.percolumnfamilyflush.size.lower.bound
      这个参数没有默认值,而是根据当前表的列簇数量计算而得,假设当前表有3个列簇,那么
      hbase.hregion.percolumnfamilyflush.size.lower.bound = max((long)128 / 3, 16) = 42 MB

    触发flush过程后,如果memStore超过42M,则只对超过的memStore进行flush操作。如果都没有超过,则对全部的memStore进行flush操作

    FlushNonSloppyStoresFirstPolicy

    这里按照isSloppyMemStore的值将memStore分成了两个部分,分别放在sloppyStores 与 regularStores这两个HahsSet里面

    当触发了flush过程后
    先到regularStores里面判断是否有超过相关阈值的memStore,如果有就对其进行flush过程,其余没有超过阈值的memStore不会被处理。

    如果regularStores里面的memStore都没有超过阈值,则到sloppyStores 查找有没有超过相关阈值的memStore,如果有则对其进行flush操作,其余的不做处理

    如果上面两个部分都没有找到超过相关阈值的memStore,那么当前策略会退化成 FlushAllStoresPolicy策略,即对region里面的全部memStore进行flush过程

    注:这里的isSloppyMemStore
    如果相关列簇的hbase.hregion.compacting.memstore.type 参数的值不是 NONE,那么这个 MemStore 的 isSloppyMemStore 值就是 true,否则就是 false。

  • 相关阅读:
    MySQL基本知识
    LeetCode 面试题 10.09. 排序矩阵查找
    工程测量模拟A卷
    Redis概述及安装使用
    晶振工作原理详解
    wgcna 官网教程II.Consensus analysis of female and male liver expression data
    Ubuntu下文件的解压缩操作:常用zip和unzip
    conda创建环境在Collecting package metadata (current_repodata.json)时报错的解决
    力扣hot100——第4天:19删除链表的倒数第N个节点、20有效的括号、21合并两个有序链表
    安全至上:落地DevSecOps最佳实践你不得不知道的工具
  • 原文地址:https://blog.csdn.net/wang6733284/article/details/126009678