同时会读 memstore 和 storefile,如果 storefile 里有数据,会加载到 blockcache 中,然后把数据做一个合并,取时间戳最大的那条数据返回给client,并且将数据写入到 blockcache
遵循的大体流程是 client->memstore->blockcache->storefile。如果读到了会把数据放到blockcache里缓存,方便下次读取
同时去读内存和磁盘,是为了避免磁盘的时间戳大于内存的时间戳,即put数据的时候设置了老时间戳
5. compact 合并memstore不断flush到磁盘,生成hfile。
minor compactions 会把多个文件hfile合并为一个大的hfile
major compactions 会把所有hfile合并为一个hfile,默认是7天,但是生产上应该关闭,会非常消耗资源,应在空闲时间手动触发
compact 会 rewrite hfile to a single storefile 重写的过程会下载hdfs文件,然后重新写入,所以很消耗资源
hbase.hstore.compactionThreshold 是一个store(列族)允许的hfile个数,超过这个个数就会合并
6. region split 切分region 交给不同服务器,缓解热点问题 => hfile 不断拆分,文件越来越大,到最后有可能还是会导致热点问题的存在,因为有的文件特别大,查的数据都在这个文件里 => 建表的时候实现 预分区
HBase 默认分区规则
memstore.flush.size=128MB
max.store.size=10G
分区规则:Min(R^2 * “hbase.hregion.memstore.flush.size”, “hbase.hregion.max.filesize”)
第一次拆分大小为:min(10G,11128M)=128M // 一开始的时候就一个region,当数据量达到128M时,会一分为二,变成2个region,然后会往第二个region里写数据,但是第一个不会写,处于半满状态 => 之前分裂的region都不会再被写入数据,处于半满状态
第二次拆分大小为:min(10G,33128M)=1152M
第三次拆分大小为:min(10G,55128M)=3200M
第四次拆分大小为:min(10G,77128M)=6272M
第五次拆分大小为:min(10G,99128M)=10G
第五次拆分大小为:min(10G,1111128M)=10G // 最大是10G
官方建议使用一个列族,避免的问题是:有的列族很多数据,有的列族可能只有几条数,按照region切分,然后flush到磁盘,可能会产生很多的小文件