hbase的写入性能远超一般的关系数据库,而且读取性能也不差。原理是怎么样的呢,这里主要是用到了LSM算法。
1 传统关系性数据库查询,主要是基于索引。 大部分都是B树和B+数来实现。
有关B,B+树的数据结构可以参考如下2篇文章:
B树_程序袁小黑-优快云博客_b树 :https://blog.youkuaiyun.com/ydonghao2/article/details/82286580
https://www.cnblogs.com/xueqiuqiu/articles/8779029.html
B 树很好的实现了大量数据的查询。查询复杂度O(log2 N), 基本上比较稳定,索引大量使用。
2 LSM原理
参考文档:https://www.zhihu.com/question/19887265
2.1 日志写。
日志文件一般都是顺序写, 我们知道顺序写比随机写要高好几个数量级。而日志文件读确不是那么快。
2.2 日志文件读 一般的优化措施
- 二分查找: 将文件数据有序保存,使用二分查找来完成特定key的查找。
- 哈希:用哈希将数据分割为不同的bucket
- B+树:使用B+树 或者 ISAM 等方法,可以减少外部文件的读取
- 外部文件: 将数据保存为日志,并创建一个hash或者查找树映射相应的文件。
- 所有的方法都可以有效的提高了读操作的性能(最少提供了O(log(n)) ),但是
上述读优化方法天生又反顺序写,当我们需要更新hash或者B+树的结构时,需要同时更新文件系统中特定的部分,这就是上面说的比较慢的随机读写操作,而修改顺序写文件这种随机的操作要尽量减少。
所以这就是 LSM 被发明的原理, LSM 使用一种不同于上述四种的方法,保持了日志文件写性能,以及微小的读操作性能损失。
具体的: HBase是如何实现LSM的呢?
Hbase写入时,先写内存Memstore,memstore有序排列定时刷新到磁盘即HFile,这些文件写磁盘即为顺序写,性能超快。
当有数据更新时,也是先写到内存区域memstore, 定时flush为HFILE,后续再合并小的HFILE为大的文件。减少文件扫描数量。
注: 这里的HFILE实际上也是以B数结构存储,类似与传统关系型数据库的索引查找单个查询也是比较快速的。
当HFILE读取操作时,首先会查询内存区域,命中的话很快。如果没有找到会查最近活动的block cache,再后会查指定的数据分区。往往会查询多个分区,访问数据。 因此会略微损失部分查询性能。 但是鉴于HBase是基于region server分布式查询,所以性能也不会差。
总结: LSM 是日志和传统的单文件索引(B+ tree,Hash Index)的中立,他提供一个机制来管理更小的独立的索引文件(sstable)。
通过管理一组索引文件而不是单一的索引文件,LSM 将B+树等结构昂贵的随机IO变的更快,而代价就是读操作要处理大量的索引文件(sstable)而不是一个,另外还是一些IO被合并操作消耗。