Sorry!Hbase的LSM Tree就是能够随心所欲!

咱们先抛出一个问题:算法

file

LSM树是HBase里使用的很是有创意的一种数据结构。在有表明性的关系型数据库如MySQL、SQL Server、Oracle中,数据存储与索引的基本结构就是咱们耳熟能详的B树和B+树。而在一些主流的NoSQL数据库如HBase、Cassandra、LevelDB、RocksDB中,则是使用日志结构合并树(Log-structured Merge Tree,LSM Tree)来组织数据。数据库

首先,咱们从B+树讲起

为何在RDBMS中咱们须要B+树(或者广义地说,索引)?一句话:减小寻道时间。在存储系统中普遍使用的HDD是磁性介质+机械旋转的,这就使得其顺序访问较快而随机访问较慢。使用B+树组织数据能够较好地利用HDD的这种特色,其本质是多路平衡查找树。一个典型的B+树以下图所示:性能优化

file

  • B+树的磁盘读写代价更低:B+树的内部节点并无指向关键字具体信息的指针,所以其内部节点相对B树更小,若是把全部同一内部节点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多,一次性读入内存的须要查找的关键字也就越多,相对IO读写次数就下降了。数据结构

  • B+树的查询效率更加稳定:因为非终结点并非最终指向文件内容的结点,而只是叶子结点中关键字的索引。因此任何关键字的查找必须走一条从根结点到叶子结点的路。全部关键字查询的路径长度相同,致使每个数据的查询效率至关。性能

  • 因为B+树的数据都存储在叶子结点中,分支结点均为索引,方便扫库,只须要扫一遍叶子结点便可,可是B树由于其分支结点一样存储着数据,咱们要找到具体的数据,须要进行一次中序遍历按序来扫,因此B+树更加适合在区间查询的状况,因此一般B+树用于数据库索引。大数据

若是你对B+树不够熟悉,能够参考这里:http://www.javashuo.com/article/p-dgncxeef-cp.html优化

那么,B+树有什么缺点呢?

B+树最大的性能问题是会产生大量的随机IO,随着新数据的插入,叶子节点会慢慢分裂,逻辑上连续的叶子节点在物理上每每不连续,甚至分离的很远,但作范围查询时,会产生大量读随机IO。.net

LSM Tree

为了克服B+树的弱点,HBase引入了LSM树的概念,即Log-Structured Merge-Trees。设计

LSM Tree(Log-structured merge-tree)起源于1996年的一篇论文:The log-structured merge-tree (LSM-tree)。当时的背景是:为一张数据增加很快的历史数据表设计一种存储结构,使得它可以解决:在内存不足,磁盘随机IO太慢下的严重写入性能问题。指针

LSM Tree(Log-structured merge-tree)普遍应用在HBase,TiDB等诸多数据库和存储引擎上:

file

咱们来看看大佬设计这个数据结构:

file

Ck tree是一个有序的树状结构,数据的写入流转从C0 tree 内存开始,不断被合并到磁盘上的更大容量的Ck tree上。因为内存的读写速率都比外存要快很是多,所以数据写入的效率很高。而且数据从内存刷入磁盘时是预排序的,也就是说,LSM树将本来的随机写操做转化成了顺序写操做,写性能大幅提高。不过它牺牲了一部分读性能,由于读取时须要将内存中的数据和磁盘中的数据合并。

回到Hbase来,咱们在以前的文章中《Hbase性能优化手册》中提到过Hbase的读写流程:

file

MemStore是HBase中C0的实现,向HBase中写数据的时候,首先会写到内存中的MemStore,当达到必定阀值以后,flush(顺序写)到磁盘,造成新的StoreFile(HFile),最后多个StoreFile(HFile)又会进行Compact。

memstore内部维护了一个数据结构:ConcurrentSkipListMap,数据存储是按照RowKey排好序的跳跃列表。跳跃列表的算法有同平衡树同样的渐进的预期时间边界,而且更简单、更快速和使用更少的空间。

file

HBase为了提高LSM结构下的随机读性能,还引入了布隆过滤器(建表语句中能够指定),对应HFile中的Bloom index block,其结构图以下所示。

file

经过布隆过滤器,HBase就能以少许的空间代价,换来在读取数据时很是快速地肯定是否存在某条数据,效率进一步提高。

欢迎关注,《大数据成神之路》系列文章

欢迎关注,《大数据成神之路》系列文章

欢迎关注,《大数据成神之路》系列文章

相关文章
相关标签/搜索