LSM(Log-Structured Merge Tree)

  • Post author:
  • Post category:其他




一、什么是LSM Tree


LSM Tree

全称

日志结构合并树



Log-Structured Merge Tree

)。对于存储介质为

磁盘



固态盘

的数据库,长期以来主流使用

B+树

这种索引结构来实现快速数据查找。当数据量不太大时,B+树读写性能表现非常好。但是在海量数据情况下,B+树越来越高,由于B+树更新和删除数据时需要沿着B+树逐层进行

页分裂



页合并

,严重影响数据

写入性能

。为了解决这种情况,google在论文《

Bigtable: A Distributed Storage System for Structured Data

》中介绍了一种新的数据组织结构LSM Tree(Log-Structured Merge Tree),

LSM Tree

是其中着重介绍的一种新的

分布式存储系统

的一个

理论模型

。LSM Tree的存储架构设计在

机械盘

时代大方异彩,同时也是一个把

顺序写

发挥到极致的设计架构,核心之一是

log文件

。当前比较流行的NoSQL数据库,如Cassandra、RocksDB、HBase、LevelDB等,newSQL数据库,如TIDB,都是使用LSM Tree来组织磁盘数据的。



二、基本原理简述


LSM Tree

是一个

分层



有序



针对块存储设备



HDD



SSD

)特点而设计的

数据存储结构

。他的核心理论基础还是磁盘的

顺序写

速度比

随机写

速度快非常多,即使是SSD,由于块擦除和垃圾回收的影响,顺序写速度还是比随机写速度快很多。

在这里插入图片描述



2.1 SSTable和Level

LSM Tree将存储数据切分为一系列的

SSTable



Sorted String Table

),并将SSTable分为

Level 0 - Level N

。每个SSTable内的数据都是

有序

的任意字节组,并且SSTable一旦写入磁盘中就像日志一样

无法修改

。对于LSM Tree若需要修改或者删除数据并不是直接对旧数据进行操作,而是将新数据写入新的SSTable中。若需删除数据则是写一个相应数据的删除标记的记录到一个新的SSTable中。依照这种方法也确保了LSM Tree写数据时对磁盘的操作都是顺序块写入操作,而没有随机写操作。

LSM Tree这种独特的写入方式,导致在查找数据的时候,LSM Tree 不能像B+ Tree那样在一个统一的索引表中进行查找,而是从最

新的SSTable



老的SSTable

中依次进行查找。如果在新的SSTable中找到了需要查找的

数据

或者相应的

删除标记

,则直接返回查找结果;若没找到,再到老的SSTable中进行查找,直到老的SSTable查找完。为了提高查找效率,LSM Tree对SSTable进行分层、有序组织,就是将SSTable组织成

多层

,同一层可以有多个SSTable,并且每个SSTable内的数据是有序的,前一个SSTable的最大数据值小于后一个SSTable的最小数据值(实际情况更加复杂),以达到提升在同一层SSTable的查询效率。同时,LSM Tree会将多个SSTable合并(Compact)为一个新的SSTable,这样可以减少SSTable的数量,同时把修改前的数据或删除的数据真正从SSTable中删除,减少SSTable的大小(这就是LSM中

Merge

(合并)的由来),对提高查找性能起到了极其重要的作用。



2.2 分布式存储系统(BigTable)



2.2.1 数据模型

BigTable本质上是一个为

稀疏结构化数据

设计的

分布式多维排序Map

。这里的“稀疏”指的是对于某一个结构化对象,有大量

属性



缺失

的,且多个对象之间缺失的

属性分布

也很

分散

。Map的Key由三个部分组成,分别是Row、Column Family:Column、Timestamp。


  • Row

    (行)

    行是

    结构化对象

    的一个实例。在BigTable中行是根据Key用

    字典序排序存储

    的。BigTable支持单行级别的

    原子更新操作

    ,客户端无须在并行调用场景关系行操作的原子性。

  • Column Family

    (列簇):

    Column

    (列)


    列簇

    是多个

    列的集合

    。一般情况下,存储在同一个列簇中的数据具有同样的类型,并且会压缩在一起。列簇还是

    访问权限控制



    最小单元


  • Timestamp

    (时间/版本)

    Timestamp是一个64-bit的时间版本号。BigTable可以存储同一份数据的

    多个版本

    ,并支持按照版本进行访问。Timestamp可以由客服端自行指定,或由BigTable实时生成。



2.2.2 组件

  • Tablet

    Tablet是

    数据调度



    最小单位

    ,由一个

    Key Range

    组成,包含了这个Key Range中的所有数据。每一行Key又包含了多个列簇,同一个列簇内的数据被

    压缩

    并存放在SSTable中。

    SSTable是Google内部的

    持久化KV存储结构

    ,将数据按Key排序存储实现高效检索。SSTable被创建过后,不可对其内容进行更改,属于“

    只读结构

    ”。SSTable内部由多个

    Block

    组成,每个Block默认大小为

    64KB

    ,在SSTable的最后存放Block的索引信息。

    使用SSTable时,首先将Block索引信息加载到

    内存

    中;检索时,首先通过二分查找检索

    Block索引

    确定Block,再从磁盘读取该Block的数据。这样设计可以更好的利用磁盘的顺序读取特性,提高

    查找性能

    。同时SSTable也可以直接

    映射



    内存

    中。

    在这里插入图片描述
  • MemTable

    前面介绍到的SSTable是不可变的,若需对BigTable实现增删改操作就要用到MemTable。

    MemTable是存放在内存中的

    数据结构

    ,当发生

    变更操作

    时,首先对MemTable进行写入;同样,读取数据时,就同时读取SSTable和MemTable,将结果

    合并

    。随着数据持续写入,MemTable不断增长,被写满后,会重新创建一个

    新的MemTable



    老的MemTable



    锁定

    ,然后Merge(合并)到新的SSTable中。

    由于MemTable存放在内存的缘故,当机器发生故障进程突然被

    kill

    时,MemTable中的数据会丢失。为了保证系统的稳定高可用,BigTable通过

    磁盘Log

    记录了所有的

    Commit操作

    ,当发生数据丢失时,可以通过Log和SSTable的时间戳,及时

    恢复

    MemTable中的数据。

    在这里插入图片描述



三、LSM Tree框架图

在这里插入图片描述

从图中可知,LSM Tree的数据主要由

Memory

(内存)和

Disk

(磁盘)组成。

Memory

主要由一个

MemTable

和一个或多个

Immutable MemTable

组成。

Disk

主要由分布在多级

Level



SSTable

组成。Level级数越



表示处于该Level的SSTable越



,Level级数越



表示处于该Level的SSTable越



,最大级数(Level N)大小由系统设定。在此处Disk中最小的级数是Level 0,也会有系统把Memory中的Immutable MemTable定义为Level 0,即Disk中的数据从Level 1开始,这只是Level定义不同,不影响系统的工作流程和对系统的理解。


WAL

(Write Ahead LOG)严格来说不是LSM Tree结构的一部分,但是实际系统中,WAL是数据库不可或缺的一部分,WAL的结构和作用跟其他数据库一样,是一个只能在尾部以

Append Only

方式追加记录的

日志结构文件

,他用来当系统崩溃重启时重放操作,使MemTable和Immuntable MemTabel中未持久化到磁盘中的数据不会丢失,这是通过

LOG

保证存储在内存中数据不丢失的一个方法。


MemTable

往往是一个

跳表

(Skip List)组织的有序数据结构(也可以是

有序数组

或者

红黑树



二叉搜索树

),跳表既支持高效的动态插入数据,对数据进行排序,也支持高效的对数据进行

精确查找



范围查找


SSTable

一般由一组

数据block

和一组

元数据block

组成。元数据block存储了SSTable数据block的

描述信息

,如

索引



BloomFilter

(布隆过滤器)、

压缩



统计

等信息。因为SSTable是不可更改的,且是有序的,索引往往采用

二分数组结构

就行了。为了节省存储空间以及提高数据块block的读写效率,可以对数据block进行压缩。



四、总结

  • LSM Tree以

    牺牲

    部分

    读取性能

    为代价

    提高


    写入性能

    ,通常适用于类似时序数据库这类

    写多读少

    的场景。
  • LSM Tree主要利用磁盘

    顺序访问

    要比

    随机访问

    快很多的思想实现

    提高


    写入性能

    的特点。
  • LSM Tree是一种

    分层的



    有序的



    基于磁盘



    数据结构

    。设计思想是先将数据的操作存到

    内存

    中,并由

    LOG记录

    ,当内存的

    MemTable


    达到阈值

    时就通过

    归并排序

    方式

    合并

    放到

    磁盘队尾

  • LSM Tree

    提升


    读性能

    的优化策略主要是使用

    布隆过滤器



    多路归并机制

    等。



参考:


经典论文研读:《Bigtable: A Distributed Storage System for Structured Data》



LSM Tree原理详解



LSM-Tree介绍



版权声明:本文为qq_47159522原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。