绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
Closing Performance Gap
2019-12-24 17:46:38

Closing Performance Gap Between Volatile and Persistent Memory



原题目:Closing the Performance Gap Between Volatile and Persistent Key-Value Stores Using Cross Referencing Logs

文章概况:

这篇文章主要研究基于 Persistent Memory(PM,持久内存)的高性能 key-value 存储。

1. Motivation

传统的 key-value 存储方案主要分为两种,(1)用作 cache,存放在 DRAM(内存) 中,以 memcached 和 redis 为代表;(2)用作持久化存储,以 LSM-tree 方案为代表,大家所熟知的有 Leveldb 和 Rocksdb 。随着当前 Persistent Memory (PM) (其实也就是 NVM 设备,例如 Intel/Micron’s 3D XPoint)技术的发展,PM 设备已经拥有仅次于 DRAM 的 latency 和吞吐,且具有持久化存储和 byteaddressable 的能力。而传统 key-value 存储方案并不完全适用于 PM 设备:传统方案(1)并不能直接迁移到 PM 设备上;方案(2)由于读写放大的因素,其实不能充分的发挥 PM 设备的性能,因为 PM 设备的顺序读写和随机读写性能相差并不大。

这篇论文的作者主要动机就是设计基于 PM 设备的高性能 key-value 存储,使其尽可能的接近 DRAM 的性能,也就是 closing the gap between DRAM with PM for key-value store。因为相比 DRAM,PM 设备具有持久化的能力,而且 latency 和 throughput 和 DRAM 非常接近, 如果能够将 PM 设备上的 key-value 存储优化到 latency 和 throughput 足够接近 DRAM,那将是一件很美妙的事情。

但是 DRAM 和 PM 之间存在一定的 gap, 如下图,给出了几组 key-value 存储在DRAM 和 PM 设备的表现:

从上图我们不难发现:

  • 随着 write 的比例增多,DRAM 和 PM 的 latency 差距越来越大,从 write 比例 0% 到15%,latency 的 gap 也从 2X 增加到了 4X;
  • DRAM 在多线程的情况 latency 表现平稳,而 PM 设备随着线程的增加 latency 显著上升;
  • 由上图的分析不难得知,key-vale 存储在 DRAM 和 PM 上的 gap 就是 write 性能较差,而且扩展性不好,也就是在多线程的表现下,性能下降很快,不能充分利用现在多核 CPU 的优势。

2. Innovation

作者给出了一个名为 Bullet 的 key-value 方案,使用 DRAM 作为 Cache,PM 负责持久化 key-value 和 log 数据,其核心的贡献在于使用多个 log 来衔接 DRAM 和 PM,从而实现了 PM 上的 key-value store 在多线程环境下具有良好的 Scalability,而且为了解决多 log 的 Consistency Apply 的问题(就是 log apply 到 PM 上的 key-value 数据中),创新的使用了一种 cross-referencing logs (CRLs) 技术。


3. Implementation

3.1. Bullet architecture

首先看看 Bullet 的架构,如上图,Bullet 分为 front-end 和 back-end:

  • front-end 将 kv 写入 DRAM hash table 中,为了保证数据落盘,还要写 log,log 是在 PM 设备上,front-end 有多个 log writers 线程(DRAM 中的 hash table 相当于就是一个 read/write Cache,因为毕竟 DRAM 相比于 PM 还是在性能上有优势的)
  • back-end 在 PM 上:有一个 hash table 负责持久化 key-value 数据;多个 log 文件。后端也会有多个 log gleaners 线程,负责将 Op log entry applied 到 PM 上的 hash table 中


3.2. CRLs

相比传统是只有一个 log,多个 log 会减少竞争,但同时也会带来一致性问题,因为需要将多个 log 按顺序 applied 到 back-end 的 hash-table 中才行,论文给出了一个巧妙的解决方案,它就是 cross-referencing logs (CRLs) ,其大致的思路就是在每个 Op log entry 中会记录其前一个有依赖关系的 log entry 的指针,所谓的有依赖关系,就是操作同一个 key 的 Op log entry 就是有依赖关系,它们 apply 的时候必须按照严格的写入顺序 apply。


下面来详细的分析 CRLs 核心结构:

  • Op log entry :主要关心几个字段就可以了
  • op code : 什么 op 类型,update/delete
  • applied : 是否被 applied,也就是是否已经后拷贝到 back-end PM 上的 hash table 中了
  • pre : 前一个依赖 op log entry 的指针(如果是个 update/delete,那么其 pre 为 NULL)

  • lentry :

就是 Figure 3: 的下面部分,它是一个持久化的 K-V Pairs,每个 key-value 数据还会有一个 lentry Pair 对应,其记录了这个 key-value pair 新的 Op log entry 的位置,这样一个新来的 Op log entry,无论是 append 到哪个 log 上,只需要读取这个 lentry,然后存放在自己的 pre 字段中,然后更新自己的位置为 lentry 即可。


3.3. Appending op log entry

下面来看看,CRLs 是如何 Write Op log entry 到 log 文件中的,下面给出 append 一个 Op log entry 的步骤:

  • 根据 key-value pair 加锁
  • 读取这个 key-value pair 的 lentry,并放在当前 Op log entry 的 pre 字段中
  • 持久化这个 Op log entry
  • 更新当前 Op log entry 的位置到 lentry 中(注意这步是 cas 操作)
  • unlock

从上面的步骤可以看出,相比单个 log 文件,多个 log 文件并发性将会极大提升。下面给一个图例(三个 log 文件,front-end 的 log writer append Op log entry 到 log 文件中,back-end 的 log gleaners 将 Op log entry applied 到 back-end 的 hash table 中):


3.4. Applying Log Records

接着来看,如何 applied 一条 Op log entry 到 PM 的 key-value (hash table)数据中

  • 从 log 的 head 取一条 Op log entry (tail 用于 append)
  • 然后在 lentry 中取出整个具有依赖关系的 Op log entry list
  • 按照相反的顺序 applied,并跟新 Op log entry 的 applied 字段(因为是 pre 指向的更早的 Op log entry,applied 的时候必须按照 Op 的顺序)
  • 更新此 key-value pair 的 lentry


3.5. Optimization

3.5.1. Dynamic Worker Threads

可以根据 read/write 的比例,动态的调整 front-end log writers 线程 和 log gleaners 线程的数量,如下图是 write-heavy workload 场景,因为在 write heavy 的场景下,由于 log 空间有限,需要多一些的 gleaner 线程尽快将 log 中的 Op log entry apply 到 PM 中 key-value hash table 中,避免阻塞 write。


3.5.2. Overwriting

在 apply Op log entry 的时候,因为是将整个有 key-value pair 的 op log entry list 都拉出来了,实际上只有后一条被 applied 就可以了,前面的都可以直接忽略,如下图,key 2 的前面两个 Op log entry 就被忽略了。


不过这里有个顺序需要注意一下,保证即使出现故障也能够一致:

  • applied key 2 的后一条 Op log entry
  • 然后再按照 lentry list 的相反顺序修改 Op log entry 的 applied 字段


4. Summary

CRTLs 思路比较有意思,有些乱序 applied 的意思,感觉和 PolarFS [2] ParallelRaft 中乱序提交和乱序 apply 有着异曲同工之妙。


Notes

限于作者水平,难免在理解和描述上有疏漏或者错误的地方,欢迎共同交流;部分参考已经在正文和参考文献列表中注明,但仍有可能有疏漏的地方,有任何侵权或者不明确的地方,欢迎指出,必定及时更正或者删除;文章供于学习交流,转载注明出处


参考文献

[1]. Closing the Performance Gap Between Volatile and Persistent Key-Value Stores Using Cross-Referencing Logs. https://www.usenix.org/conference/atc18/presentation/huang

[2]. PolarFS: An Ultra-low Latency and Failure Resilient Distributed File System for Shared Storage Cloud Database. http://www.vldb.org/pvldb/vol11/p1


分享好友

分享这个小栈给你的朋友们,一起进步吧。

分布式存储笔记
创建时间:2019-12-13 16:59:52
分布式与存储技术
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

栈主、嘉宾

查看更多
  • 暗淡了乌云
    栈主

小栈成员

查看更多
  • bluetooth
  • 栈栈
  • ?
  • R-B
戳我,来吐槽~