写入数据
写入数据的过程
- 通过行键 ==》 哪个region ==》regionServer ==》region
- 通过列族 ==》 region中某个store
- 先向hlog里插入操作记录 ==》 把数据直接放入 memStore ==》 返回写入成功
- 后台去把memStore的数据Flush到StoreFile
写入数据的思想
- 为了提高写入速度,使用了基于内存的memStore。虽然hlog依旧是存储在hdfs上的,由于针对hlog的写入是连续性的(一般机械硬盘速度最高峰100m/S),速度依然很理想。实质上是把对storeFile的随机写入转为了针对hlog的连续写入,提高写入性能
- 基于内存的memStore断点数据丢失的解决方案:当某个server挂掉,另外一个server来接替时,会从zookeeper中获取最后一次写出数据的信息,然后从hlog恢复memStore中丢失的数据
- 一个regionServer使用一个hlog,而不是一个region一个hlog。
- 基于内存的memStore空间满了的解决方案:若memStore满了,则重新开一个新的memStore,同时开一个线程把满了的memStore的数据写入storeFile,然后清空旧的memStore,最后向zookeeper里记录最后写出数据时间的redo point信息
- 垃圾数据的产生:由于hdfs只能追加数据的特性,hbase对数据的修改,其实是不停创建新的storefile的过程。这样多个storefile中可能存在对同一个数据的多个版本,其中旧的版本其实是垃圾数据。
- 垃圾数据的清理:当达到一定的阈值的时候,master会自动合并storefile, 在合并的过程中将垃圾数据清理,而当合并出来的文件达到一定程度时,master再重新进行切分防止文件过大。
读取数据
- 找到具体的StoreFile(过程与写入数据一样)
- 在索引块中查找,若没有找到,则说明整个StoreFile里没有对应数据
- 若在多个StoreFile中都找到了对应数据的datablock,则直接把所有dataBlock返回给查询程序,由查询程序去组装这些数据后返回。
通过行健寻找Region
在hbase中有一个hbase:meta表,其中存放了表和region和regionSever之间的对应关系。这个表只有一个region, 这个region的位置信息被存放在了zookeeper的meta-region-server节点下。
每次操作数据前,先去zookeeper的meta-region-server节点下,找到meta表的region对应regionServer的地址,然后通过meta表得到自己需要操作的数据对应的region及regionServer。
写数据时Region分裂
刚开始数据少只有一个region,随着数据的增加,当达到某个阈值(可配置),则会分裂为多个region。数据越来越多,会继续分裂。
memStore缓存导致查询多余版本数据
定义表的时候,若定义version=3,则在hdfs上真正保存的也只有三个版本的信息。但是如果scan表的时候,指定version=5,最近五个版本的信息都会展示出来。是因为在内存里有缓存。
若是停止hbase然后重启hbase,再去scan,只会有三个版本的信息展示出来。因为内存会释放,数据真正的从hdfs上加载出来。