前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WiscKey:LSM-Tree 写放大优化WiscKey 简介WiscKey 带来的好处WiscKey 面临的问题和挑战参考文档

WiscKey:LSM-Tree 写放大优化WiscKey 简介WiscKey 带来的好处WiscKey 面临的问题和挑战参考文档

作者头像
linjinhe
发布2018-10-10 17:30:54
1.7K0
发布2018-10-10 17:30:54
举报
文章被收录于专栏:linjinhe的专栏linjinhe的专栏

第一次看完 WiscKey 这篇论文,觉得写得很接地气,很实用,很通俗易懂。

这里简单记录一下。

WiscKey 简介

WiscKey 的提出,主要是为了优化 LSM-Tree 的写放大问题。此前已经有不少论文讨论过这个问题,如 LSM-trie 和 PebblesDB,但是大部分优化方法都不是很彻底——简单说就是,优化效果太差,或者不够通用。WiscKey 提出的是一种比较通用、效果明显且简单易懂的方法。

其实 WiscKey 优化写放大的原理非常简单:在 LSM-Tree 上做 key 和 value 的分离存储

LSM-Tree 写放大的根本原因是,compaction 时为了保证数据有序进行大量数据(key 和 value)重写。实际上,需要保持有序的只有 key,如果将 key 和 value 分开存储,compaction 重写数据的时候,就只需要重写 key(和 value 的位置,简称 vpos)。这在 key size (简称 ksize)远小于 value size (简称 vsize)的场景(现实场景基本都是这样)降低写放大的效果十分明显。

另一方面,当 vsize 比较小的时候,重写 value 这部分的开销就比较小,key-value 分离存储带来的好处就不足以抵消它带来开销。Key-value 分离存储带来的额外开销 —— 读写一个 key-value 需要操作不同文件。这在 range query 的场景下,会产生多次随机 I/O,影响比较明显。如下图所示。

WiscKey-Range-Query-Performance.PNG

对顺序 range query:

  1. 当 vsize 比较小的时候,LevelDB 的性能和 WiscKey 很接近。因为是顺序 range query,WiscKey 的预读缓存功能可以有效地提升性能。
  2. 当 vsize 逐渐变大,LevelDB 的性能急剧下降,WiscKey 的性能比较平稳,明显优于 LevelDB。因为 value 变大,导致 LevelDB 一个 block 可以存储的 kv pair 变少了,cache 效果变差。

对于随机 range query:

  1. 当 vsize 比较小的时候,LevelDB 的性能优于 WiscKey。因为是随机 range query,范围应该比较小,WiscKey 的预读缓存功能没能很好发挥作用。
  2. 当 vsize 逐渐变大,WiscKey 的性能很快超越了 LevelDB。

Key-value 分离存储后,LSM-Tree 索引结构上只存储 key 和 vpos,实际的 value 存储在另一个 append-only 的 log 文件中,称为 vlog。总体看来,WiscKey 很像一个用 LSM-Tree 做索引的 BitCask。

WiscKey 带来的好处

  1. LSM-Tree Compaction 不需要重写 value,大大减小写放大。
  2. LSM-Tree 不存储 value,体积更小,一个 block 能存更多的 key,有利于减少读 LSM-Tree 的 I/O。
  3. LSM-Tree 的体积小,cache 效果应该会更好。LSM-Tree 的上面几层基本都可以 cache 在内存中。

WiscKey 面临的问题和挑战

虽然减小了写放大,提升了 key 的密度,进而优化了 LSM-Tree 的 cache 效果。但是 key-value 分离存储也给 WiscKey 带来一些问题和挑战。下面简单分析一下。

  1. 当发起一次 range query 的时候,最终会转化成多次针对 vlog 的随机读。这种场景下, WiscKey 会通过多个后台线程对后面的多个数据进行预读,并缓存起来,充分利用 SSD 内部的并行性。预读缓存对于范围比较大的 range query 效果可能比较明显,对于小范围的随机 range query,可能发挥不了什么作用。
  2. Key 和 value 分开存储后,怎么保证 key 和 value 的一致性呢?针对这个问题,WiscKey 采用的方案是,先写 vlog,再写 LSM-Tree 。如果写 vlog 成功,写 LSM-Tree 失败,则写失败。此时,vlog 上的值不会被暴露出去,只需后面进行垃圾回收。这里如果要保证数据一致性和可靠性,则写 vlog 后要刷盘,写 LSM-Tree 后也要 WAL 刷盘。这里有两次刷盘开销,通过 WAL 和 vlog 的合并,可以优化成一次。
  3. vlog 的垃圾回收。垃圾回收需要扫描数据,根据数据结构,有两个方向可以考虑:
    1. 扫 LSM-Tree。根据 LSM-Tree 把 vlog 中有效的内容都提取出来。这个方法不太适合在线服务,需要一次性重写整个 vlog,开销比较大。重写 vlog 的同时外部依然会更新 LSM-Tree 和 vlog,数据一致性不太好处理。
    2. 扫 vlog。为了扫描 vlog,vlog 不能只存储 <value>,需要存储 <key, value>。根据扫出来的每一个 <key, value>,通过 LSM-Tree 验证其有效性。为了不影响在线服务,WiscKey 每次取出 vlog 最旧的一部分数据(几 MB),通过 LSM-Tree 进行验证,过期则丢弃,有效则 append 到 vlog,并修改 LSM-Tree(类似执行一次写入操作),并删除这部分回收验证过的数据,通过 fallocate() 释放无效的文件磁盘空间。

参考文档

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.10.03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • WiscKey 简介
  • WiscKey 带来的好处
  • WiscKey 面临的问题和挑战
  • 参考文档
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档