HBase写流程:
从客户端创建连接开始到刷写落盘到hdfs结束。
- 客户端向ZK发送请求创建连接;
- 读取ZK存储meta表是由哪个RegionServer管理;
- 访问ZK返回的RegionServer上的meta表;
- 将读取的meta表作为属性保存作为MetaCash缓存(1-4说明这种连接是重量级的);如果meta表发生变化需要重新读取缓存;
- 客户端发送put命令到RegionServer,解析RowKey,对照缓存的MetaCash,找到具体写入的位置有哪个RegionServer
- RegionServer将请求写入WAL并落盘到hdfs,之后再写入到对应的MemStore并排序,由此可知,HBase也只能保证单文件是有序的;如果数据是顺序写入的,此时的写入会直接落盘(先写入到WAL因为数据会在MemStore保存一段时间并排序,期间如果发生意外会导致数据丢失是不安全的);
- 等待触发刷写条件后,会写入到对应的store,生成新的文件HFile(StoreFile);
MemStore Flush 刷写:
MemStore刷写由多个线程控制,条件相互独立。
(1)当某一个memstore的大小达到了hbase.hregion.memstore.flush.size(默认128M),这个region对应的所有memstore都会进行刷写(一个region可以有多个store,每一个store都对应一个memstore);需要注意,这种刷写模式可能会由于一个memstore达到128M而有的memstore十分小;为了避免这种情况的发生,由于每个store存储的是列簇和列,在进行表设计时,应尽可能保证列簇之间的列的数量与内容尽量均匀。
当memstore的大小达到了hbase.hregion.memstore.flush.size(默认128M)*hbase.hregion.memstore.block.multiplier(默认值是4)时,会刷写并阻止往该memstore继续写入数据,以保证数据的安全性。
(2)水位线刷写:
- 低水位线:hbasejvm内存x0.4x0.95,达到会进行刷写(因此官方建议避免使用过多的列簇);
- 高水位线:hbasejvm内存x0.4,达到会阻止继续往所有的memstore写入数据。
(3)时间:避免数据长时间处于内存中,5min自动监控数据一次,查看数据是否存储在内存中超过一小时,达到1小时刷写一次
HFile:
读取的数据是存储在HDFS上每一个store文件夹下实际存储数据的文件HFile,存储了包括数据本身(KV键值对)、元数据记录,文件信息,数据索引,元数据索引和一个固定长度的尾部信息(记录文件的修改情况)。
HBase读流程:
hbase->data->namespace->表名->regionId->列簇名->进入store,里面是HFile
读流程从客户端创建连接开始,到合并数据返回客户端结束。
- 客户端向ZK发送请求创建连接;
- 读取ZK存储meta表是由哪个RegionServer管理;
- 访问ZK返回的RegionServer上的meta表;
- 将读取的meta表作为属性保存作为MetaCash缓存(1-4说明这种连接是重量级的);如果meta表发生变化需要重新读取缓存;
- 客户端发送get请求给RegionServer;
- RegionServer将请求写入WAL并落盘;
- 读取BlockCache(BlockCache缓存的是元数据信息),去对应的store查找数据,看是否发生变化,发生变化读缓存会重新读取;
- 读取对应store的写缓存数据,看是否有新写入的数据,有的话读缓存会重新读取;并读取对应的store的数据;
- 合并所有读取的数据并返回给客户端(高版本数据覆盖低版本数据)
Store File Compaction 合并:
Minor Compaction:小合并:将邻近的若干个小HFile合并成较大的HFile,清理部分过期和删除的数据
Major Compaction:大合并:将一个store下所有HFile全部合并,清理所有过期和删除的数据,由参数hbase.hregion.majorcompaction控制,默认是七天。