一、写流程
1.当HRegionServer接收到写请求的时候,会先将这个写请求记录到WAL中,记录成功之后会在将数据更新到memStore中
2.数据在memStore中会进行排序,按照 行键字典序 > 列族名字典序 > 列名字典序 > 时间戳倒序 来进行排序
3.当达到冲刷条件的时候,memStore会自动冲刷产生HFile。因为memStore中的数据已经排序,所以冲刷出来的单个HFile中的数据是有序的。所有的HFile之间是局部有序整体无序。
4.HFile最终会以Block形式落地到HDFS的DataNode上
5.HFile的v1
1)DataBlock:数据块,用于存储数据
DataBlock的结构
- 每一个HFile中包含1个到多个DataBlock,DataBlock是数据存储的基本结构/最小单温
- 因为HFile中的数据是有序的,所以切分出来的DataBlock之间的数据是不交叉的
- 每一个DataBlock默认是64KB。小的DataBlock利于查询(get),大的DataBlock利于遍历(scan)
- 每个DataBlock都是由1个Magic(魔数)以及1到多个KeyValue来构成
Magic魔数:本质上就是一个随机数,用于校验的
KeyValue:存储数据,每一条数据最终都会以键值对形式来存储
2)MetaBlock:元数据块,用于存储元数据。注意,不是所有的HFile都包含这一部分,一般只有hbase:meta表对应的HFile会包含这一部分
3)FileInfo:文件信息,用于记录HFile大小,所属HStore等信息
4)DataIndex:数据索引,用于记录DataBlock的索引
5)MetaIndex:元数据索引,用于记录MetaBlock的索引
6)Trailer:在文件末尾,占用固定的字节大小,用于记录FileInfo,DtaIndex和MetaIndex在文件中的起始字节
6.在HFile的v2版本中,引入了BloomFilter(布隆过滤器)
BloomFilter在使用的时候,需要定义一个字节数组和3个不同的哈希函数
当有了数据之后,利用3个哈希函数对这个数据进行映射,映射到数据的不同位置上。
在BloomFilter中,如果映射到了0,那么说明这个元素一定不存在;但是如果映射到了1,不代表元素存在。
那么在新增/删除/修改的时候还要去维护BloomFilter吗?
BloomFilter的优势在于理解和实现过程相对容易,但是劣势也同样明显:随着元素个数的越多,数组中空闲的位置会越来越少,此时误判率也会越来越高,解决方法是数组扩容。
感觉适合读多写少的场景,用来避免缓存穿透。因为增/删/改的时候还要维护布隆过滤器?
二、读流程
1.当HRegionServer接收到读请求时,会先试图从BlockCache中获取数据
2.如果BlockCache中没有数据,则会试图从memStore中获取
3.如果memStore中没有数据,那么试图从HFile中获取。在读取HFile的时候,会先根据行键范围进行筛选,筛选掉不符合范围的HFile,但是不代表剩余的HFile中一定有找的数据。帅选完成之后,如果开启了布隆过滤器,那么可以利用布隆过滤器再次筛选,被筛选掉的文件一定没有要找的数据(一个文件对应一个布隆过滤器),但是不代表剩余的文件中有要找的数据