数据修改
小史:不过吕老师,我还有问题啊,我记得 HDFS 是不能随机修改文件的,只能追加,那么 HBase 里的数据是不是写了之后就不能改也不能删除呢?
吕老师:删除同样是追加一条版本最新的记录,只不过标记这个数据被删除而已,查询的时候,看到版本最新的记录是数据删除,就知道这个数据被删了。
吕老师:哈,小史,你思考得非常深入,还记得 LSM 的第三层吗,HBase 会在合并的时候,将这些用不到的记录删除掉,节省存储空间。
吕老师:不全对,其实 HBase 把合并分为两种:
- 小合并 Minor Compact,这种方式只会将少数文件进行简单合并,不会进行数据的清理。
- 大合并 Major Compact,这种方式会将大部分文件进行合并,并且清理数据。
吕老师:基本正确,但是你要知道,如果数据量大,这个过程是非常耗性能的,一般在生产环境都禁止大合并,否则在正常服务的时候突然来个大合并,整个集群可能资源被耗光,没法正常服务。
HBase 架构
小史:HBase 的架构似乎也是 master-slave 架构,和 HDFS 有点像,HMaster 是用来管理集群,HRegionServer 是真正存储数据的地方吧?
吕老师:啊,这块不太对,HBase 在数据查询和写入的时候,其实并不是像 HDFS 那样询问 HMaster。
在 HBase 中,每一张表都会有元信息,这些信息也是被存储为 HBase 表,称为元信息表,也叫 Meta 表,这是一种系统表。
小史:但是这又有个问题,既然 Meta 表也是存储在 HBase 上,那么 HBase 又如何知道 Meta 表存在哪个 HRegionServer 上呢?这岂不是一个鸡生蛋蛋生鸡的问题?
吕老师:小史啊,我说 Meta 表是 HBase 表,是指 Meta 表也是用 Rowkey 和 Value 的键值存储,但是我并没有说 Meta 表在 HBase 上啊。
其实 Meta 表不是存储在 HRegionServer 上,而是存储在那个分布式协调服务 Zookeeper 上面。
小史:哦,原来如此,所以 Meta 表其实是在一个固定地方读取,然后根据 Meta 表就知道数据在哪个 HRegionServer 上。但是 Zookeeper 又是啥呢?
吕老师:其实 HMaster 的任务相对不繁重,但是却比较重要,它主要是通过调整和管理 Region 分布来实现 HRegionServer 的负载均衡。
HRegionServer 架构
吕老师:其实 Region 是 HBase 在 Rowkey 上的切分,每个 Region 都可以通过 StartKey 和 EndKey 来确定 Rowkey 的范围,一个 HRegionServer 上可能会有多个 Region。
小史:所以说数据是根据 Rowkey 和一定的哈希规则,分散到不同的 Region 上面,而 Region 又是属于某一个 HRegionServer 上的,这个关系没错吧?
吕老师:没错,通过这里其实可以得出 Rowkey 设计的另一个原则,就是散列性。
Rowkey 的头几个字母,最好不要是一样的,不然会分布在同一个 HRegionServer 上面,导致这个 HRegionServer 的负载非常高,累死累活,其他 HRegionServer 却没事干。
一般可以根据一定规则算一个数据的摘要,比如 MD5,把 MD5 的头几位拼在 Rowkey 的前面。
吕老师:哈哈,名词没讲过,原理可都是讲过的哟。比如这个 Store,我们之前说过,一个列簇中的列是存储在一起的,对应到这里,一个列簇中的数据就是存到一个 Store 中。
吕老师:没错,这里 StoreFile 只是一个名字,它是以 HFile 的格式存储在 HDFS 上,HFile 是一个存储格式,在新版本的 HFile 存储格式中,它就是一个类似 B+ 树的索引形式。
读取和写入流程
①HBase Client 要写输入了,先从 Zookeeper 中拿到 Meta 表信息,根据数据的 Rowkey 找到应该往哪个 RegionServer 写。
②然后 HBase 会将数据写入对应 RegionServer 的内存 MemStore 中,同时记录操作日志 WAL。
③当 MemStore 超过一定阈值,就会将内存 MemStore 中的数据刷写到硬盘上,形成 StoreFile。
④在触发了一定条件的时候,小的 StoreFile 会进行合并,变成大的 StoreFile,有利于 HDFS 存储。
吕老师:当大量 Rowkey 相近的数据都被分配到一个 Region 中,导致这个 Region 数据过大的时候,Region 会进行拆分,HMaster 会对拆分后的 Region 重新分配 RegionServer,这是 HMaster 的负载均衡策略。
①HBase Client 要读数据了,先从 Zookeeper 中拿到 Meta 表信息,根据要查的 Rowkey 找到对应的数据在哪些 RegionServer 上。
②分别在这些 RegionServer 上根据列簇进行 StoreFile 和 MemStore 的查找,得到很多 key-value 结构的数据。
③根据数据的版本找到最新数据进行返回。
OLTP 和 OLAP
吕老师:OLTP 应用叫联机事务处理应用,就是类似银行转账等业务的,这类应用对事务要求比较高。
而 OLAP 应用叫联机分析处理应用,比如推荐系统,是在收集了大量用户行为后进行分析,再得出结论的应用,主要侧重分析,对事务要求非常低。
总结
小史把这次学习到的 HBase 的知识记了下来:
- HBase 是列式存储,和 MySQL 的行式存储不一样。
- HBase 中有列簇概念,同一个列簇下的列存储在一起,在 Region 的一个 StoreFile 中。
- HBase 是按照 Rowkey 进行查找,要查询的字段要想办法放到 Rowkey 中。
- HBase 内部使用 LSM 三层模型进行存储,数据先写到内存的 MemStore 中,内存达到一定阈值再刷写到硬盘 StoreFile 中,再满足一定条件时,小的 StoreFile 会合并为大的 StoreFile。
- HBase 适合 OLAP 类的应用。
学完 HBase,记完笔记,小史开开心心地洗袜子去了。
作者:channingbreeze
编辑:陶家龙、孙淑娟