数据库原理 LSM vs BTree

1. 数据库的本质

数据库的本质就是帮助我们存储和获取数据个中间件。 最简单的数据库可以通过下面两个脚本实现。

  • set.sh 存储
[qa@qaserver1 db]$cat set.sh
#!/bin/bash

echo "$1,$2" >> database
  • get.sh 获取
[qa@qaserver1 db]$cat get.sh
#!/bin/bash

cat database | grep "$1," | tail -n 1 | awk -F, '{print $2}'

这个实现写入十分高效,所有的写入都是顺序写入,查询性能就比较糟糕,时间复杂度O(n),每次都是全部扫描。

数据库设计者们通过修改数据的存储结构,或者在数据外额外的维护一份元数据来加速查询过程,这一份额外的元数据被称为索引,最常见的索引是Hash索引、LSM-Tree、 B+Tree。

2. Hash索引

以我们上面举例的最简单Key-Value数据库为例,最直观的索引结构就是Hash索引,在内存中维护一个HashMap,HashMap的Key就是数据库的Key, HashMap的Value是文件内位置(offset)。

image.png

有了Hash索引后,每次我们可以通Key找到记录地址,seek到特定位置,直接读取数据返回。 每次写入数据时,需要同时更新Hash索引。

Hash索引有两个明显的缺陷:

  • 内存需要能过放下索引的整个HashMap
  • Range Scan效率低下

3. Segment

数据文件如果只是不断的追加,即使数据库系统不间断正常运行,文件会越来越大,文件里的无用信息越来越多(一个Key的值修改了N次,文件里记录了N条,只有最后一条有意义),如果从文件从新构建索引,耗时也会很长。

于是数据库设计者们想到了将数据文件切分,切分的每一段被称为一个Segment,只有当前Segment会有数据Append动作,历史Segment都可以认为是固定的。

那我们就可以启动后台线程对历史Segment做合并压缩(Compaction),一个Key的多次操作只保留最后一条,之前已经标记为删除的数据移除。

image.png

每个Segment都有对应的Hash索引,查找特定Key时,我们需要依次查询Segment对应的Hash索引。

这类存储引擎称为 Append-Only Log-Structed。 它们的优点是:

  • 永远只做顺序写入,写入效率极高

确定也很明显:

  • Hash索引庞大,需要存入到内存,然而内存大小永远是受限的
  • 一个Key可能在多个Segment里,需要遍历每个Segment(至少检查每个Segment索引是否包含Key)

4. SSTable 和 LSM-Tree

前面提到用Hash索引是需要将每个Key保存到内存中,但是内存可能无法放下所有的Key。 SSTable完美解决了这个问题, SSTable全称Sorted String Table, 要求每个Merged-Segment里Key只出现一次,且Segment内Key是有序的。

相比之前简单的拆分Segment,SSTable有如下优势:

  1. SSTable内的Segment是有序的,所以合并Segment要高效的多,也不需要完整的加载两个Segment排序然后合并
  2. Segment有序,我们的索引里不需要完整的保存索引Key,而至少维护一个稀疏索引
  3. Segment有效,在Range-Scan的只需要顺序扫描,十分高效

那如何做到Segment内部有序呢? 因为数据写入会先经过内存,我们可以在内存维护一个红黑树(Red-Black Tree)或者平衡二叉树(AVL Tree)。

写入SSTable的工作流程:

  1. 写入Write-Ahead-Log,用于避免宕机导致Memtable丢失,通过重做日志恢复Memtable
  2. 数据插入到平衡二叉树中,内存中的这棵树我们称为Memtable
  3. 当Memtable超过一定阈值后,将Memtable Flush到磁盘,输出的文件被称为SSTable,也是之前说的一个Segment
  4. 清除已经写入SSTable的Memtable数据,比如新生成一个Memtable接收新数据,老的Memtable用于写入SSTable的,写完后丢弃
  5. 记录已经固化的Write-Ahead-Log的Position,下次重做日志从这个Position开始

读取SSTable的工作流程:

  1. 查询每一个SSTable的索引,确认是否包含给定Key,包含则读取对应Value
  2. 后面读取的SSTable的Value值,覆盖之前的值
  3. 读取当前正在写入Memtable,如果读到覆盖之前的值

==LSM-Tree的三大核心主键就是: Write-Ahead-Log、 Memtable 、 SSTable, 上面我们讲的其实就是LSM-Tree的核心思想。==

LSM-Tree已经被广泛使用, 如LevelDB、 RocksDB、 Cassandra 、 HBase都采用这个核心架构。 SSTable的概念也被广泛借鉴,如ClickHouse、 Palo里都有相关概念。

5. 总结

LSM-Tree的优点:

  • 高吞吐的写
  • 可以高效的压缩,更节省磁盘(B-Tree一般会为Page的分裂预留一些空间)

LSM-Tree的缺点:

  • Compaction会影响正常数据的读取,读取性能略有影响。
  • 数据量越大,Compaction需要的磁盘带宽就越多。
  • B-Tree中Key只在一个Page中,LSM-tree可能出现在多个Segment中,影响读取性能,想要事务加锁也更困难一些。

 
 
 


参考文档

 
 
 

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343