《设计数据密集型应用》第三章(2) 存储索引:B-tree

上一节介绍的LSM-tree,是已经被认可的日志存储的索引结构。这节我们会介绍更通用的一种索引类型:B-tree。

B-tree的概念

B-tree在1970年提出,并且已经广泛使用在所有的关系型和许多非关系型数据库中。下面我们通过和LSM-tree的对比介绍一下B-tree的特性:

  • 相同:B-tree维护的是按key排序的键值对,实现高效的查找的范围查询;
  • 不同:LSM-tree将数据库分为若干个变长的segments,而B-tree将数据库划分为定长的块或者页(fixed-size blocks or pages),这样更加接近于底层硬件,方便磁盘管理。

如下图可以直观的看到B-tree的查找过程,以一个页作为B-tree的顶端,按照key的值,依次查找key所在的范围的目标引用地址,直到叶子页(leaf page)。

B-tree索引的查询过程

每个节点带有的区间段个数称为分支因子,上图的分支因子为6。分支因子的大小由引用需要的存储空间和数据范围边界有关,一般都是几百个。
在更新B-tree的一个值时,同样需要需要查找该值在B-tree中的位置。如果页的存储空间不足以插入新值,则分裂为两个完整的页,同时更新上一级的页以负责新的key值范围。
B-tree的分裂

该方法可以保证B-tree的平衡,每个点带有n个key的B-tree的深度为O(logn)。大多数的B-tree的深度为3-4,一个4层深并且分支因子为500的B-tree可以存储256TB的数据。

提升B-tree的可靠性

B-tree的修改,是需要修改并覆盖在磁盘上存储的对应的页文件,这和LSM-tree只在文件后追加,但不修改文件的方式是不同的。如果B-tree的修改引起了页文件的分裂,以及上层文件的修改,并且数据库崩溃导致操作没有全部完成,可能会导致索引文件的损坏。

为了使数据库能够抵抗这样的崩溃,一种普遍的做法是在修改B-tree的同时,将改动写入到磁盘文件中,称该文件为write-ahead log(WAL)。该文件用于在数据库崩溃时,恢复B-tree到正确的状态。

另外,在更新B-tree时,如果有多个线程同时进行写操作,可能会出现不一致的状态。因此使用latches(轻量级锁)来保护B-tree的数据结构。

B-tree的优化

B-tree经历了较长时间的发展,有很多的优化方式已经被提出,这里列举几点:

  1. 使用copy-on-write的机制替换WAL日志。对页文件的修改,是先在另一个位置写入新的版本,然后在树中指向该地址,该方法同样可用在并发场景中;
  2. 在页中,不保存整个key,只保存它的缩写,可以节省一部分空间;
  3. 将临近的页文件保存在磁盘的相邻位置,提高扫描和查询的速度;
  4. 在B-tree中增加额外的指针,比如在叶子页中增加到左右邻居的指针,可以更快的进行扫描;
  5. 借用日志结构的思想,减少磁盘寻址,比如fractal tree。

B-tree和LSM-tree的比较

  • LSM-tree的优点:
  1. 建立B-tree需要额外写入WAL日志中,LSM-tree不需要;
  2. LSM-tree的写性能要优于B-tree,吞吐量更大和写磁盘次数更少;
  3. LSM-tree的压缩情况更好,占用的磁盘空间更少,B-tree的页空间浪费更多;
  • LSM-tree的缺点:
  1. LSM-tree的压缩过程可能会影响正在进行的读写操作,因为它们共享磁盘I/O,所以LSM-tree的性能起伏更大,而B-tree的性能更稳定;
  2. LSM-tree的压缩速度可能会跟不上写入的速度,导致segments文件的数量越来越多,直至用完磁盘空间;
  3. LSM-tree中每个key在多个位置保存多个值,而B-tree则只有一个确定的位置保存值,因此B-tree更容易提供良好的事务性。

扩展阅读:其他索引方式

第二索引

前面提到的key-value型的索引,比如B-tree和LSM-tree,适合于做数据库的主键,因为主键是唯一确定数据库中的一行。那数据库的第二索引应该用怎么方式构建呢?

用B-tree这种唯一类型的索引也是可以的,但需要对重复值进行处理。一种处理方式是为每个值匹配的行创建一个列表;另一种处理方式是在每个key上增加一个唯一的行标识符。

索引的类型

从索引是否包含指向行的数据,可以将索引分为两大类型:

  • clustered index:索引的值为数据库中对应行的数据,这种类型的索引可以节省一次读磁盘的时间,但需要额外的存储空间,以及事务性的处理等;
  • nonclustered index:索引指向的是文件位置,数据库的内容都存储在堆文件中,这是比较常见的索引类型。
  • covered index:折中了这两种索引方式的优缺点,将一部分列的内容作为索引的值,可提供更好的性能,其他列还需要从数据库文件中读取。
多列索引

多列索引的使用场景在使用多列进行查询时的提速。一种简单的实现方式是将索引中的每列的值连接之后作为索引的key。如果这些列之间存在一些逻辑关系,比如经度和纬度,红绿蓝等,可以使用R-tree创建索引。

全文搜索和模糊索引

Lucene是这类索引的代表,允许在一定的编辑误差内进行搜索。Lucene使用的类似SSTable的结构,内存中的索引是key中的字符自动修改后的有限状态,因此可以进行模糊搜索。

内存数据库

内存数据库指所有数据均保存在内存中的情况,比如Memcached,Redis,Couchbase等。内存数据库之所以性能更好,不完全是因为不需要进行磁盘读写。内存数据库由于不需要读写磁盘,可以避免在数据结构设计上的限制,从而得到更好的处理性能。并且能够处理更加复杂的数据结构,比如Redis中的优先级队列和集合等。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念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

推荐阅读更多精彩内容