HBase MemStore简介

本文深入解析了MemStore在HBase中的关键作用,包括数据存储、内存缓存、版本管理和flush策略。重点讨论了flush时机、影响业务的因素,以及flush流程和MemStore对性能的影响。

MemStore 是 HBase 非常重要的组成部分,MemStore 作为 HBase 的写缓存,保存着数据的最近一次更新,同时是HBase能够实现高性能随机读写的重要组成。

MemStore

HBase Table 的每个 Column family 维护一个 MemStore,当满足一定条件时 MemStore 会执行一次 flush,文件系统中生成新的 HFile。而每次 Flush 的最小单位是 Region

MemStore的主要作用:

  1. 更新数据存储在 MemStore 中,使用 LSM(Log-Structured Merge Tree)数据结构存储,在内存内进行排序整合。即保证写入数据有序(HFile中数据都按照RowKey进行排序),同时可以极大地提升HBase的写入性能。

  2. 作为内存缓存,读取数据时会优先检查 MemStore,根据局部性原理,新写入的数据被访问的概率更大。

  3. 在持久化写入前可以做某些优化,例如:保留数据的版本设置为1,持久化只需写入最新版本。

如果一个 HRegion 中 MemStore 过多(Column family 设置过多),每次 flush 的开销必然会很大,并且生成大量的 HFile 影响后续的各项操作,因此建议在进行表设计的时候尽量减少 Column family 的个数。

Flush 时机

MemStore 无论是对 HBase 的写入还是读取性能都至关重要,其中 flush 操作又是 MemStore 最核心的操作。MemStore 在多种情况下会执行一次 Flush 操作:
再次注意,MemStore 的最小 flush 单元是 HRegion 而不是单个 MemStore

  1. hbase.hregion.memstore.flush.size
    默认值:128M
    MemStore 级别限制,当 Region 中任意一个 MemStore 的大小(压缩后的大小)达到了设定值,会触发 MemStore flush。

  2. hbase.hregion.memstore.block.multiplier
    默认值:2
    Region 级别限制,当 Region 中所有 MemStore 的大小总和达到了设定值(hbase.hregion.memstore.block.multiplier * hbase.hregion.memstore.flush.size,默认 2* 128M = 256M),会触发 MemStore flush。

  3. hbase.regionserver.global.memstore.upperLimit
    默认值:0.4
    Region Server 级别限制,当一个 Region Server 中所有 MemStore 的大小总和达到了设定值(hbase.regionserver.global.memstore.upperLimit * hbase_heapsize,默认 0.4 * RS堆内存大小),会触发全部 MemStore flush。

  4. hbase.regionserver.global.memstore.lowerLimit
    默认值:0.38
    与 hbase.regionserver.global.memstore.upperLimit 类似,区别是:当一个 Region Server 中所有 MemStore 的大小总和达到了设定值(hbase.regionserver.global.memstore.lowerLimit * hbase_heapsize,默认 0.38 * RS堆内存大小),会触发部分 MemStore flush。

    Flush 顺序是按照 Region 的总 MemStore 大小,由大到小执行,先操作 MemStore 最大的 Region,再操作剩余中最大的 Region,直至总体 MemStore 的内存使用量低于设定值(hbase.regionserver.global.memstore.lowerLimit * hbase_heapsize)。

  5. hbase.regionserver.maxlogs
    默认值:32
    当一个 Region Server 中 HLog 数量达到设定值,系统会选取最早的一个 HLog 对应的一个或多个 Region 进行 flush。

    当增加 MemStore 的大小以及调整其他的 MemStore 的设置项时,也需要去调整 HLog 的配置项。否则,WAL的大小限制可能会首先被触发。因而,将利用不到其他专门为Memstore而设计的优化。

    需要关注的 HLog 配置是 HLog 文件大小,由参数 hbase.regionserver.hlog.blocksize 设置(默认512M),HLog 大小达到上限,或生成一个新的 HLog

    通过WAL限制来触发Memstore的flush并非最佳方式,这样做可能会会一次flush很多Region,尽管“写数据”是很好的分布于整个集群,进而很有可能会引发flush“大风暴”。

  6. hbase.regionserver.optionalcacheflushinterval
    默认值:3600000
    HBase 定期刷新 MemStore,默认周期为1小时,确保 MemStore 不会长时间没有持久化。为避免所有的 MemStore 在同一时间都进行 flush,定期的 flush 操作有 20000 左右的随机延时。

  7. 手动触发
    用户可以通过shell命令一下分别对一个 Table 或者一个 Region 进行 flush:
    hbase> flush 'TABLENAME'
    hbase> flush 'REGIONNAME'

  8. 其他
    执行 Compact 和 Split 之前,会进行一次 flush。

 

 

Flush 阻止更新的情况

  1. 出现上述(2)的情况,Region 下所有 Memstore 的总大小超过了 MemStore 默认大小的倍数,该 Region 在 flush 完成前会 block 新的更新请求。

  2. 出现上述(3)的情况,RegionServer 所有 MemStore 占整个堆的最大比例超过 hbase.regionserver.global.memstore.upperLimit 设置值,该 RegionServer 的更新请求会被 block,一直到 MemStore 恢复阈值一下。

更新被阻塞对单个节点和整个集群的影响都很大,需要关注 MemStore 的大小和 Memstore Flush Queue 的长度。

Memstore Flush 流程

为了减少 flush 过程对读写的影响,HBase 采用了类似于两阶段提交的方式,将整个 flush 过程分为三个阶段:

  • prepare 阶段:遍历当前 Region 中的所有 MemStore,将 MemStore 中当前数据集 kvset 做一个快照 snapshot,然后再新建一个新的 kvset,后期的所有写入操作都会写入新的 kvset 中。整个 flush 阶段读操作读 MemStore 的部分,会分别遍历新的 kvset 和 snapshot。prepare 阶段需要加一把 updateLock 对写请求阻塞,结束之后会释放该锁。因为此阶段没有任何费时操作,因此持锁时间很短。

  • flush 阶段:遍历所有 MemStore,将 prepare 阶段生成的 snapshot 持久化为临时文件,临时文件会统一放到目录.tmp下。这个过程因为涉及到磁盘IO操作,因此相对比较耗时。

  • commit 阶段:遍历所有的 MemStore,将 flush 阶段生成的临时文件移到指定的 Column family 目录下,生成对应的 Storefile(HFile) 和 Reader,把 Storefile 添加到 HStore 的 Storefiles 列表中,最后再清空 prepare 阶段生成的 snapshot。

上述 flush 流程可以通过日志信息查看:

/******* prepare 阶段 ********/
2018-07-06 18:33:31,329 INFO  [MemStoreFlusher.1] regionserver.HRegion: Started memstore flush for [table],,1528539945017.80ab9764ae70fa97b75057c376726653., current region memstore size 21.73 MB, and 1/1 column families' memstores are being flushed.

/******* flush 阶段 ********/
2018-07-06 18:33:31,696 INFO  [MemStoreFlusher.1] regionserver.DefaultStoreFlusher: Flushed, sequenceid=40056, memsize=21.7 M, hasBloomFilter=true, into tmp file hdfs://ns/hbase/data/default/[table]/80ab9764ae70fa97b75057c376726653/.tmp/f71e7e8c15774da683bdecaf7cf6cb99

/******* commit 阶段 ********/
2018-07-06 18:33:31,718 INFO  [MemStoreFlusher.1] regionserver.HStore: Added hdfs://ns/hbase/data/default/[table]/80ab9764ae70fa97b75057c376726653/d/f71e7e8c15774da683bdecaf7cf6cb99, entries=119995, sequenceid=40056, filesize=7.3 M

整个 flush 过程可能涉及到 compact 操作和 split 操作,因为过于复杂,不做详细讲解。

MemStore 对业务的影响

正常情况下,大部分 Memstore Flush 操作都不会对业务读写产生太大影响,比如:定期刷新 MemStore、手动触发、单个 MemStore flush、Region 级别的 flush 以及超过 HLog 数量限制等情况,这几种场景只会短暂的阻塞对应 Region 上的写请求,阻塞时间很短,毫秒级别。

然而一旦触发 Region Server 级别的限制导致 flush,就会对用户请求产生较大的影响。会阻塞所有落在该 RegionServer 上的更新操作,阻塞时间很长,甚至可以达到分钟级别。

导致触发 RegionServer 级别限制的主要因素:

- Region Server 上运行的 Region 总数
Region 越多,Region Server 上维护的 MemStore 就越多。根据业务表读写请求量和 RegionServer 可分配内存大小,合理设置表的分区数量(预分区的情况)。

- Region 上的 Store 数(表的 Column family 数量)
每个 Column family 会维护一个 MemStore,每次 MemStore Flush,会为每个 Column family 都创建一个新的 HFile。当其中一个CF的 MemStore 达到阈值 flush 时,所有其他CF的 MemStore 也会被 flush,因此不同CF中数据量的不均衡将会导致产生过多 HFile 和小文件,影响集群性能。很多情况下,一个CF是最好的设计。

频繁的 MemStore Flush

频繁的 MemStore Flush 会创建大量的 HFile。在检索的时候,就不得不读取大量的 HFile,读性能会受很大影响。为预防打开过多 HFile 及避免读性能恶化(读放大),HBase 有专门的 HFile 合并处理(HFile Compaction Process),根据一定的策略,合并小文件和删除过期数据。后续的文章会有详细介绍。

 

 

<think>嗯,用户现在在问HBaseMemstore Flush的设置是否实时生效。我需要先回顾一下之前提供的参考资料,特别是关于Memstore Flush的相关参数,比如hbase.regionserver.optionalcacheflushinterval。 根据引用1和2,这个参数的默认值是1小时,HBase会定期执行flush。用户想知道修改这个参数后是否立即生效,也就是是否实时生效。首先,我得确认HBase的配置加载机制是怎样的。一般来说,很多系统需要重启服务或者重新加载配置才能使参数生效,但HBase有没有例外呢? 另外,用户可能关心的是如何动态调整这些参数,避免重启集群带来的影响。HBase是否支持动态配置?我记得有些参数可以通过HBase的API或者Shell动态修改,但Memstore相关的参数可能不在其中。比如,hbase-site.xml中的某些参数可能需要重启RegionServer才能生效。需要证这一点。 再看引用3和4,提到了Memstore的大小和BlockCache的配置,但并没有直接涉及参数生效时间的问题。不过用户的问题核心在于配置变更后的生效机制,所以需要结合HBase的官方文档或者实践经验来回答。 另外,用户可能是在生产环境中调整参数,希望避免频繁的flush导致小文件问题,如引用2中提到的建议将flush间隔设为10小时。如果修改这个参数后需要重启,可能会影响服务可用性,所以用户可能希望知道是否有替代方案或者最佳实践。 总结一下,用户的问题可以分为两点:1. Memstore Flush相关参数修改后是否需要重启生效;2. 如何在不重启的情况下调整这些配置。需要明确回答是否实时生效,并给出配置生效的具体机制,可能的话提供动态调整的方法或者替代建议。</think>### HBase Memstore Flush 配置生效机制解析 #### 一、核心参数与生效逻辑 **关键参数**:`hbase.regionserver.optionalcacheflushinterval`(默认1小时) 该参数控制后台线程定期刷新所有MemStore的间隔时间,目的是避免MemStore长期未刷新导致内存占用过高[^1][^2]。 #### 二、配置修改的生效方式 1. **静态配置(非实时生效)** 若通过修改`hbase-site.xml`调整参数,**需重启RegionServer**才能生效[^1][^2]。这是大多数HBase参数的通用规则。 2. **动态配置(部分支持)** HBase支持通过Admin API或HBase Shell动态修改**部分参数**,但MemStore刷新间隔(`optionalcacheflushinterval`)**不支持动态生效**[^2]。 *示例动态调整命令(仅限支持参数)*: ```bash hbase shell> alter '表名', CONFIGURATION => {'hbase.some.dynamic.param' = 'value'} ``` #### 三、替代实时控制方案 若需立即触发MemStore刷新,可通过以下方式**绕过定时机制**: 1. **手动触发刷新** ```bash hbase shell> flush '表名' # 单表刷新 hbase shell> flush_all # 全集群刷新 ``` 2. **基于阈值触发** - `hbase.hregion.memstore.flush.size`(默认128MB):单个MemStore大小阈值 - `hbase.regionserver.global.memstore.size`(默认堆内存40%):全局MemStore总大小阈值 超过阈值时**立即触发强制刷新**,无需等待定时任务[^3][^4]。 --- ### 配置建议与注意事项 1. **生产环境优化** - 将`optionalcacheflushinterval`设为较大值(如10小时),减少小文件生成[^2] - 优先依赖阈值触发机制(`flush.size`和`global.memstore.size`)实现内存控制[^4] 2. **监控指标** - `MemStoreSize`(Region级别) - `FlushQueueSize`(RegionServer级别) 通过HBase Web UI或Metrics API实时监控,辅助决策手动刷新。 --- ### 相关问题 1. 如何通过HBase Metrics监控MemStore状态? 2. HBase哪些核心参数支持动态修改? 3. MemStore频繁刷新的性能影响及规避方法?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值