客户端读取表中的某一行数据时的流程:
1.客户端向ZK发送请求,获取meta所在的 region
2.去meta表获取该rowkey的数据所在的 region
3.去该rowkey所对应的 region 查找数据,先从写缓存(MEMStore)中获取数据
4.若未从写缓存(MEMStore)中获得数据,则从客户端的读缓存中获取
5.若也未从客户端的读缓存中获得数据,则从磁盘(StoreFile)获取数据
6.从磁盘获取数据时,先将数据放入客户端的读缓存,再将数据返回给客户端
ps: meta元数据所在的表永远不会进行切分; 不同列族对应着不同的 StoreFile
总结:
读数据总共要请求3次(3个节点),才能获得数据:
① Zookeeper
② meta所在的RS(HRegionServer)
③ 目标数据所在的RS
注:在0.9版本以前的老版本中,有个 _ROOT_ 节点,每次请求是从ZK中获取到 _ROOT_节点所在RS,再从该RS中
获得meta所在的RS,再从meta元数据中获取目标数据所在的RS,最终才获取到目标数据。
客户端往表中写入一行数据时的流程:
1.客户端向ZK发送请求,获取meta所在的 region
2.去meta表获取要写入的rowkey所对应的 region
3.往该rowkey所对应的 region发送写请求,先将数据写到 Hlog 中
4.再将数据写到写缓存(MEMStore)中
5.一定时间后刷新缓存时,就会将不同列族的数据写到不同的StoreFile(磁盘)中
注:在源码中其实显示,写数据时其实是先写到 MEMStore 中,然后才往Hlog中写的。
但是,如果Hlog中写失败了,那么 MEMStore 中刚刚的写操作就会进行回滚,导致最终未写成功。
因此,其实就等于先确定Hlog的写成功,才能确定 MEMStore 中是否最终写成功!
所以,既可以说是先写的Hlog,也可以说是先写的 MEMStore