ATC 2023 Paper 论文阅读笔记整理
问题
由于需要执行昂贵的后台压缩操作,CPU 往往是持久键值存储的性能瓶颈。在日志结构合并树(LSM树),标准的基于磁盘的键值存储设计[2,4,8,22,41],压缩可以在生产工作负载中消耗高达45%的CPU。我们实验发现使用RocksDB,压缩消耗总CPU周期的72%。
在包含多个相同数据副本的复制存储系统中,我们观察到 CPU 可以用多余的网络带宽来换取。在复制键值存储的情况下,压缩操作只需在一个节点上执行一次,已经压缩过的数据可以传输到其他节点的磁盘上,节省了它们大量的 CPU 时间。而且现代数据中心的网络流量往往没有得到充分利用;例如,Alibaba[1]和Snowflake[47]的集群跟踪显示,50-75%的网络容量始终保持空闲。
为了进一步降低总 CPU 消耗,文件复制协议可以利用 NVMe-oF,这是一种网络存储协议,可以完全将网络和存储数据路径卸载到网卡,不需要目标节点的 CPU 参与。然而,NVMe-oF 是一种单向协议,如果使用不当,很容易在目标节点引起数据损坏或数据丢失。
挑战
使用NVMe oF跨存储节点复制文件会带来两个挑战。首先,由于远程节点的本地文件系统(例如ext4)不参与写入文件,它不知道更新的文件及其位置,无法读取它。其次,运行在远程节点上的键值应用程序也必须与传入的文件同步。它的应用程序级内存数据结构必须更新,以便从本地存储设备上更新的新文件中查找和读取数据,并且不能从压缩过程中删除的陈旧文件中读取数据。
本文方法
我们设计了 RubbleDB,利用 NVMe-oF 进行高效复制的键值存储。关键贡献是在远程节点提供文件系统同步和应用程序同步的机制,因此它可以安全、正确地读取通过NVMe oF写入的数据。
-
为了文件系统同步,RubbleDB 在所有节点上预分配所有磁盘数据为固定大小的固定位置文件。RubbleDB 维护一个文件映射,存储文件名与预分配文件位置之间的映射,并指示文件是否包含实时数据或旧数据。当复制新文件时,它被发送到一个不包含实时文件的预分配位置。当在压缩过程中删除文件时,它只是在映射中标记为旧,实际上并未删除。
-
对于应用级同步,RubbleDB 需要保持次要节点的内存数据结构同步,因此当它们从磁盘读取数据时,它们读取最新的对象版本。通过强制在副本之间应用版本编辑顺序的方法,确保在次要节点中对内存数据结构进行的更改与主节点执行的压缩操作一致。它还仔细同步从磁盘或内存中刷新的对象的删除,以避免在次要节点中以无序方式处理时意外删除对象。
开源代码:https://github.com/lei-houjyu/RubbleDB
我们在 RocksDB 之上实现了 RubbleDB,并展示它在写入密集型工作负载下相对于复制键值存储(如在所有副本节点上执行紧凑操作的 ZippyDB)提供了一致的 CPU 节省,吞吐量增加了最多 1.9 倍,并将尾部延迟降低了最多 93.4%。
实验
实验环境:在CloudLab上进行所有实验[24,40]。除非另有规定,复制组在多台r6525服务器上运行,客户端在一台带有复制器的c6420计算机上运行。每个r6525服务器都有两个2.8 GHz的32核AMD 7543 CPU、256 GB DDR4内存、一个1.6 TB的Dell Enterprise SSD和一个双端口Mellanox ConnectX-6 100 GB NIC。默认情况下,RubbleDB使用Mellanox NIC的NVMe oF卸载功能。c6420服务器有两个2.6 GHz的16核Intel Xeon Gold 6142 CPU和384 GB DDR4内存。操作系统是Ubuntu 20.04 LTS,Linux版本为5.4.0。
数据集:YCSB[20],Twitter Cluster[49]
实验对比:CPU占用时间,I/O节省,网络开销,吞吐量,尾延迟,不同复制比,故障恢复
总结
在包含多个数据副本的KV存储系统中,如何减少压缩的CPU利用率。作者利用网络和NVME-oF,在单个节点上压缩,压缩后传输到其他复制节点上。为了实现文件系统的同步,提出为数据预分配固定的磁盘空间,通过维护映射表确保复制节点的文件系统同步。为了实现应用级同步,提出在副本之间应用版本编辑顺序的方法,确保各复制节点执行顺序一致,避免删除导致的节点间不一致问题。