HBase MemStore简介
HBase表的每个列族都维护一个MemStore,当满足某些条件时,MemStore将执行刷新,在文件系统中生成一个新的HFile。每个齐平的最小单位是区域。
MemStore的主要功能:
如果一个HRegion中的MemStore太多(列族设置太多),那么每次刷新的代价必然非常大,会产生大量的HFile,影响后续的操作。因此,建议在设计表时尽可能减少列族的数量。
MemStore对于HBase的读写性能都非常重要,而刷新操作是MemStore的核心操作。MemStore在多种情况下执行刷新操作:
再次注意,MemStore的最小刷新单位是HRegion,而不是单个MemStore。
阻塞更新对单个节点和整个集群的影响都很大,需要注意MemStore的大小和Memstore Flush队列的长度。
为了减少刷新过程对读写的影响,HBase采用了类似两阶段提交的方式,将整个刷新过程分为三个阶段:
可以通过日志信息查看上述刷新过程:
整个冲洗过程可能会涉及到紧凑操作和拆分操作,因为太复杂,无法详细解释。
一般情况下,大部分MemStore刷新操作不会对业务读写产生太大影响,比如:周期性刷新memstore、手动触发、刷新单个Memstore、区域级刷新、超过HLog数量限制等。这些场景只会暂时阻塞相应区域上的写请求,阻塞时间非常短,以毫秒计。
但是一旦触发区域服务器级别的限制导致flush,就会对用户请求产生很大的影响。它会阻塞所有落在RegionServer上的更新操作,阻塞时间非常长,甚至达到分钟级别。
导致触发区域服务器级别限制的主要因素有:
-在区域服务器上运行的区域总数。
区域越多,区域服务器上维护的MemStore就越多。根据服务表的读写请求和RegionServer能够分配的内存大小,合理设置表的分区数(预分区的情况下)。
-区域上存储的数量(表中列族的数量)
每个列族维护一个MemStore,每次刷新MemStore时,都会为每个列族创建一个新的HFile。当一个CF的MemStore达到刷新阈值时,其他所有CF的MemStore也会被刷新,所以不同CF中数据的不平衡会导致HFile和小文件过多,影响集群性能。在很多情况下,CF是最好的设计。
频繁刷新内存将创建大量的HFile。搜索时要读取大量的HFile,读取性能会受到很大影响。为了防止打开过多的HFile,避免读取性能恶化(读取放大),HBase有专门的HFile合并流程,按照一定的策略合并小文件,删除过期数据。后续文章会详细介绍。