在debug region一文中http://blog.csdn.net/mrtitan/article/details/8209994已经说到Hbase中每个region都是个独立的个体,本文会分析一次get操作在region层面是如何实现的。
HBase系统架构:
client的一次get操作到了regionserver后,regionserver会根据rowkey的范围选择对应的region。
region拼装rowkey,根据get的column选择对应的HStore(每个column对应一个HStore),开始get
HStoreKey key = new HStoreKey(row, column, timestamp);
HStore targetStore = stores.get(HStoreKey.extractFamily(column));
return targetStore.get(key, numVersions);
get的基本流程是:
1.首先在内存即memstore中查找HStoreKey,如果查到足够数量的记录则返回
2.如果memstore没能满足我们的get请求,则遍历所有文件即storefiles,直到拿到足够数量的记录为止。
根据这样的流程,我们可以看出:
1.memstore的命中率很重要
2.如果内存没命中,则需要遍历所有的storefile,这样,随着storefile变多或者单个storefile过大则会明显减慢get的速度
3.为了防止storefile过多,region会定期compact,将所有storefile合并为一个
4.合并后storefile过大,因此region又会做split,将一个region分成2个
5.使用bloomfilter会大大加快get的速度,因为bloomfilter会直接跳过那些不存在此key的storefile。
这种先mem后file的get流程Hbase一直沿用到最新的版本都没有改变,这也是LSM-Tree为了解决读效率的解决方式。
在0.1.0后面的版本中主要增强了bloomfilter的功能,包括支持row,rowcol,还有在mapfile上又包了一层HFile。