暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

LSM学习分享——LSM读写流程


    大家好,我是春哥,最近在学习LSM,这是很多数据库存储引擎的底层数据结构。想和大家分享一下,我有讲的不对的地方请大家加我微信指正。

LSM读写示意图

LSM树的写入流程:

     1、当收到一个写的请求时,会把这个操作写入到WAL日志中,用作故障恢复。

     2、写完wal之后会把这条数据写入sstable的内存中Memtable。

    3、当Memtable超过一定的大小后,会在内存里面冻结,变成不可变的Memtable,同时为了不阻塞写操作需要新生成一个Memtable继续提供服务

     4、把内存里面不可变的Memtable给dump到硬盘上的SSTable层中,此步骤也称为Minor Compaction,这里需要注意在L0层的SSTable是没有进行合并的,所以这里的key range在多个SSTable中可能会出现重叠,在层数大于0层之后的SSTable,不存在重叠key。

     5、当每层的磁盘上的SSTable的体积超过一定的大小或者个数,也会周期的进行合并。此步骤也称为Major Compaction,这个阶段会真正 的清除掉被标记删除掉的数据以及多版本数据的合并,避免浪费空间,注意由于SSTable都是有序的,所以可以直接采用merge sort进行高效合并。

LSM读取流程: 

     当收到一个读请求的时候,会直接先在内存里面查询,如果查询到就返回。如果没有查询到就会依次下沉,知道把所有的Level层查询一遍得到最终结果。

提出问题:

       从图中和读取流程我们会发现,SSTable的分层越多,最坏的查询情况就是会把所有的分层都遍历一遍,对于这种情况,优化方式一般有:压缩、缓存、布隆过滤器和合并四种方式。其中,合并在LSM学习分享——初识LSM中已经有提到,可以有效清除无效数据,提高磁盘的利用空间。


       但Compaction操作是非常消耗CPU和磁盘IO的,尤其是在业务高峰期,如果发生了Major Compaction,则会降低整个系统的吞吐量,这也是一些NoSQL数据库,比如Hbase里面常常会禁用Major Compaction,并在凌晨业务低峰期进行合并的原因。

HBase的写入流程:


      HBase中只有增添数据,所有更新和删除操作都在后续的合并中进行,使得用户的写操作只要进入内存就可以立刻返回,实现了hbase的高速存储。Hbase使用memstore和storefile存储对表的更新。

      (1)首先数据在写入的时候会先写入写前日志hlog

      (2)然后先将数据写入metastore,当metastore中的数据达到一定的阈值的时候,此时就会将数据flush到磁盘上成为一个Storefile

      (3) 随着Storefile的数量不断增多,再次达到一个阈值之后,就会触发compact操作,将多个的storefile合并成一个,并进行版本的合并和数据的删除

      (4)当storefile的文件通过compact合并成越来越大的文件以后,就会触发split操作,把当前Region Split成2个新的Region,父Region会下线,新Split出的2个子Region会被HMaster分配到相应的RegionServer上,使得原先1个Region的压力得以分流到2个Region上。


flush,compact,split 这也就是我们所说的HBase的三大机制


学习小结:

       LSM树的思想大体上可以理解为:

      (1)使用写前日志来保障数据的高可用性

      (2)对于不断append的数据首先写入在内存中,以便在读取的时候可以快速 的返回,这也算是对读性能的一个优化吧

      (3)然后merage/compact越来越大的文件,落地到下一层,采用有序的结构,以便于进行高效的合并,减少数据冗余,保证读取速度相对快速


      这种思想适合于写多,读少的场景,或者读取最新数据多的场景,因为他们被缓存在内存中,可以快速的返回,不需要磁盘io操作。



文章转载自春哥的嵌入式小世界,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论