HBase为何优先读取MemStore/HFile新版本数据而非BlockCache旧版本?
HBase BlockCache与MemStore的读取优先级问题
假设存在键
100,其初始值存储在HFile中。首次读取时,该键值会从HBase取出并存入BlockCache,同时返回给客户端;后续读取该键时,会直接从BlockCache返回值。
之后更新键100的值,新值被存入MemStore。此时即使未指定版本,读取该键仍会返回最新的更新后的值,而非BlockCache中的旧值。
针对上述场景,以下是问题的解析:
1. 为何客户端不会从BlockCache获取旧值?
HBase的读取流程是优先检查MemStore,再处理BlockCache和HFile,并非先读取BlockCache。当键100被更新后,最新版本的数据存放在MemStore中,读取请求到达后会首先命中MemStore里的新值,完全不会走到取BlockCache旧值的环节。
2. BlockCache存在旧值时,HBase如何获取新版本数据?
当未指定读取版本时,HBase会按固定顺序读取各存储层的数据,再合并版本返回最新值:
- 第一步:读取当前Region的MemStore,获取该键的所有版本数据(包含最新更新的版本)
- 第二步:读取BlockCache中缓存的HFile块数据,提取该键的所有历史版本
- 第三步:读取磁盘上未被缓存的HFile文件,提取该键的所有历史版本
- 最后,HBase会将所有获取到的版本数据按时间戳降序排序,返回排在最前面的最新版本(默认行为)
也就是说,即使BlockCache里存在旧值,MemStore的新值会被优先读取,最终合并后只会返回最新的那个版本。
3. HBase如何识别BlockCache中的值已被更新?
HBase不需要主动标记BlockCache里的旧值为“过期”,而是通过时间戳对比来处理:
- 每个键值对都带有唯一的时间戳,更新操作会生成一个更大的时间戳(默认使用系统当前时间)
- 读取时,MemStore里的新值时间戳必然大于BlockCache中旧值的时间戳,在版本排序时新值会被优先选中,旧值直接被忽略
- 当MemStore刷写到HFile后,新生成的HFile会被加入Region的HFile列表,读取时会遍历所有HFile(包括新刷写的),同样通过时间戳对比取最新版本;而BlockCache中的旧HFile块,会在后续的缓存淘汰(比如LRU策略)中被逐步替换,不会影响最新数据的读取
内容的提问来源于stack exchange,提问作者pacman
相关产品推荐
相关产品推荐

