(一)研究目标

结合B+Tree利用PM对LSM-Tree进行优化。

(二)研究背景


LevelDB 存在的问题:较低的读性能和严重的读写放大。
Slow read operations
一个读操作至少需要两次块读取,一次读索引块,另一次读数据块
先搜索内存中的MemTable和Imutable Table,找不到则在磁盘上的每一个 Level 上根据SSTable的开始key进行二分查找,定位数据所在的SSTable,然后对 SSTable File 中存储的数据索引再次进行二分查找,找到对应的数据块。为了避免不必要的块读取和减少搜索成本,LevelDB对每个块使用Bloom过滤器

High write and read amplification
写放大:

  • 维护垂直的多级有序数据结构 SSTables 来保证顺序写
  • 需要在不同的层级之间进行归并排序操作,同时需要常常进行数据压缩(Compaction)
    读放大:
  • 由于 LSM 树的原因,读数据时往往需要在多个层级进行检索
  • 不仅需要读取该 Key 所对应的数据所在的数据块,还要读取对应的索引块和 Bloom Filter 块,索引块和 Bloom Filter块的数据和可能比 KV 本身大得多

(三)研究概述

使用 PM 进行缓冲写入,省略了 WAL 的写开销,采用单层的 LSM 结构来减小写放大问题带来的影响。利用 PM 的特性维护 B+ Tree 作为索引,加速数据的检索。

(四)关键技术

Persistent MemTable


MemTable 的核心数据结构为跳表(SkipList)。跳表的操作,如插入、更新、删除均可用 8bytes 的原子操作完成。采用PM存储MemTable, SLM-DB就不需要依赖于W AL来保证数据一致性。跳表的索引部分不需要提供一致性保证,因为可以从原始数据中快速重建。

插入操作:为了保证MemTable中kv的一致性,首先调用内存fence和cacheline flush指令持久化一个新节点,该节点的next指针被设置指向。然后更新其上一个节点的next指针(8字节)指向新节点,并持久化更改。

Insert(key, value, prevNode)1: curNode := NewNode(key, value); // Create Node
2: curNode.next := prevNode.next;  // Modify currentNode.next pointer
3: mfence();                       // 插入内存屏障(读屏障),让高速缓存中的数据失效,重新从主内存加载数据
4: clflush(curNode);               // 缓存刷新, 持久化 currentNode 数据
5: mfence();                       // 插入内存屏障(写屏障),内存隔离,让写入缓存的最新数据写回到主内存
6: prevNode.next := curNode;       // Modify preNode.next pointer
7: mfence();                       // 插入内存屏障(读屏障),让高速缓存中的数据失效,重新从主内存加载数据
8: clflush(prevNode.next);         // 缓存刷新,持久化 preNode 的修改
9: mfence();                       // 插入内存屏障(写屏障),内存隔离,让写入缓存的最新数据写回到主内存

B+tree Index in PM

基本操作:

  • 当将Imutable MemTable中的KV对刷新到SSTable时,key相关的索引信息被插入到B+树的叶节点,其指针指向一个PM对象,该对象包含键值对在磁盘上的位置信息、SSTable file ID、file内键值对的块偏移量、块的大小。
  • B+ Tree 的更新操作:更新已有的 KV 对时,首先创建对应该 Key 的索引对象,然后修改原有的在 B+ 树中的指针,指向新的索引对象。旧的索引信息将会被视为垃圾数据进行统一的垃圾回收。
  • B+ Tree 的删除操作:当需要删除指定 Key 的数据时,则将该 Key 在 B+ 树中对应的索引信息删除。
  • 垃圾回收时使用 PM 管理器如 PMDK 来进行垃圾回收。

对于刷新操作,SLM-DB会创建两个后台线程,一个用于创建文件,另一个用于插入B+tree。

  • file creation thread:在文件创建线程中,SLM-DB创建一个新的SSTable文件,并将KV对从Immutable MemTable写入该文件。一旦文件创建线程将文件刷新到磁盘,它就将存储在新创建的文件上的所有KV对添加到一个队列中,这个队列是由B+tree插入线程创建的。
  • B+tree insertion thread:创建相应的 KV 索引信息队列,待数据写入线程将该队列填入数据之后,依次处理队列中的每个数据,构建 B+ 树。
  • 一致性保证:待 B+ Tree构建完成以后,将 LSM 树中组织结构的变化(例如 SSTable File 的元数据信息)以追加写的方式写入到 MANIFEST 文件中。
  • 待完成一致性的日志追加写操作之后,对应的删除PM中的 Immutable Memtable

Scanning a B+tree

  • SLM-DB 提供了一个迭代器,主要用于扫描存储在磁盘中的 KV 键值对。支持 seek()、value()、next()等操作。

    • seek(k):让迭代器指向 key 为 k 的键值对或者当 k 不存在时,指向比 k 稍大的 Key
    • next():将迭代器指针移动到下一个 Key
    • value():返回该 Key 对应的值

Selective Compaction

SLM-DB 支持选择性的压缩操作,目的:

  • 回收废弃的KV
  • 提高KV在SSTable的顺序性

SLM-DB 维护一个压缩候选 SSTable 列表。当执行一个压缩线程时,SLM-DB 从候选列表中根据key的重叠率选择SSTable的一个子集进行压缩合并。
压缩过程也使用文件创建线程和B+Tree索引插入线程。合并多个 SSTable Files 时,需要检查该文件中的每一个键值对是否有效或过时。有效的数据进行归并排序,老旧的数据则对应将其删除。压缩过程中,文件创建线程创建新的SSTable文件(存压缩合并的文件),然后刷新到磁盘,然后将新文件中包含的所有KV对添加到B+Tree插入线程。然后文件创建线程创建新文件,插入线程更新KV对,重复这个过程直到完成压缩合并。最后将SSTable元数据的更改提交到MANIFEST文件,并删除过时的SSTable文件。

为了选择用于压缩的候选SSTable,采用三种选择算法:

  • 基于SSTable的有效Key进行选择(目的是回收磁盘上的垃圾):统计每个SSTable的有效Key的比例,一旦比例低于设定的阈值,就被添加到候选压缩列表中。(有效Key指维护在B+Tree中的Key)
  • 基于B+Tree的叶节点扫描进行选择(目的是提高存储在L0中KV的顺序性):扫描叶节点,统计包含指定Key的SSTable文件的数量,如果数量大于阈值,则将这些文件添加到候选列表。
  • 基于范围查询的有序程度进行选择(提高数据分布的顺序性):将范围查询查到的键划分为若干子范围,统计每个子范围中SSTable的数量,找到拥有最大SSTable数量的子范围,若数量大于阈值,则将这些SSTable添加到候选列表。

(五)实验

实验配置:

  • two Intel Xeon Octa-core E5-2640V3 processors (2.6Ghz)
  • Intel SSD DC S3520 of 480GB
  • disable one of the sockets and its memory module and only use the remaining socket composed of 8 cores with 16GB DRAM
  • Ubuntu 18.04 LTS with Linux kernel version 4.15
  • emulate PM using DRAM

评估了SLM-DB的性能,并将其与LevelDB(版本1.20)在不同的值大小下的性能进行了比较。

  • MemTable size:64MB
  • a fixed key size:20bytes

三种选择算法的阈值:

  • live-key threshold = 0.7
  • leaf node threshold = 10
  • sequentiality degree threshold = 8 (子范围有30个key)

使用 db_bench benchmarks 作为微基准测试,使用YCSB作为真实世界的工作负载基准测试。

与LevelDB相比,SLM-DB的写时延和总写数据量平均减少了49%和57%。这是因为SLM-DB通过在单个Level组织sstable并执行限制性压缩进一步减少了写放大。

  • 对于随机写操作,各value大小下,SLM-DB的平均吞吐量大约是LevelDB的2倍。这是通过显著减少写入磁盘进行压缩的数据量来实现的。对B+树的插入是由后台线程执行的,开销很小。
  • 对于随机读操作,根据值的大小,SLM-DB表现出与LevelDB相似或更好的性能。随着数值大小的增加,SLM-DB和LevelDB之间的性能差异增大,这是由于SLM-DB中使用B+tree索引对KV对进行高效搜索。但是,当值大小达到64KB时,从磁盘读取数据块所花费的时间会比读取较小值的时间长。因此,SLM-DB和LevelDB之间的性能差异下降到25%。
  • 对于小范围查询操作,每级KV全顺序的LevelDB可以连续读取给定范围内的KV对,对于1KB和4KB大小的值具有更好的性能。
  • 对于顺序读工作负载扫描所有KV对,SLM-DB的性能优于LevelDB,除了1KB的值大小。

SLM-DB: Single-Level Key-Value Store with Persistent Memory(FAST 19)相关推荐

  1. 图相处理自学(二):图像处理基本算法Black level / sensor offset/ Shading/ Color Matrix/ AWB(QP值)

    1.Black level / sensor offset (1)sensor 输出数据中包含了OB(optical black)或data pedestal 部分,需要去除,以免影响画面暗部表现.去 ...

  2. 无线知识:dBm、dBw、dB、dBi、dBd、asu、RSSI(接收信号强度)、天线增益、灵敏度等无线参数快速了解

    文章目录 1.dBm 2.dBw 3.dB 4.RSSI(Received Signal Strength Indication,接收信号强度) 5.asu 6.天线增益.dBi.dBd 7.灵敏度 ...

  3. MacOs平台下 Vs2022 for Mac、Xamarin、IOS Android 双平台证书申请、开发环境配置、实机测试、内部分发B(贝塔)测试、 App store发布 超详细(多图)全程笔记

    本文超长,含盖从前期准备到发布的全程细节,多图杀猫-- 这些天,研究使用Visual studio for macos做ios和android双平台开发.遇到最大的坑就是apple开发各种证书.真机测 ...

  4. vuex结合php,vuex中store的使用介绍(附实例)

    本篇文章给大家带来的内容是关于vuex中store的使用介绍(附实例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 一.状态管理(vuex)简介 vuex是专为vue.js应用程序 ...

  5. App Store最新审核标准(2015.3)公布

    苹果近日更新了App Store审核指南的相关章节,对此前版本进行了修改和完善.除了增加应用截图.预览等限制外,使用Apple Pay进行定期付款的应用程序必须展示每个阶段所需款额,费用归属以及如何取 ...

  6. 如何解决MacOS无法登录app store的问题?(方法二)

    在Mac电脑上登录app store,但是确给出了[未能登录,因为服务器发生错误,请再次尝试登录一次.]这样的提示.那么我们该如何解决这样的问题呢? 解决方法如下 1.查看你的"关于本机&q ...

  7. stealwatch里的安全功能——ETA结果会显示加密套件以及key长度,还有流量大小(例如41MB)...

    以后可以考虑的方向,在stealwatch里包含: ad Injector click fraud cryptocurrency miner exploit kit malicious adverti ...

  8. PAT (Advanced Level) Practice - 1127 ZigZagging on a Tree(30 分)

    题目链接:点击打开链接 题目大意:给出中序和后序序列,按照"S"形层序遍历输出. 解题思路:找规律可以发现,只要每次用queue保存,然后遍历了该层的所有结点后,把queue里的结 ...

  9. Berkeley DB的数据存储结构——哈希表(Hash Table)、B树(BTree)、队列(Queue)、记录号(Recno)...

    Berkeley DB的数据存储结构 BDB支持四种数据存储结构及相应算法,官方称为访问方法(Access Method),分别是哈希表(Hash Table).B树(BTree).队列(Queue) ...

最新文章

  1. java 创建servlet_javaweb02-创建第一个Servlet
  2. 人工智能的学习,需要学习哪些算法和数学知识呢?需要什么学历?
  3. (三)数字判断大小语句
  4. mvc在页面上显示PDF
  5. JavaScript数组的API
  6. TADOStoredProc返回多个数据集
  7. 必知必会的RocketMQ消息类型
  8. bartlett 算法 matlab,GWO(灰狼优化)算法MATLAB源码逐行中文注解(转载)
  9. java基础—Objcet中的equals方法重写
  10. 【零基础学Java】—哈希值(四十一)
  11. SAP HANA Cloud Connector图文全攻略
  12. php代码审计小技巧
  13. js中函数返回值return
  14. ANTS Memory Profiler - NET内存泄漏分析工具
  15. 光学定位与追踪技术_视觉SLAM技术学习笔记(一)基础知识以及SLAM的应用
  16. ENSP安装教程【手把手教学】
  17. linu修改open files无效_安卓容器app如何使用 容器app修改机型方法【详解】
  18. Android项目报错:Could not resolve com.android.support.constraint:constraint-layout:2.0.2.
  19. java计算机毕业设计高校贫困生信息管理系统源码+mysql数据库+系统+lw文档+部署
  20. SVN学习:SVN的下载安装

热门文章

  1. 【C语言】案例五十 歌曲管理系统
  2. 技嘉 B360 HD3 Core i7-8700 GTX1060黑苹果efi引导文件
  3. linux shell脚本
  4. 站在邙山之颠仰望天的那份湛蓝
  5. 广东省-IT公司红黑榜排名
  6. turtle简单绘图
  7. 对勾函数的性质及其应用
  8. gitlab+jenkins 利用webhook自动构建代码
  9. 四旋翼无人机学习第13节--Padstack Editor的简单使用
  10. Oracle的客户端工具