TiDB 底层存储结构 LSM 树原理介绍

news2025/7/8 8:33:38

随着数据量的增大,传统关系型数据库越来越不能满足对于海量数据存储的需求。对于分布式关系型数据库,我们了解其底层存储结构是非常重要的。本文将介绍下分布式关系型数据库 TiDB 所采用的底层存储结构 LSM 树的原理。

1 LSM 树介绍

LSM 树(Log-Structured-Merge-Tree) 日志结构合并树由 Patrick O’Neil 等人在论文《The Log-Structured Merge Tree》(www.cs.umb.edu/~poneil/lsm…

LSM 树的核心特点是利用顺序写来提高写性能,代价就是会稍微降低读性能(读放大),写入量增大(写放大)和占用空间增大(空间放大)。

LSM 树主要被用于 NoSql 数据库中,如 HBase、RocksDB、LevelDB 等,知名的分布式关系型数据库 TiDB 的 kv 存储引擎 TiKV 底层存储就是用的上面所说的 RocksDB,也就是用的 LSM 树。

2 LSM 树算法大概思路

LSM 树由两个或多个树状的结构组成。 这一节我们以两个树状的结构构成的简单的双层 LSM 树举例,来简单说下 LSM 树大概思路,让大家对 LSM 树实现有个整体的认识。

原论文中的图

2.1 数据结构

双层 LSM 树有一个较小的层,该层完全驻留在内存中,作为 C0 树(或 C0 层),以及驻留在磁盘上的较大层,称为 C1 树。 尽管 C1 层驻留在磁盘上,但 C1 中经常引用的节点将保留在内存缓冲区中,因此C1经常引用的节点也可以被视为内存驻留节点。

2.2 写入

写入时,首先将记录行写入顺序日志文件 WAL 中,然后再将此记录行的索引项插入到内存驻留的 C0 树中,然后通过异步任务及时迁移到磁盘上的 C1 树中。

2.3 读取

任何搜索索引项将首先在 C0 中查找,在 C0 中未找到,然后再在 C1 中查找。 如果存在崩溃恢复,还需要读取恢复崩溃前未从磁盘中取出的索引项。

2.4 Compact 过程

将索引条目插入驻留在内存中的 C0 树的操作没有 I/O 成本,然而,与磁盘相比,容纳 C0 组件的内存容量成本较高,这对其大小施加了限制。达到一定大小后,我们就需要将数据迁移到下一层。 我们需要一种有效的方法将记录项迁移到驻留在成本较低的磁盘介质上的 C1 树中。为了实现这一点,当插入达到或接近每一层分配的最大值的阈值大小,将进行一个滚动合并(Compact)过程,用于从 C0 树中删除一些连续的记录项,并将其合并到 C1 中。 Compact 目前有两种策略,size-tiered 策略,leveled策略,我们将在下面的内容里详细介绍这两种策略。

2.5 崩溃恢复

在 C0 树中的项迁移到驻留在磁盘上的C1树之前,存在一定的延迟(延迟),为了保证机器崩溃后C0树中的数据不丢失,在生成每个新的历史记录行时,首先将用于恢复此插入的日志记录写入以常规方式创建的顺序日志文件 WAL 中,然后再写入 C0 中。

3 LSM 树的组成

LSM树有三个重要组成部分,MemTable,Immutable MemTable,SSTable(Sorted String Table),如下图。

这张经典图片来自 Flink PMC 的 Stefan Richter 在Flink Forward 2018演讲的PPT

这几个组成部分分别对应 LSM 树的不同层次,不同层级间数据转移见下图。这节就是介绍 LSM 树抽象的不同层的树状数据结构的某个具体实现方式。

3.1 MemTable

MemTable 是在内存中的数据结构,用于保存最近更新的数据,会按照 Key 有序地组织这些数据。LSM 树对于具体如何组织有序地组织数据并没有明确的数据结构定义,例如你可以任意选择红黑树、跳表等数据结构来保证内存中 key 的有序。

更多C++后台开发技术点知识内容包括C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,MongoDB,ZK,流媒体,音视频开发,Linux内核,TCP/IP,协程,DPDK多个高级知识点。

C/C++Linux服务器开发高级架构师/C++后台开发架构师免费学习地址

【文章福利】另外还整理一些C++后台开发架构师 相关学习资料,面试题,教学视频,以及学习路线图,免费分享有需要的可以点击领取

3.2 Immutable MemTable

为了使内存数据持久化到磁盘时不阻塞数据的更新操作,在 MemTable 变为 SSTable 中间加了一个 Immutable MemTable。 当 MemTable 达到一定大小后,会转化成 Immutable MemTable,并加入到 Immutable MemTable 队列尾部,然后会有任务从 Immutable MemTable 队列头部取出 Immutable MemTable 并持久化磁盘里。

3.3 SSTable(Sorted String Table)

有序键值对集合,是 LSM 树组在磁盘中的数据结构。 其文件结构基本思路就是先划分为数据块(类似于 mysql 中的页),然后再为数据块建立索引,索引项放在文件末尾,并用布隆过滤器优化查找。

4 LSM 树的 Compact 策略

当某层数据量大小达到我们预设的阈值后,我们就会通过 Compact 策略将其转化到下一层。

在介绍 Compact 策略前,我们先想想如果让我们自己设计 Compact 策略,对于以下几个问题,我们该如何选择。

  1. 对于某一层的树,我们用单个文件还是多个文件进行实现?
  2. 如果是多个文件,那同一层 SSTable 的 key 范围是有序还是重合?有序方便读,重合方便写。
  3. 每层 SSTable 的大小以及不同层之间文件大小是否相等。
  4. 每层 SSTable 的数量。如果同一层 key 范围是重合的,则数量越多,读的效率越低。

不同的选择会造成不同的读写策略,基于以上 3 个问题,又带来了 3 个概念:

  1. 读放大:读取数据时实际读取的数据量大于真正的数据量。例如在 LSM 树中可能需要在所有层次的树中查看当前 key 是否存在。
  2. 写放大:写入数据时实际写入的数据量大于真正的数据量。例如在 LSM 树中写入时可能触发Compact 操作,导致实际写入的数据量远大于数据的大小。
  3. 空间放大:数据实际占用的磁盘空间比数据的真正大小更多。LSM 树中同一 key 在不同层次里或者同一层次的不同 SSTable 里可能会重复。

不同的策略实际就是围绕这三个概念之间做出权衡和取舍,我们主要介绍两种基本策略:size-tiered 策略和 leveled 策略,这两个策略对于以上 3 个概念做了不同的取舍。

4.1 size-tiered 策略

4.1.1 算法

  1. size-tiered 策略每层 SSTable 的大小相近。
  2. 当每一层 SSTable 的数量达到 N 后,则触发 Compact 操作合并这些 SSTable,并将合并后的结果写入到一个更大的 SStable。
  3. 新的更大的 SStable 将直接放到下一层 SStable 的队尾。所以同一层不同 SStable key 范围重合,查找时要从后向前扫描,且最坏情况下可能会扫描同一层所有 SStable ,这增大了读放大的问题(之所以说增大,是因为 LSM 树不同层之间也有读放大问题)。

4.1.2 总结

由此可以看出 size-tiered 策略几个特点:

  1. 每层 SSTable 的数量相近。
  2. 当层数达到一定数量时,最底层的单个 SSTable 的大小会变得非常大。
  3. 不但不同层之间,哪怕同一层不同 SSTable 之间,key 也可能会出现重复。空间放大比较严重。只有当该层的 SSTable 执行 compact 操作才会消除这些 key 的冗余记录。
  4. 读操作时,需要同时读取同一层所有 SSTable ,读放大严重。

4.2 leveled 策略

4.2.1 算法

  1. leveled 策略和 size-tiered 策略不同的是,它限制 SSTable 文件的大小,每一层不同 SSTable 文件 key 范围不重叠且后面的最小 key 大于前一个文件的最大 key
  2. 当每一层 SSTable 的总大小达到阈值 N 后,则触发 Compact 操作。
  3. 首先会随机选择一个 SSTable 合并到下层,由于下一层 key 是全局有序的,这就要求 leveled 策略 Compact 操作时需要当前 SSTable 和下一层里和当前 SSTable key 存在范围重叠的所有 SSTable 进行合并。最坏情况下可能下一层所有 SSTable 都参与合并,这就增大了写放大问题(之所以说增大,是因为 LSM 树不同层之间 Compact 也有写放大问题)。

4.2.2 总结

由此可以看出 leveled 策略几个特点:

  1. 不会出现非常大的 SSTable 文件。
  2. 每一层不同 SSTable 文件 key 范围不重叠。相对于 size-tiered 策略读放大更小。
  3. Compact 操作时,需要同时和下一层 SSTable 一起合并,写放大严重。

5 LSM 树的插入、修改、删除

从 LSM 树的名字,Log-Structured-Merge-Tree 日志结构合并树中我们大概就能知道 LSM 树的插入、修改、删除的方法了——顺序追加而非修改(对磁盘操作而言)。

  1. LSM 树的插入、修改、删除都是在 L0 层的树里插入、修改、删除一条记录,并记录记录项的时间戳,由于只需要取最新的内容即可,所以不需要操作后面层次的树。
  2. 历史的插入、修改、删除的记录会在每次 Compact 操作时被后面的记录覆盖。

6 LSM 树的查找

  1. 由于后面的操作会覆盖前面的操作,所以查找只需从 L0 层往下查,直到查到某个 key 的记录就可以了,之前的记录不需要再查了。
  2. 对于 size-tiered 策略,同一层 SSTable 需要从后向前遍历,直到找到符合的索引项。
  3. 在查找过程中也会使用其他一些手段进行优化,例如增加缓存、布隆过滤器等。

7 LSM 树和 B+ 树的比较

  1. 不考虑写日志等操作,插入、修改、删除一条记录 B+ 树需要先找到数据位置,可能需要多次磁盘 IO;LSM 树不需要磁盘 IO,单次插入耗时短,所以其写入的最大吞吐量是高于 B+ 树的。
  2. LSM 树后面的 Compact 操作也会操作这条数据几次,总的写入量是大于 B+ 树的,但可以通过将 Compact 操作放到业务低峰时来降低这个劣势的影响。
  3. 查找时, LSM 树需要遍历所有层次的树,查找效率上要低于 B+ 树,但 LSM 树写入时节省的磁盘资源占用,可以一定程度上弥补读效率上的差距。

8 总结

LSM 树特点:顺序写入、Compact 操作、读、写和空间放大。 LSM 树适用场景:对于写操作吞吐量要求很高、读操作吞吐量要就较高的场景,目前主要在 NoSql 数据库中用的比较多。

原文链接:https://juejin.cn/post/7187222825819144250

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/155574.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

测试开发基础 mvn test | 利用 Maven Surefire Plugin 做测试用例基础执行管理

一、需求在测试工作场景中,经常会遇到下面的问题:1、执行自动化测试用例的时候,只想指定某个测试类,或者某个方法,又或者某一类用例等,怎么办?2、想要和 Jenkins 一起进行持续集成,可…

C语言_文件操作(下)

目录 8. 文件的随机读写 8.1 fseek 8.2 ftell 8.3 rewind ​9. 文件结束判定 10. perror 8. 文件的随机读写 假设文件中存放的是abcdef,如下图,通常在读文件时,是先读取首元素地址,也就是文件指针指向a,每读一…

【Linux进程信号】

Linux进程信号技术应用角度的信号信号的发送与记录信号处理常见方式产生信号通过终端按键产生信号通过系统函数向进程发信号由软件条件产生信号由硬件异常产生信号阻塞信号信号其他相关常见概念在内核中的表示sigset_t信号集操作函数sigprocmasksigpending捕捉信号内核空间与用…

three.js 之 入门篇 5之几何体的认知( 顶点创建矩阵、炫酷三角形科技物体、基础网格材质 material )

目录three.js 之 入门篇 5之几何体的认知01BufferGeometry设置顶点创建矩阵02 生产炫酷三角形科技物体03 常见的网格几何体 geometry04 基础网格材质 material04-1 初识别材质与纹理04-2 初识别材质与纹理 ( 平移、旋转 )04-3 纹理显示设置( …

C语言——指针面试题详解

🐒个人主页:平凡的小苏📚学习格言:别人可以拷贝我的模式,但不能拷贝我不断往前的激情目录 1. 指针和数组笔试题解析 一维数组 字符数组 二维数组 2. 指针笔试题 笔试题1: 笔试题2: 笔试题…

ffmpeg 颜色空间转换分析

颜色空间转换有很多相关标准: https://docs.opencv.org/3.4.0/de/d25/imgproc_color_conversions.html https://www.itu.int/rec/R-REC-BT.601-4-199407-S/en ffmpeg命令行颜色空间转换是通过调用vf_scale中的swscale来进行转码。 我们通过gdb来调试ffmpeg. 首先编译…

《Getting Started with NLP》chap11:Named-entity recognition

《Getting Started with NLP》chap11:Named-entity recognition 最近需要做一些NER相关的任务,来学习一下这本书的第十一章 文章目录《Getting Started with NLP》chap11:Named-entity recognition11.1 Named entity recognition: Definition…

jar转成dex文件

jar转成dex文件 dx 可以利用android studio中的dx工具。 可以看到android的tool安装位置: 在此路径下的如下目录有dx.bat,这个正是我们需要使用的工具。 D:\sdk\build-tools\30.0.3将dx.bat添加到环境变量 基本指令 > dx --dex --output 输出路径 待转化的jar包C

高性能网络模式:Reactor 和 Proactor

文章目录演进多 Reactor 多进程 / 线程Proactor总结演进 如果要让服务器服务多个客户端,那么最直接的方式就是为每一条连接创建线程。其实创建进程也是可以的,原理是一样的,进程和线程的区别在于线程比较轻量级些,线程的创建和线…

【Dash搭建可视化网站】项目12:全球恐怖主义数据大屏制作步骤详解

全球恐怖主义数据大屏制作步骤详解1 项目效果图2 项目架构3 文件介绍和功能完善3.1 assets文件夹介绍3.2 app.py和index.py文件完善3.3 header.py文件完善3.4 filteritem.py文件完善3.5 api.py文件和api.ipynb文件完善3.6 staclbarline.py文件完善3.7 piechart.py文件完善3.8 m…

IO多路复用之select、poll、epoll之间的区别总结

一、IO多路复用基本概念 select、poll、epoll都是IO多路复用的机制。IO多路复用就是通过一种机制,让一个进程/线程可以监视多个描述符,一旦某个描述符就绪(一般是读写就绪),能够通知应用程序进行相应的读写操作。 I/…

并网逆变器学习笔记5---三电平DPWM

参考文献:《中压三电平全功率风电变流器关键技术研究---任康乐》 1、调制策略分析 DPWM由于其在任意时刻均有一相钳位在某个电平,使得该相的功率器件不发生开关动作,因而可以大大降低开关损耗(平均降低1/3)&#xff…

Java多线程案例——定时器

一,定时器1.定时器的概念定时器是Java开发中一个重要的组件(功能类似于闹钟),可以指定一个任务在多长时间后执行(尤其在网络编程的时候,如果网络卡顿很长时间没有响应用户的需求,此时可以使用定…

分享|UWB使用频段大幅收窄,新标准对于行业发展是好是坏?

近日,工信部无线电管理局发布了《超宽带(UWB)设备无线电管理规定(征求意见稿)》(以下简称“新版《规定》”)。 根据新版《规定》,未来国内UWB技术的使用频段为:7235-875…

seo的基本知识(概述网站内部优化和外部优化)

了解网站外部优化的4大重点 网站优化的时候都会重视网站的外部优化,所以网站外部优化的4大重点!今天就来和大家说一说! 1.高质量的内容和外链 未来的SEO道路高质量的有价值的内容是非常重要的,还有就是高质量的外链也是重要之…

北大硕士LeetCode算法专题课-查找相关问题

黑马算法面试专题 北大硕士LeetCode算法专题课-字符串相关问题 北大硕士LeetCode算法专题课-数组相关问题_​​​​​​ 北大硕士LeetCode算法专题课-基础算法查找_ 北大硕士LeetCode算法专题课-基础算法之排序_客 北大硕士LeetCode算法专题课---算法复杂度介绍_…

Neo4j框架学习之一安装和使用

文章目录1、何为Neo4j2、安装和使用2.1 安装2.2 基础概念1、何为Neo4j ​ Neo4j是一个高性能的NOSQL图形数据库,是一个嵌入式的、基于磁盘的,数据结果为网格(图)、具备完全的事务特性的Java持久化引擎。 数据结构 ​ 在一个图中包含两种基本的数据类型…

从浏览器里输入URL构建你的前端知识体系

嗨!我是团子,好久不见~ 记得22年寒假复习八股的时候,一直在苦恼怎样才能把八股的内容真正的转换为自己的知识。毕竟光靠死记硬背每个知识点,是不能在面试中给面试官留下不错的印象的。后面在整理《浏览器里输入URL后发生了什么》…

Stellarium 1.2 正式发布

导读Stellarium 1.2 已发布。Stellarium 是一款免费开源 GPL(自由软件基金会 GNU 通用公共许可证)软件,它使用 OpenGL 图形接口对星空进行实时渲染。 软件可以模拟肉眼、双筒望远镜和小型天文等观察天空,根据观测者所处时间和位置…

项目管理:项目经理如何创建项目日程计划表

当项目经理接手项目后,要做好项目的日程安排,这是决定项目是否成功完成的最重要任务之一。 项目经理都希望项目按照制定好的进度计划完工,但在实际的情况中,总会有那么一两个项目会出现进度延迟的情况,管理者可以使用…