读数据流程
- 客户端先查看本地是否存有 meta 表 (包含所需数据所在的 HRegionServer 位置) 数据位置元信息的缓存, 即 blockCache, 如果有直接找对应的 HRegionServer 而不用去 zookeeper 查找元信息, 否则需要到 zookeeper 读取 meta 表, 读取后会先把位置元信息缓存到 blockcache
- 找到 meta 信息后, 向对应的 HRegionServer 发送读取请求, 去往目标 HRegionServer 中的 Region
- 找到位置后发起读请求, 注意这里是从 MemStore 和磁盘同时读取, 选择其中时间戳最大, 即最新的数据返回, 返回到客户端
这个地方很多博客写的都是 [blockCache 缓存在 Stroe 中, 读取会先从 MemStore 中读, 如果没有去 blockCache 中读, 如果还没有去磁盘 StroeFile 中读], 其实是错误的, 上面的 3 个步骤是查看过源码之后得出的结论
0.98 版本为界, 老版的 hbase 中有 -Root- 表, -Root- 表中存放 -meta- 表位置, 而新版发现没有必须, 去除了 -Root- 表, 旧版的要三步 (root, meta, region) 找到位置, 新版两步 (meta, region), 读流程和 Hmaster 没有关系. Hmaster 挂掉不影响读数据
写数据流程
- 客户端发送写请求, 先去 zookeeper 获取 meta 表元数据, 确定要写入的数据的位置, 即 HRegion 和 HRegionServer
- 客户端向 HRegionServer 发送写数据请求
- HRegionServer 响应后, 客户端先记录步骤到 HLog
- 然后将数据写入 Memstore, HLog 和 MemStore 写入后即返回写入成功信息, 由于只与内存交互, 所以 HBase 存在写数据比读数据快的现象
- 如果 Memstroe 达到阈值, 会刷新内存中的数据到 Storefile 磁盘中, 此时会有小文件产生
- 当 Stroefile 越来越多, 会触发 Compact 合并操作, 将多个 Storefile 合并为一个 Storefile 小合并: 当一个 Region 中的 HFile 的数量超过一个值(默认3)的时候, 这个 Region 中的 HFile 会进行合并成换一个文件, 并删除旧的文件 大合并: Major compaction 指一个 region 下的所有 HFile 做归并排序, 最后形成一个大的HFile. 这可以提高读性能. Major compaction 可以被调度成自动运行的模式, 但是由于写放大的问题(write amplification), major compaction通常在一周执行一次或者只在凌晨运行.此外, major compaction的过程中, 如果发现region server负责的数据不在本地的HDFS datanode上, major compaction除了合并文件外, 还会把其中一份数据转存到本地的data node上
- Storefile 变大, Region 也随之变大, 达到阈值后, 会触发 Split 操作, 将 Region 一分为二