Region是HBase数据存储和管理的基本单位。在HBase的一个表中,可以包含一个或多个region。对于一个region,每个列族都会对应一个store,用来存储该列族的数据。每个store都有一个写缓存memstore,用于缓存写入的数据。
    【写过程】
    1、Client先从缓存中定位region,如果没有缓存则需访问zookeeper,从.META.表获取要写入的region信息
    2、找到小于rowkey并且最接近rowkey的startkey对应的region
    3、将更新写入WAL中。当客户端发起put/delete请求时,考虑到写入内存会有丢失数据的风险,因此在写入缓存前,HBase会先写入到Write Ahead Log(WAL)中(WAL存储在HDFS中),那么即使发生宕机,也可以通过WAL还原初始数据。
    4、将更新写入memstore中,当增加到一定大小,达到预设的Flush size阈值时,会触发flush memstore,把memstore中的数据写出到hdfs上,生成一个storefile。
    5、随着Storefile文件的不断增多,当增长到一定阈值后,触发compact合并操作,将多个storefile合并成一个,同时进行版本合并和数据删除。
    6、storefile通过不断compact合并操作,逐步形成越来越大的storefile。
    7、单个stroefile大小超过一定阈值后,触发split操作,把当前region拆分成两个,新拆分的2个region会被hbase master分配到相应的2个regionserver上。
    【读过程】
    1、Client先从缓存中定位region,如果没有缓存则需访问zookeeper,查询.-ROOT-.表,获取.-ROOT-.表所在的regionserver地址。
    2、通过查询.-ROOT-.的region服务器 获取 含有.-META-.表所在的regionserver地址。
    3、clinet会将保存着regionserver位置信息的元数据表.META.进行缓存,然后在表中确定待检索rowkey所在的regionserver信息。
    4、client会向在.META.表中确定的regionserver发送真正的数据读取请求。
    5、先从memstore中找,如果没有,再到storefile上读。
    【为什么HBase查询速度快】
    采用了LSM树型结构(日志结构合并树),而不是B或B+树。
    B+树最大的性能问题是会产生大量的随机I/O,低下的磁盘寻道速度。
    为了读性能的提高,数据在磁盘中必须有序,这就是B+树的原理。但是写就悲剧了,key跨度很大的情况,新插入的数据存储在磁盘上相隔很远的地方,会产生大量的随机IO,磁盘寻道速度跟不上。
    对于LSM树来说,牺牲了部分读性能,来大幅提高写性能。
    原理是:将一颗大树拆分成N颗小树,首先写入内存(内存中的数据是有序的,内存没有寻道速度的问题,随机写的性能得到大幅提升),在内存中构建一颗有序小树(memstore),随着其越来越大,flush到磁盘上,成为一个storefile,该storefile中的数据是有序的。