C++,python,热爱算法和机器学习
全部博文(1214)
分类: 大数据
2017-11-10 09:30:02
最近, 继续查阅资料, 对Hbase有了一些了解, 所以有了这篇文章.
本文尝试将Hbase的理论以及跟现实中Hadoop框架结合, 最后阐述Hbase的基本结构为什么是这个样子, 文本篇幅有限, 如果读者对一些概念不清楚, 可以google以获取更详细的解释。
说到Hbase, 首先我们需要了解一下LSM模型, 这是支撑Big Table论文的重要组成部分, 下面是它的简单介绍.
LSM(Log Structure Merge Tree) - 原理是, 对于写操作, 首先将数据Log到内存中, 当内存中的Log超过容量, 将Flush到磁盘上形成一个Tree File, 当Flush的文件数量超过限制, 这时会执行Merge操作, 最后形成一个大的Tree File.
由于数据都在内存上, 为了防止Server宕机造成数据丢失, 这里就又增加了一个操作, HBase中称为WAL, 就是在写数据到内存之前, 先将这次操作Log到一个文件中, 该文件类型下文再介绍.
所以LSM在写的时候, 并没有random write disk的操作, write的性能能得到很大的提升.
HDFS的文件类型倾向的是大文件的顺序读和顺序写, 这与Hbase想要实现的功能 - 随机读,随机写是冲突的, 那么Hbase又是做了那些事使它能够兼容HDFS?
先来介绍HDFS支持的两种文件类型: SequnceFile和MapFile.
SequenceFile - 简单来说是一个支持Key, value对的文件类型, 写支持Append操作, 读是顺序读取, 所以它是一种类似Log File的类型。
MapFile - MapFile是在SequenceFile的基础上做了一些封装。
> MapFile也是Key, Value对, 但是它的数据是按照Key排序的.
> MapFile对随机读做了一些优化, 它实际上还保存了一个Index文件, 存储一些key, Value的偏移量(一些是指MapFile并不会把所有Record都记录到index中去,默认情况下每隔128条记录存储一个索引映射。当然,记录间隔可人为修改).
那么, Hbase的早期设计者, 就是利用SequenceFile和MapFile实现Hbase的WAL, 随机读和随机写功能.
使用MapFile可以轻松实现了随机读, 但是上述的两种文件类型都不支持随机修改和删除, 因此Hbase对于删除的操作, 就对对这条数据Mark一下删除标志, 然后Log到内存中, 这样某一Cell有多次写的操作, 在读取该Cell的, 会有多条结果, 为判断那一次的更新是最后的操作, 对于每一个Cell, Hbase增加了timestamp. 这也可以解释为什么存储的数据有timestamp.
对于WAL功能来说, 就比较简单了, SequenceFile天然解决。
实际上, 早期的Hbase版本存放Tree File就是MapFile类型, 后来Hbase开发人员借鉴MapFile的思想, 自己实现了性能更好的HFile, HFile相对与MapFile而言, 有以下的改变
> 将Index和Data两个文件合并成了一个文件.
> 存放了更多的信息, 例如Bloom Filter, Meta Data, 等等, 以减少随机读的磁盘IO的次数.
当然HFile也经历了几次版本变迁, 感兴趣的读者可以另外Google.
上文已经提到了写的时候先写到内存中, 那么读取的时候, 直接访问该内存来获取数据会明显提高读取的性能, 而该内存模型在Hbase中叫做Memstore.
当查询的数据不在Memstore中, 而Hbase又不想马上在磁盘上寻找, 所以提出了Block Cache的概念, 简单理解就是将HFile中的Data Block缓存到内存中, 减少Disk I/O.
可以看出, HBase中存在的很多的数据模型, 但是他们当中的大多数目的都相同 - 提高Hbase的随机读写的性能.