FAST’23 ADOC
2023-3-14|2023-8-10
DieInADream
type
status
date
slug
summary
tags
category
icon
password
Property
Aug 10, 2023 06:53 AM
References
FEAT_7.11
supermt • Updated Jan 17, 2024
- 自动协调日志结构键值存储中组件之间的数据流以提高性能

Abstract
- LSM 的一大痛点就是写停顿,即在很大写压力的时候写性能的突然下降。之前的研究将写入停滞归因于一个特定的原因,如资源短缺或调度问题。
- 本文通过在多种存储设备上对 RocksDB 进行评估,系统地研究了发生写阻塞的原因。结果表明,侧重于单个方面的结论虽然有效,但并不普遍适用。在 RocksDB 上的实验结果表明,数据溢出是 LSM-KV 系统中一个或多个组件由于数据流激增而迅速膨胀的现象,可以解释写入停顿的形成。我们认为,通过平衡和协调组件之间的数据流,我们将能够减少数据溢出,从而减少写入停顿。为此,提出一种优化框架 ADOC (Automatic Data Overflow Control),自动调整系统配置,特别是线程数量和批处理大小,以最小化 RocksDB 中的数据溢出。
- 对 RocksDB 的广泛实验评估表明,与自调整的 RocksDB 相比,ADOC 减少了 87.9% 的写入停顿时间,并提高了 322.8% 的性能。与手动优化的最先进的 SILK 相比,在合成写密集型工作负载下,ADOC 的吞吐量最高提高了 66%,同时在真实世界的 YCSB 工作负载下达到了相当的性能。然而,但 SILK 平均要多消耗 20% 以上的 DRAM
Introduction
- LSM 因优异的写性能应用广泛,但是在写密集负载下也会遭遇写停顿的问题。
- 写停顿就如下图所示的红线,即吞吐的突然下降。测试了多种设备下的性能,发现了写停顿的两个特征:
- 普遍性(所有设备都会存在,尽管不同设备可能是在不同条件下触发的写停顿)
- 和设备关联性很强:写停顿的持续时间、下降速度受到设备类型和写强度等多种因素的影响

- 已有的关于写停顿的研究:(这些研究都是在特定设置下进行的,不够通用)
- ATC’19 SILK
- SOSP’19 KVell
- arXiv 2019:On performance stability in LSM-based storage systems
- VLDBJ’20 LSM-based storage techniques: a survey
- SIGMOD’12 bLSM: a general purpose log structured merge tree
- ATC’20 MatrixKV
- FAST’20 FPGA-Accelerated Compactions for LSM-based KeyValue Store
- 本文提出了自动数据溢出控制 (Automatic Data Overflow Control, ADOC) 框架,通过协调 LSM-KV 组件之间的数据流来最小化写入停顿。为此,首先进行了广泛的实验研究,以分析写停顿的发生模式
- 以往很多研究认为写停顿是因为资源枯竭,但是我们发现即便硬件资源还有富余也会停顿。这表明写入停顿不仅发生在被动阻塞情况下,也发生在系统主动暂停输入流以避免进一步的性能损失时。
- 我们发现流行的 LSM-KVs,如 LevelDB 和 RocksDB,已经使用主动延迟策略来避免“磁盘溢出”,这是指刷新或合并作业无法跟上写入速率的情况。
- 通过深入分析,我们发现写停顿的根源是一种更普遍的磁盘溢出形式,我们称之为“数据溢出”。具体来说,数据溢出是指 LSM-KV 系统中一个或多个组件由于流入其中一个组件的数据量激增而迅速膨胀。
- 根据形成数据溢出的组件,我们将数据溢出分为三种场景。本文还展示了数据溢出如何能够解释早期研究无法解释的局限性。基于这些观察,设计并实现了一个自动调优框架 ADOC,用于统一控制和协调 LSM-KV 组件之间的数据流,以避免数据溢出。ADOC 具有以下 4 个主要特点:
- 1) 均衡利用资源,减少写阻塞,提高性能
- 2) 它是一个设备透明的解决方案,提高了各种设备的性能,从传统的 HDD 到最先进的 SSD 和 PM 设备
- 3) 无需人工干预的自动调优系统
- 4) 可通过 LSM-KV 系统的本地接口实现,具有高度的可移植性
Background
Advanced Storage Devices
- NVMe SSD:通过 PCIe 总线连接,使用 NVMe 协议通信。NVMe 是针对于 PCIe SSD 设计的,NVMe 的命令集直接和系统 CPU 通信,而不需要额外的总线控制器。结合扩展的命令队列,NVMe 提供了比 SATA 和 SAS 等传统协议更高的并行度。
- PM:两种模式。相比于 NVMe SSD 有更低的写延迟,支持字节寻址,不要求 GC。但是 PM 连在了内存总线,PM 的 IO 处理消耗大量的 CPU 资源,因为带宽相比于 DRAM 有限,高并发的时候很快就饱和。虽然 Intel 停止了 3D XPoint 产品的开发,但是还有其他形式的 NVM (CXL-SSD)。
LSM 架构
- 组件不做过多介绍,两种后台操作:flush 和 compaction
- Compaction 可以继续细分:
- L0-L1:不能和其他 L0-L1 Compaction 并行,因为 L0 数据表范围重叠,
- 更深层次的 Compaction:可以并行执行

Write Stall
- 以前的研究表明了大概有三种 write stalls:
- MT Stall:内存组件满,比如 RocksDB 如果配置了两个内存组件,两个都满了的话就会导致 stall。这是最常见的一种 stal
- L0 Stall:当 L0 的文件数量达到预定义的阈值就会减缓或者停止数据流入,从而导致 Stall。RocksDB 设置的默认阈值是 20 减速,36 停止。这种类型的控制最早出现在 LevelDB 中,但已被大多数使用类似合并策略的后续实现所采用
- Pending Input Size (PS) stall: 当待处理的合并作业的输入大小超过某个阈值时,LSM-KVs 还会使系统变慢或停止。需要注意的是,待合并的输入大小不仅指 SSTable 中重复和过时的条目,还包括 SSTable 中所有待合并的条目。在 RocksDB 中,用于降低系统速度和停止系统的默认 pending compaction input size 阈值分别为 64GB 和 128GB。之前的研究使用术语“合并待决字节 compaction pending bytes” 来表示该值,而在本研究中,我们使用术语“冗余数据 redundant data”。这种控制的目的是减少冗余数据的总量,或者当合并作业发生在较深的层次时,避免磁盘带宽突发。
来自以前研究的观察
- 我们使用 RocksDB 的实验结果来回顾之前的研究。虽然这些早期研究为写作停顿的原因提供了有价值的见解,但这些见解都是有限的,因为这些见解无法解释许多实验结果
实验设置
- 不同盘

- Ubuntu 18.04 LTS,CMake 3.10.2,RocksDB 6.11(注意其实官方在 7.5.2 有对 stall 做优化)
- db_bench - fillrandom,写入 1h,这段时间足以触发各种写入停顿,并在所有设备中维持一种趋势。size: K16-V1k。
- 所有实验都是在吞吐量峰值下评估的,因为只有当写压力足够大时,才会出现写停顿,如图 1 所示。

- 使用一个官方提供的 嵌入式 event listener 来测量写停顿,提供了基本信息,如总持续时间和每种类型的写暂停出现的次数。得到的所有实验结果均为 3 轮执行的平均值:这三轮需要 240 小时
- 主要考虑了两个参数对性能的影响:
- 并发线程数:决定了可以分配给每个线程的 CPU 时间和盘带宽
- RocksDB 默认 四分之一的线程分配给刷新作业 (四舍五入),剩下的给 Compaction
- batch size:即 Memtable 和 SSTable 的大小,对于性能分析很关键。因为:
- 控制了调度模式和后台输入的规模
- 它会影响不同级别的数据分布
现有研究的限制
- 现有的研究都是从一个单一组件的角度来分析的,我们做了总结。
资源耗尽:
- 一些研究认为是带宽争用,其他则认为根本原因是 CPU 利用率
- 我们做了实验来验证:下图展示了随着线程数的增加,停顿的出现次数和持续时间
- 首先检查 CPU 利用率
- O1:对于 PM 和 NVMe SSD 来说,停顿的时间随着线程数的增加而降低,直到达到 6 线程。PM 降低的更显著。六线程的时候,PM 和 NVMe SSD 的 CPU 利用率还是很高。所以得到结论 C1 (高 CPU 开销是写停顿的一个原因)
- O2:但是,我们还从图 3 中观察到,当线程数超过 4 时 ( CPU 利用率下降,如图 4 所示),写暂停发生次数开始下降,而持续时间略有增加。该特征在 PM 和 NVMe SSD 上更明显。得到结论 L1(如果线程数超过一定数量,CPU 利用率会持续下降,但会导致写暂停时间的增加)
- btw,图 3 中 PM 其实在 6 线程后才表现出这样的趋势
- 最终结论:有限的 CPU 资源可能在某些场景下是写停顿的原因,但是并不普适。
- 检查 batch_size:
- O3:对于 PM 和 NVMe SSD 而言,batch 的大小对 CPU 利用率影响不大,但是发现写停顿的次数和持续时间在大 batch 的时候要更低。
- O4:但是超过六线程后,PM 在大 batch 512MB 的 CPU 利用率要低于小 batch,相应的 stall 持续时间也变长了,除开 15 线程及其更多线程。
- 对应得到了结论 L2:即使 CPU 利用率很高,仅通过增加批处理大小就可以减少写入停顿。也就是说,CPU 利用率和写停顿是没有那么高的相关性
- btw,这里其实很片面。因为实验中 CPU 利用率的计算方式是标准化了的,即多线程利用率求了平均,但其实更好的方式是针对具体完成任务类型来分开讨论。真实的情况推测应该是 写停顿和 CPU 利用率是相互影响的。
- 发生了写停顿,通常对于前台线程来说就意味着 CPU 利用率的降低,因为没有那么多数据需要前台线程的 CPU 来处理了。
- 但是造成写停顿的原因,又可能是因为后台做 flush/compaction 的线程的 CPU 达到了瓶颈,导致后台线程处理数据的速度跟不上数据涌入的速度。
- 需要更具体到每个线程/任务类型的 CPU 开销分析才有说服力。


- 检查磁盘带宽:
- 有很多研究认为随着线程数的增加,磁盘带宽饱和,不堪重负,导致写停顿。也就是 结论 C2, C3。但是我们有一些观察表明,即使磁盘空闲,系统也可能被暂停。
- 观察理论带宽限制,即当设备被 FIO 工具使用多线程产生的大量请求给填充的时候,观察到的峰值带宽。以及图 5 中随着线程数量增加使用的峰值带宽。虽然对于 HDD 和 SATA SSD,峰值达到了理论带宽限制,但对于 NVMe SSD 和 PM,仍然有很大的空闲带宽差距,表明 即使有空闲带宽,也会发生写停顿 ([L3])
- 另外,如果写停顿是因为带宽不足,设备应长时间处于高写入压力下,这将使平均带宽接近理论值。但是图 5 结果表明不是这样。
- btw:这里感觉也不是那么严谨,需要进一步去确认这里的带宽是如何测试计算的。另外就是只使用了 batch size 来区分,默认了主要是 flush 带来的写操作,但其实 Compaction 涉及到表的读操作,然后表的读操作也不一定是读整个表,需要再看读表的 I/O 大小。

- 代表方案
- SILK
- RocksDB Experience
- Performance Bottlenecks and Potentials in RocksDB with Storage Evolution
- KVell
- ICDE’20 FPGA-based Compaction Engine for Accelerating LSM-tree Key-Value Stores
- MatrixKV
- FAST’20 FPGA-Accelerated Compactions for LSM-based KeyValue Store
- 确认的观点:
- C1. 高 CPU 开销是写停顿的一个原因,增加后台线程可以减少 CPU 利用率,因此减少写停顿。(3,4,5,7)
- C2. 如果增加线程数,大多数设备都表现出带宽使用增加,CPU 利用降低。但是线程数达到一定的阈值的时候,写停顿的发生次数会增加。(2)
- C3. 因为现代设备更高的带宽和更好的并行性,所以 stall 的次数和持续时间在 PM 和 NVMe SSD 上相比于 SATA SSD 有所降低。(1,4,6)
- 局限性:
- L1. 如果线程数超过一定数量,CPU 利用率会持续下降,但会导致写暂停时间的增加。也就是说,降低 CPU 利用率不会减少写停顿
- L2:即使 CPU 利用率很高,仅通过增加批处理大小就可以减少写入停顿。也就是说,CPU 利用率和写停顿是没有那么高的相关性
- L3:现代设备可以提供比传统设备多得多的带宽,但在带宽容量达到之前,写停顿仍然可能发生。
L0-L1 的 Compaction 数据移动:
- 一些研究认为 L0-L1 因为重叠键没法并行执行 Compaction 直接导致了写停顿。
- 如下图所示,绘制了 L0-L1 压缩过程时间中瞬时吞吐量,这之前的结论部分正确。C4
- 使用两个线程,初始发现系统吞吐的下降几乎和 L0-L1 的 Compaction 是匹配的。就像图中左边的虚线箭头指定的所示。但是当系统持续处理输入流的时候,这种匹配就消失了,即出现了右边箭头所示的位移。即 L0-L1 发生之前进行了 Compaction。
- 线程数增加到 20 的时候,如下图 b 所示,L0-L1 的合并发生的更频繁,这时候在 L0-L1 Compaction 时间和写停顿之间就没有了明显的映射关系。L4

- 代表方案:SILK,MatrixKV
- 确认的观点:
- C4:在执行的早期阶段,NVMe SSD 和 PM 中的性能波谷与 Compaction 的发生相匹配
- 局限:
- L4:性能低谷和 L0-L1 合并作业之间的对应关系会随着时间的推移而减弱,特别是在多线程环境中
深层次的 Compaction 数据移动:
- 有研究认为深层次的 Compaction 任务的高资源消耗和其他后台任务竞争,造成了写停顿。这个结论只有部分正确。
- 如下图 a 所示,更多的线程意味着更频繁的 Compaction 任务,后台线程的平均处理率也就下降了,如下图 b 所示。C5

- 但是如果冲突的 Compaction 任务是写停顿的主要原因的话,我们应该观察到 PS Stall 的出现次数也增加才对,就像缓慢的 flush 增加了 MT 停顿一样。但是我们观察到了图 8
- PS Stall 的出现次数随着线程数的增加以及 batch 的增大反而下降了,和之前的结论是相反的 L5

- 代表方案:
- On performance stability in LSM-based storage systems (extended version).
- PebblesDB
- bLSM
- 确认观点:
- C5:当生成更多线程用于压缩 Compaction 作业时,刷新 flush 作业 的处理速度会降低
- 局限性:
- L5:随着线程数量的增加,由缓慢压缩引起的 PS 停顿的发生减少

Data Flow
- 早期研究可能主要关注了造成写停顿的个别方面,而本文的分析揭示了更普适的写停顿的根源,
Data Overflow in Modern LSM-KVs
- 数据溢出是指在 LSM-KV 系统中,由于流入某一个组件的数据量激增,导致某一个或多个组件迅速膨胀。当不同后台作业的处理速度不匹配时,就会发生这种情况。我们确定了三种数据溢出类型,即内存溢出、0 级溢出和冗余溢出,如图9所示。我们现在更详细地描述这些
- 内存溢出 MMO:当系统输入速率超过不可变的 Memtable Flush 速率时,就会发生 MMO。因此,由于不可变的内存表不能及时刷写,内存组件中就没有足够的空间来吸收新数据。在大多数现代的 LSM-KVs中,在 MMO 中,系统会停止接收输入,因为没有空间来缓冲即将到来的更新。这导致 MT Stall
- Level0 溢出 L0O:L0O 发生在 L0-L1 合并的处理速率无法匹配刷写速率时。这导致级别 0 的SSTable 数量增加。在现代 LSM-KVs 中,当这个值达到某个阈值时,输入流就会停止或减慢,这样积累的数据就可能被消耗掉,从而导致 L0 停顿
- 冗余溢出 RDO:当合并线程的工作效率无法匹配冗余数据产生的速率时,就会发生 RDO。在现代 LSM-KVs 中,当冗余数据的大小达到阈值时,系统会减慢或停止输入,等待合并线程清除累积的冗余数据。这样的行动导致 PS 停顿

Explaining the Unexplained
- 在第 3 节中,我们展示了早期研究中得出的结论如何无法解释我们获得的大量实验结果的某些部分出现停顿的原因 (表 2 )。在这里,我们展示了如何用数据溢出来解释这种不一致。为了观察本节中的写入停顿,我们利用 RocksDB 提供的日志文件。虽然上一节中使用的嵌入式侦听器只提供基本信息,但日志文件提供了每个写停顿的更详细信息,包括停顿类型、有限的输入速率和确切的时间戳。
Resource Exhaustion
- 首先考虑在低资源利用率的时候,写停顿是如何发生的。关键的潜在原因是这三种数据溢出都会在系统达到硬件限制之前停止或降低输入速度。让我们来详细说明
- 首先当刷新的速度不够高导致不能及时持久化输入请求的时候,MMO 将暂停输入。图 7b 表明刷回任务在后台作业之间分配的带宽最少,因此,平均刷写速率随线程数单调下降。这是因为随着线程数的增加,更多线程强制共享有限的带宽,导致更少的带宽分配给 flush 线程。这就导致了 Immutable 不能被及时刷回,这也就是对于如 SATA HDD 而言(CPU 资源 相对充足的场景)最常见的写停顿原因。解释 L1-L3
- 我们展示了 RDO 如何在 CPU 利用率很低且有空闲磁盘带宽时使 LSM-KVs 停滞。图 10b 展示了冗余数据是如何聚集的,因为深层次的 Compaction 不能跟上 L0-L1 Compaction。最终在冗余数据达到 64G 的时候 RDO 发生,也就是默认的 PS stall 阈值。此时系统会放慢输入速度,如红线所示。但是,请注意,在这些停顿点上,CPU 和带宽利用率与执行中的任何其他点一样低(且稳定)(图10(c)),显示了在低资源使用情况下如何发生 RDO。

L0-L1 Compaction Data Movement
- 这一节讨论为什么 L0-L1 的 Compaction 和写停顿的次数不再匹配,也就是解释 L4
- 首先,如图 6a 所示,L0-L1 的合并在两个线程的时候就出现了不匹配的现象。在执行的更早阶段,因为深层次的数据还没有聚集,L0-L1 的合并很容易分配给一个线程,因此早期 Compaction 和 Write Stall 是匹配的。然而 随着继续执行,数据开始聚集然后有了更多深层次的 Compaction 请求。在线程数量有限的情况下,这减少 L0-L1 合并分配给线程的机会,因此这时候开始不匹配。
- 现在考虑线程数是 20 的情况,我们有足够的线程来做 L0-L1 Compaction。但是因为线程多,Flush 任务的可用带宽就减少了,从而导致刷新任务的处理速度变慢,造成更多的 MMO。也就是说这时候的写停顿主要是 MT Stalls,然后 L0O 几乎不发生,也就几乎不会跟 L0-L1 产生什么关系(图 6b)。
Deep Level Compaction Data Movement
- 早期的研究说随着线程数增加,PS Stalls 也会增加,对于四线程之前来说确实是对的。但是过了四线程就开始截然相反。也就是我们前面归纳的 L4
- 这个可以用 RDO 解释,PS Stalls 的初始 spike 是因为 Flush 获得了足够的带宽。当线程数增加到 4,L0O 的出现次数就会减少,因为分配了更多的线程,从而导致更多数据被挤倒更深的层次,导致深层次 Compaction 任务处理速度减慢,从而增加了 PS Stalls 次数。但是超过阈值 4 之后,刷写速率降低,从而降低数据冗余率。这减少了处理深层合并任务的需求,最终减少了 RDO
- 超过 4 之后 Flush 线程得到的带宽变少了,所以处理的没那么快了。

Automatic Data Overflow Control
- 我们的目标是最小化甚至移除写停顿对 LSM 的影响。所以本文设计了一个框架,ADOC。自动数据流控制,它控制数据流,使数据溢出可以最小化。数据流是通过在线调整线程数量和批处理大小来控制的,因为这些值对数据流有很强的影响,如第 4 节中的讨论所示,大多数 LSM-KVs 提供 api 来调整这两个值,而无需重启系统。
- 我们根据两个原则开发 ADOC。
- 第一个是设备透明性。新的存储设备将继续发展,而不是针对特定的存储设备进行优化,不管底层存储设备是什么,ADOC 都应该能够自我调整以减少写停顿。为此,ADOC 监视组件之间的数据流,而不依赖于底层设备的特定性能参数。然后,通过调整线程数和批处理大小来控制后台作业的处理速率和调度频率,从而控制 LSM-KV 内的数据流量
- 第二个是易于移植。如图 11 所示,ADOC 的设计是 RocksDB 控制流机制的直接扩展。不像MatrixKV 和类似的方法需要改变 Compaction 策略,或者 SILK 那样和自适应的 RocksDB 调整内部线程调度和 IO 进程,与此不同,ADOC 不会破坏 LSM-KV 系统的内部架构,使其具有高度可移植性
- Auto-tuned Rate Limiter | RocksDB
- 本文的实现中只是修改了两个类,一个是 Options 类,它控制是否启用 ADOC 调谐器,并在共享的 C++ vector 中记录系统的即时信息。另一个是调谐器类本身,它将周期性地唤醒调谐器线程以执行调优操作。总的来说,我们添加了大约 300 行代码(LOC)来实现 ADOC,其中 250 行代码用于调谐器,50 行代码用于收集系统状态。
- 现在我们讨论触发机制以及调整这些参数的动作。回想一下,我们将数据溢出确定为写入停顿的根源。因此,对于每个时间窗口 , ADOC 监控数据溢出并采取相应的行动,如下所述。在我们当前的实现中,我们根据经验观察将 设置为 1 秒;较大的值不够敏捷,无法快速检测溢出,从而导致最先进的高性能存储设备的性能下降,而较小的值可能会由于响应太快而产生开销并导致波动
- MMO:当不可变的 Memtable 被刷写之前活动的 Memtable 被填满时,ADOC 判定 MMO 发生了。在 MMO 检测中,ADOC 通过减少线程数量来提高刷写速率,这将为刷写作业预留更多带宽,并通过增加 batch 大小来提高处理速率
- L0O:判断 L0O 是否发生的逻辑与 RocksDB 相同,即 L0 文件数量超过阈值 (RocksDB 默认为20)。一旦检测到 L0O, ADOC 会增加线程的数量。这可以提高为 L0-L1 压缩分配线程的机会,并降低刷写速率以缓解溢出。在这种情况下,批量大小不变,因为增大它会增加 L0-L1 压缩的负载,而减小它会产生更多的 L0 文件,两者都导致更多的 L0 停滞。
- RDO:与 L0O 一样,判断是否发生 RDO 的逻辑与 RocksDB 相同,即当总冗余数据大小超过阈值 (RocksDB 默认为64GB) 时。当检测到 RDO 时,ADOC 会增加线程数并降低批量大小。前者提高了深层合并的速率(同时也降低了刷写速率),后者允许调度器生成更细粒度的合并作业,因为小而密集的合并作业有助于提高冗余缩减的效率
- 如果 中检测到多个溢出,我们根据实验观察选择处理 L0O、RDO、MMO 顺序的溢出。此外,在调节调节钮时,我们采用了以其在 TCP 拥塞控制[40] 中的应用而闻名的 AIMD (Additive increase /Multiplicative Decrease) 算法[9]所使用的方法。使用 AIMD 的原因是该算法与 ADOC 工作场景的适应度,即轻轻增加调谐旋钮以探索合适的配置,快速移除过度分配的资源以避免资源竞争。我们将线程数增加 2,批处理大小增加 64MB,这是 RocksDB 的默认线程数和批处理大小值,而当减少时,这些值减少了一半。调整后,分配给刷写作业的线程数也会调整为总线程数的四分之一,就像默认设置一样
实验
- 最大 batch 大小 512MB,ADOC 基于 RocksDB v7.5.3,截至本次提交的最新版本。SILK 是基于RocksDB 5.7.1 构建的,由于兼容性问题,我们将 SILK 移植到较新的版本的尝试失败了,因为自 RocksDB v6 以来已经进行了大量优化。因此,SILK 的所有性能测量都是在 RocksDB v5.7.1 上进行的。在其中一个实验中,我们也展示了移植到 v5.7.1 上的 ADOC 结果,虽然与v7.5.3 的结果有一些差异,但总体上趋势是非常相似的。
- 对比方案:
- RocksDB-DF:默认 2 个后台工作 threads,64MB 的 batch
- -AT:开启了自动调优的版本,自动修改速率限制器的阈值,根据后台线程的 IO 压力来限制后台线程的IO操作数。RocksDB-AT 还根据线程优先级调整每个线程的分配率,以避免优先级低于 flush 作业的“饿死”合并作业。
- SILK-D
- SILK-P:4 bg_threads,128M batch_size
- SILK_O:我们认为这是我们的实验平台中性能最好的设置,具有 8 个后台线程和 512MB 批处理大小,这些批处理大小是通过详尽的调优尝试手动获得的,我们考虑了10 种 (2,4,8,…, 18,20) 线程和两个 (256MB和512MB) 批量配置。我们没有考虑64MB和128MB的批量大小,因为在观察 SILK-D 和 SILK-P 的结果时,我们发现更大的批量明显更好。除了线程和批量大小设置之外,SILK 实现还使用了特定的硬编码设置。一个是硬编码到 db_bench 工具中的带宽分配。为了忠实地相应地配置这三个版本,我们设置了配置标志,将整个介质带宽的四分之一(表1)留给合并作业,其余的留给刷新作业。该比率保留了原始 Paper 中使用的比率。此外,与最初的实现一样,我们通过设置 L0 SST 文件数量的阈值来禁用 L0O,当达到一个非常大的值时,这会减慢输入流的速度

Microbenchmark
- 吞吐量
- ADOC 最好
- SILK-O 在高端设备上的表现要好得多,但在低端设备上的表现并不怎么样。最值得注意的是,我们观察到 SILK 的配置对整体性能有相当大的影响,其中最好的配置不是直接找到的
- RocksDB-DF 和 RocksDB-AT 的表现与 SILK-D 和 SILK-P 相当,但不如 SILK-O
- 实验结果表明,RocksDB-AT 自动决定不同后台作业[39] 的带宽利用率,但这还不足以发挥最佳性能。因此,我们发现,在 NVMe SSD 和 SATA SSD 上,RocksDB-AT 的性能优于RocksDB-DF,这与 RocksDB 针对闪存设备进行了优化[11,15,25]的事实一致,但在PM和SATA硬盘上的性能较差。用户需要提供带宽信息也是有限制的

- Stall duration (bar) and occurrences (lines).

- Comparison of CPU utilization, disk space occupied, and input data size with the fillrandom workload

- Proportion of major operation occurrences, with numbers representing total occurrences.

- Tail latency in fillrandom workload

Macrobenchmark
- YCSB
- 对于Load这种纯粹的写工作负载,ADOC胜过SILK-O。但是,对于YCSB-A、-B、-C和-F工作负载,SILK-O性能更好。对于YCSB-D和-E,胜者取决于设备。
- 回想一下,SILKO和ADOC运行的RocksDB版本是不同的。为了消除版本效应,我们还在RocksDB 5.7.1上运行ADOC。图17中的ADOC-5.7.1结果表明,版本差异对ADOC性能有一定影响,在大多数运行阶段,旧版本的性能更好,尤其是硬盘上的YCSB-A和-E
- 尽管从微基准测试中可以看出,在写操作方面,ADOC的性能比SILK-O要好得多,但SILK-O表现良好的主要原因可能是内存使用过多。如图18所示,我们发现SILK-O使用的内存比ADOC多76.8%。更大的内存允许从缓冲在内存中的数据中处理更多请求,这不仅有利于读取密集型工作,也有利于更新密集型工作,如YCSB-A和-F
- 总之,SILK-O和ADOC的性能相当。然而,回想一下,对于SILK,性能的变化很大程度上取决于初始设置,而“最佳”SILK- o设置是手动获得的。这与ADOC相反,ADOC是一种不需要人工干预的在线调优系统

- 内存开销

- Throughput for the read-while-writing workload
- 作为宏基准测试的补充,我们在db_bench的边读边写负载下,使用两个线程(reader和writer)分别产生了50M的写请求和读请求。注意,由于reader和writer并发运行,reader线程可能会请求尚未被writer持久化的数据项;我们在图19中显示了找到的条目的百分比以及各种方案的吞吐量。结果表明,ADOC比SILK-O提高了5.2% ~ 45.3%的吞吐量,比RocksDB-AT提高了95% ~ 135%

- Comparison of system throughput and resource consumption with different tuning knobs triggered, the values shown are normalized to the value of ADOC

- Tuning actions during one-hour execution.

- Utterance
