想象你管理着一家藏书百万的图书馆。每天都有新书从后门送进来,但你不会一本一本地把它们塞进对应楼层——太慢了。你先把书堆在门口的小桌上登记,等桌面堆满,再抱到一楼的书架;一楼放不下,就往二楼、三楼搬。可奇怪的是,每次向上搬一层,你都要顺手把那个楼层里已经摆好的旧书抽出来,和新书混在一起重新排序、重新誊写标签。于是,你明明只添了一本新书,为了维持整座图书馆的秩序,搬运工却来来回回搬了几十本旧书。这就是存储引擎里的“写放大”:应用请求写入 1 块数据,磁盘却可能为此写入了 30 块。本文要讲清的,正是这座“LSM 图书馆”为什么会产生这种浪费、怎么用公式把它算清楚,以及业界如何通过合并策略、层级设计和日志优化把这些额外搬运降到最低。

岗位关联

写放大是存储引擎性能的天花板:学会本文的量化公式与优化手段,你就能在读数据库源码、调参、做压测时,用一条公式快速定位写入瓶颈,让 SSD 寿命与写入吞吐同时受益。

目录
  1. 可视化演示
  2. 写放大成因
  3. 量化建模公式
  4. Compaction策略
  5. 参数调优
  6. WAL优化
  7. 业界实践
  8. 实测验证
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态演示LSM存储引擎写放大问题深度的核心机制,通过架构/数据/状态/性能四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

LSM存储引擎写放大问题深度:写放大问 写放大问题的概念与成因 写放大倍数的量化计算 核心机制可视化 LSM存储引擎写放大问题深度整体架构与关键组件

写放大成因

管理员的整理规则很简单:新书上架前先堆在门口临时桌登记,桌面满后就抱去一楼;一楼不够放,就把一层旧书连同新书一起重新誊写,搬去二楼。每向上一层,被牵动的旧书就多一批。管理员发现,自己一天下来手忙脚乱,真正摆好的新书却没几本——搬运工大部分时间都在挪动旧书。

计算机里的 LSM 树和这座图书馆惊人地相似。数据先写入内存中的 MemTable(临时登记桌),攒满后刷成磁盘上的 SSTable(书架上的文件);当某一层文件多到阈值,后台就会触发 Compaction(合并整理),把上层新文件与下层旧文件重新排序、合并写回。这个过程读旧写新,一次合并就把大量已经落盘的数据又写了一遍。

于是,磁盘实际写入量 = 应用写入量 + 多次合并重写量。合并的层数越多、每层牵涉的文件越大,重写就越多。在 LSM 里,写放大倍数 WA 通常定义为实际写盘字节数与请求提交字节数之比,它直接决定 SSD 寿命、IO 带宽与写入延迟。

回到图书馆:如果管理员放任每层反复腾挪,搬运工一天要搬上万本旧书。真实数据库里,写放大 10 倍、30 倍并不罕见——这正是我们接下来要量化它的原因。

WA=WdiskWapp\displaystyle \text{WA} = \frac{W_{\text{disk}}}{W_{\text{app}}}
WA=1 表示没有多余写入;生产环境常见的 10~40 倍意味着磁盘每写 1GB 数据,实际消耗 10~40GB 的 SSD 寿命与带宽。
  1. W_disk(磁盘实际写入量)统计周期内存储引擎向磁盘真正写下的字节数,包含刷盘与所有合并重写,是整个分数的分子。
    WdiskW_{\text{disk}}
  2. W_app(应用请求写入量)应用调用写入接口提交的原始字节数,用户以为只写了这么多,是整个分数的分母。
    WappW_{\text{app}}
  3. 比值(放大倍数)分子除以分母得到倍数,等于 1 表示没有放大,大于 1 的部分全是“白写的旧数据”。
    WdiskWapp\frac{W_{\text{disk}}}{W_{\text{app}}}

量化建模公式

要改造图书馆,先得数清楚搬运工到底多搬了多少本。管理员每天记录三件事:新到书的数量、实际被搬动的书的总数,以及书架层数和每层规模。有了这三本账,浪费就会显形。

对应 LSM,我们也有三个核心变量:层级数 L(书架层数)、大小比例 T(每往下放一层,容量放大为上一层的 T 倍),以及总量与最顶层的比例 N/M(顶层由内存表刷出的单次量决定)。它们之间的基本关系是 N = M×T^L:顶层一小批数据经过 L 次逐层放大,最终撑起总量 N。

工程中广泛使用的估计式认为:写放大约为“每层平均重写倍数”与“层级数”的乘积。T 越大,单层数据越多,合并时牵动的旧数据比例越接近 (T−1)/2;L 越大,数据被反复重写的次数越多。两者相乘,就是整棵树的放大账单。

代入常见配置:7 层、每层放大 10 倍,写放大 ≈ 7×4.5 ≈ 32 倍。也就是说,应用写 1GB,磁盘悄悄写了 32GB——这个数字,正是管理员“多搬的书”在磁盘上的代价。

WA≈L×T−12\displaystyle \text{WA} \approx L \times \frac{T-1}{2}
当 T=10、L=7 时,写放大约为 32 倍;T=4、L=7 时约 11 倍。层数与比例共同决定放大。
  1. L(层级数)从最上层到底层共多少层,每层数据量约为上一层的 T 倍,数据每下移一层就要被重写一次。
    LL
  2. (T−1)/2(每层平均重写率)合并时下层大约有 (T−1)/T 比例的旧文件被牵动,取平均约为一半,T 越大牵动越多。
    T−12\frac{T-1}{2}
  3. 整体近似(相乘)层数乘以每层平均重写率,得到整棵树的写放大估计,是工程上最常用的快速估算式。
    L×T−12L \times \frac{T-1}{2}

Compaction策略

面对整理问题,图书馆界分成两个流派。A 馆信奉“时时精整理”:每层书架永远整齐,来一本就归位一本;B 馆信奉“先囤后理”:新书先在临时区堆成几摞,堆满一整层再统一装箱上架。管理员发现,两家每天的搬书量天差地别。

LSM 里对应两种合并策略:Leveled Compaction(分层合并/精整理)与 Tiered Compaction(分级合并/囤积式)。Leveled 保证每层文件互不重叠,查询快、空间省,但每次合并都把下层旧文件一起重写,写放大高;Tiered 让同一层先攒出多个重叠文件,攒够再一次合并,写入几乎只写一次,但重叠文件多,读放大和空间放大都高。

两种策略的写放大可用近似式对比:Tiered 约等于 T−1,Leveled 约等于 L×(T−1)/2。当 T=4、L=7 时,前者约 3 倍,后者约 11 倍,差距接近 4 倍;数据规模越大、层数越多,差距越悬殊。

图书馆最终的选择取决于读者是多是少:写多读少的场景选囤积式省写放大,读多写少的场景选精整理换稳定读性能。没有免费的午餐,只有合适的姿势。

WAtiered≈T−1≪WAleveled≈L×T−12\displaystyle \text{WA}_{\text{tiered}} \approx T - 1 \ll \text{WA}_{\text{leveled}} \approx L \times \frac{T-1}{2}
Tiered 的写放大低到接近常数,Leveled 则随层数增长;差距可达 3~10 倍,但 Tiered 要用读放大与空间放大来交换。
  1. Tiered 的 T−1同一层囤到 T 份目标文件才合并一次,每份新文件平均被重写约 T−1 次,放大很小。
    T−1T - 1
  2. Leveled 的 L×(T−1)/2每层都精修,新数据每穿过一层都要付出约 (T−1)/2 倍的重写代价,再乘以层数 L。
    L×T−12L \times \frac{T-1}{2}
  3. 远小于号对比号强调两种策略在同一批数据上的写放大差距,可达到一个数量级。
    ≪\ll

参数调优

既然整理方式定下来了,管理员开始思考:图书馆到底该建几层?每层书架是上一层的几倍?调大一倍,楼层可以减少吗?这些问题直接决定搬运工的日均步数。

这就是参数调优:给定总数据量 N 和顶层基准 M(由内存表大小决定),层数与大小比例满足 N = M×T^L,两边取对数即得 L = log_T(N/M)。层数和比例相互制约:T 翻倍,L 大约减半。

但 T 也不是越大越好。工程经验上 T 取 4~10 比较平衡:太小则层数过多、文件又碎又小,每次合并的固定开销吃掉收益;太大则每层重写代价 (T−1)/2 直线上升。同时,增大内存表 M 能让层级变浅,直接降低写放大,代价是内存占用与崩溃恢复时间变长。

建楼有讲究:层数由总量和顶层共同决定,比例 T 则是平衡“整理次数”与“单次整理代价”的旋钮。T=10、7 层不是唯一答案,量好 N 和 M 再动手。

L=log⁡TNM=ln⁡(N/M)ln⁡T\displaystyle L = \log_T \frac{N}{M} = \frac{\ln (N/M)}{\ln T}
顶层越小、总数据越多,层数越多;给定 N/M 后,T 越大层数越少,但每层重写率越高,工程上取 4~10 为经验区间。
  1. N/M(总量与顶层比)数据库总数据量 N 与最顶层基准量 M 的比值,决定了数据需要被“放大”多少倍。
    NM\frac{N}{M}
  2. log_T(对数求层数)以 T 为底取对数,算出从顶层放大到总量需要经历的层级数,这是层数的本质。
    log⁡TNM\log_T \frac{N}{M}
  3. 换底公式(ln 形式)换成自然对数后,用计算器或程序即可快速求值,便于在调参面板里实时推算。
    ln⁡(N/M)ln⁡T\frac{\ln (N/M)}{\ln T}

WAL优化

管理员还有个心病:停电。万一整理到一半断电,还没誊写的登记单就全丢了。于是他在门口加了一本持久化的“登记台账”——每本书先在这本台账上记一笔,保证电源断了也能按台账找回书单。

这就是 WAL(Write-Ahead Log,预写日志)。LSM 数据先落 WAL 再进内存表,保证崩溃可恢复。但每次提交都触发一次磁盘 fsync 是昂贵的:单次 fsync 可能耗时几毫秒,而攒在内存里的数据本身写起来很快。日志落盘开销甚至可能占写入路径一半以上的延迟。

工程上使用组提交(group commit)与批量合并:把一小段时间内的多条日志在内存里攒成一个批次,一次性 append 到 WAL 并只 fsync 一次。于是 fsync 次数从逐条降为批次数,批量越大,摊到每条日志上的落盘成本越低,写放大与延迟同时下降。

台账不是负担,而是保险。把分散的记账合成一本,既保住了断电后的性命,也让单次落盘的代价被几十条记录分摊——这正是 WAL 优化的精髓。

Nfsync=⌈NwriteBbatch⌉\displaystyle N_{\text{fsync}} = \left\lceil \frac{N_{\text{write}}}{B_{\text{batch}}} \right\rceil
例如 6400 条写操作以 64 条为一批,fsync 只需 100 次;而逐条提交需要 6400 次,相差一个数量级。
  1. N_write(待写日志条数)单位时间内应用提交的写操作条数,是所有日志的总量。
    NwriteN_{\text{write}}
  2. B_batch(批次容量)组提交把多条日志合并为一次落盘的批大小,是分摊 fsync 成本的“公交载客量”。
    BbatchB_{\text{batch}}
  3. ceil(向上取整)批次不可能出现“半次”,余数也还需一次 fsync,因此向上取整得到真实落盘次数。
    ⌈NwriteBbatch⌉\left\lceil \frac{N_{\text{write}}}{B_{\text{batch}}} \right\rceil

业界实践

大图书馆们在实战中总结了不少经验,最有名的当属 RocksDB 的动态层级(Dynamic Leveling):与其给每层设固定阈值,不如让每层大小严格按比例递增,维持“每层都被装满”的健康状态。

原理是维护 S_{i+1} = T×S_i 的迭代关系,从顶层一路推算到底层,让每一层的利用率保持一致。配合大小比例、块大小、前缀压缩等配置,RocksDB 能把默认写放大压到 10~20 倍区间;而选用 Tiered/Universal Compaction 的高吞吐场景,可以进一步压到 5 倍以下。

硬件侧也有文章:把新数据优先落到低层省掉多次重写,使用更大容量的内存表缓存吸收突发写入,把 WAL 放在独立小分区避免与数据写互相干扰。软件与硬件的配合,能让 SSD 寿命延长数倍。

先进图书馆的经验告诉我们:写放大不是宿命。每一层的容量规划、每一块硬件的安排,都在静悄悄地决定“多搬书”的账单。

Si+1=T×Si\displaystyle S_{i+1} = T \times S_i
动态层级让第 i+1 层严格等于第 i 层的 T 倍,层与层之间大小守恒,避免上层过小、下层过大的“空转”。
  1. S_i(第 i 层大小)层级 i 的当前数据量,是递推的起点与基准。
    SiS_i
  2. T×S_i(放大规则)每往下一层容量放大 T 倍,这是动态层级维持的“满度守恒”约束。
    T×SiT \times S_i
  3. 递推到底(迭代)从最上层反复套用该式可得 S_i = T^i×S_0,最终层即总量 N,层间永不失衡。
    Si+1=T×SiS_{i+1} = T \times S_i

实测验证

道理讲再多,不如计数器说话。管理员给搬运工配了计步器:白天记新到书的数量,晚上对账实际搬动的书本总数,两者一除就是真实的“搬书放大”。没有这本账,所有理论都只是纸上谈兵。

工程上同样用两本账对账:W_app 来自应用侧写入统计,W_disk 来自引擎内部统计(如 RocksDB 的 compaction 写入字节)或块设备层指标。两者相除即实测写放大倍数,它能暴露配置是否真的生效。

基准测试时,观察不同 T、不同合并策略下的实测倍率,再与理论公式比对:如果偏差巨大,说明模型假设(如重叠率、trivial move 比例)不成立,需要修正后再调参。一个完整的调优闭环是:建模 → 预估 → 压测 → 对比 → 修正。

对完账,管理员终于把“搬书放大”从 30 倍降到了 8 倍。公式只是地图,实测才是路标——两者对齐,优化才算真正落地。

WAmeasured=WdiskWapp\displaystyle \text{WA}_{\text{measured}} = \frac{W_{\text{disk}}}{W_{\text{app}}}
实测与理论差 2 倍以上时,优先检查重叠率假设与 trivial move 占比,再回到参数面板微调。
  1. W_disk(实测磁盘写)通过引擎统计或 iostat 拿到的实际写盘字节数,是唯一可信的“搬书总量”。
    WdiskW_{\text{disk}}
  2. W_app(应用侧写量)应用层登记的写入总量,代表“本该搬的书”。
    WappW_{\text{app}}
  3. 对账比值两者相除得到实测写放大,与理论式对照即可验证模型假设是否成立。
    WdiskWapp\frac{W_{\text{disk}}}{W_{\text{app}}}

AI 应用场景

大模型训练日志与检查点落库

阶段:数据采集与存储(训练数据管道)

解决的问题:训练任务每秒产生海量指标与样本日志,传统 B+ 树引擎每次小写都伴随随机 IO 且写放大高;LSM 引擎配合 Tiered Compaction 与 WAL 组提交,把写放大压到 5 倍以内,SSD 寿命与写入吞吐同时改善,相当于给图书馆请了一位“囤积式管理员”。

具体案例:某 LLM 训练平台将千卡集群的训练日志接入基于 RocksDB 的存储,开启组提交后 fsync 频率下降 90%,单节点写入吞吐从 120MB/s 提升到 480MB/s,SSD 磨损明显缓解。

推荐系统特征存储的高频写入

阶段:在线推理特征存取

解决的问题:特征更新以小数据块高频到达,要求低延迟;若写放大高达 30 倍,热点 SSD 几个月就会报废。通过 LSM 参数调优(T=8、动态层级)与合并策略选型,把放大降到 10 倍以内,相当于重新规划了图书馆的楼层比例。

具体案例:某电商推荐特征存储日更新数十亿条特征,调优后 P99 写入延迟下降 60%,磁盘总写量减少 70%,为在线推理的实时性提供了稳定底座。

向量数据库的批量索引灌库

阶段:向量索引构建

解决的问题:向量索引需要批量灌入海量向量,LSM 的层级规划与合并策略直接决定灌库速度;写放大过高会让索引构建期的写入带宽被后台合并吃光。用好 Leveled 与 Tiered 的权衡,等于为向量“新书”选择正确的上架节奏。

具体案例:某向量数据库在千万级向量灌库时,将临时空间采用 Tiered 合并、建成后切换 Leveled 合并,灌库耗时缩短 60%,查询延迟保持稳定。

Python 演示

python35 行
import math  def run_sim(t, max_level=6, flush_size=64, flushes=5000):    level = [0] * (max_level + 1)    disk = 0    app = 0     def cascade(lv):        nonlocal disk        size = level[lv]        if size == 0 or lv == max_level:            return        overlap = level[lv + 1] * 0.5        disk += size + overlap        level[lv] = 0        level[lv + 1] += size        if lv + 1 < max_level and level[lv + 1] * t > level[lv + 2]:            cascade(lv + 1)     for _ in range(flushes):        level[0] += flush_size        app += flush_size        disk += flush_size        for lv in range(max_level):            if level[lv] * t > level[lv + 1]:                cascade(lv)     print("T=%d  app_writes=%d  disk_writes=%d  WA=%.2f"          % (t, app, disk, disk / app))  run_sim(t=4)print("---")run_sim(t=10)
目的:用 20 行核心逻辑模拟 Leveled LSM 的刷盘与合并过程,对比不同大小比例 T 下的写放大倍数。
  1. level = [0] * (max_level + 1)用一个数组记录每层当前数据量,对应图书馆每层书架的书数。
  2. disk += flush_size内存表刷盘本身也算一次真实磁盘写入,是放大的起点。
  3. if level[lv] * t > level[lv + 1]:当下层相对上层“太小”、比例失衡时触发合并,正是 LSM 的整理规则。
  4. disk += size + overlap合并时新数据与下层重叠旧数据都会重写,这一行就是写放大的直接来源。
  5. level[lv + 1] += size合并后数据归入下一层,层间完成迁移。
  6. cascade(lv + 1)一次合并可能引起下一层超阈值,像瀑布一样向下级联传递。
  7. disk / app最终用磁盘总写量除以应用写量,得到实测写放大倍数。

常见误区

误区写放大不就是多占了点磁盘空间吗?SSD 便宜,多写几次无所谓,反正数据最后都一样。

正解写放大消耗的是 IO 带宽与寿命:SSD 的擦写次数(P/E)有限,每多写一块都在透支寿命;后台合并还会抢占前台 IO,造成写入延迟尖刺。省钱的前提是别把寿命和延迟搭进去,图书馆里“多搬的书”同样消耗搬运工的体力与时间。

为何常见:只看到“空间”这个显性成本,忽略了“带宽”与“寿命”这两个更贵的隐性账单。

误区每层放大倍数调大,层数 L=log_T(N/M) 就少了,写放大肯定更小,所以 T 越大越好。

正解层数确实随 T 减小,但每层重写代价 (T−1)/2 随 T 线性上升。二者相乘后整体放大通常不降反升;T 过小又会让文件多而碎、固定开销吃掉收益。实际工程 T 多在 4~10,用公式算一遍再定,别凭直觉。

为何常见:只看到“层数变少”这一半,漏掉了“单层牵动变多”的另一半。

误区Tiered 写放大低,那大家都该用 Tiered,Leveled 该被淘汰。

正解Tiered 的代价是读放大与空间放大:同一层多个重叠文件,查询要读多份,删改后空间回收慢。读多写少的线上库用 Tiered 可能让查询延迟翻倍,相当于图书馆囤积式整理后读者找书反而更慢。二者是不同目标的权衡,没有绝对优劣。

为何常见:拿单一指标(写放大)去比较,忽略了读放大和空间放大这两个同样重要的维度。

误区WAL 每次提交都写盘,那干脆关掉或把缓冲区调小,写入不就快了吗?

正解WAL 是崩溃恢复的保险绳,关掉等于随时可能丢数据。真正该做的是组提交与批量合并,把多次 fsync 合成一次,既保留耐久性又把日志开销摊薄。台账不能撕,但可以把账合起来记。

为何常见:把“WAL 开销大”误当成“WAL 无用”,忽略了它承担的持久化语义。

面试题

Q1. 下列哪项最准确描述了 LSM 存储引擎的“写放大”现象?

单选题 · easy

  • A.应用写入数据被 CPU 压缩后体积变小
  • B.磁盘实际写入量是应用请求写入量的数倍← 正确答案
  • C.内存数据被频繁换出到磁盘导致的抖动
  • D.多个进程同时写同一块磁盘造成的争抢

答案:B。写放大定义是磁盘实际写入字节数 ÷ 应用请求写入字节数。合并重写旧数据会让磁盘写远大于请求写,正如管理员为摆一本新书搬动几十本旧书;压缩是空间优化,换出与争抢都与写放大定义无关。

Q2. Leveled Compaction 的写放大常用近似公式是哪一个?

单选题 · mid

  • A.WA ≈ L × (T−1) / 2← 正确答案
  • B.WA ≈ L × T / (T−1)
  • C.WA ≈ T − 1
  • D.WA ≈ log_T (N / M)

答案:A。Leveled 的写放大近似为层级数 L 乘以每层平均重写率 (T−1)/2;C 是 Tiered 的近似式,D 是层级数公式,B 不常用且量级不符。记住“层数 × 每层重写率”这个配对即可。

Q3. WAL(预写日志)在 LSM 存储引擎中的主要作用是什么?

单选题 · easy

  • A.提高数据的压缩率
  • B.防止数据被重复写入
  • C.崩溃恢复时重建内存表数据← 正确答案
  • D.减少内存表的容量占用

答案:C。WAL 先于数据落盘记录操作,断电后靠它重放重建 MemTable,相当于门口的持久化登记台账。它不压缩、不去重、也不省内存,只负责“断电后能找回账”。

Q4. 已知总数据量 N、顶层基准量 M、大小比例 T,LSM 的层级数 L 约为多少?

单选题 · mid

  • A.L = T / (N − M)
  • B.L = log_T (N / M)← 正确答案
  • C.L = N / (T × M)
  • D.L = sqrt(N × M / T)

答案:B。由 N = M×T^L 两边取对数即得 L = log_T(N/M),层数是对数级的。线性式或平方根式都无法描述“每层放大 T 倍”的指数关系,正如楼层数由总规模的指数决定而非线性决定。

Q5. 下列哪些做法能有效降低 LSM 的写放大?(多选)

多选题 · mid

  • A.采用 Tiered 合并策略← 正确答案
  • B.对 WAL 做组提交批量落盘← 正确答案
  • C.增大内存表以减少层级数← 正确答案
  • D.关闭所有后台合并任务

答案:ABC。Tiered 让写放大降到 T−1;组提交把多次 fsync 合成一次;增大内存表使层级变浅。而关闭合并会让文件无限堆积,空间放大与读放大爆表,属于自毁行为。

Q6. 相比 Leveled Compaction,Tiered Compaction 的主要代价是什么?

单选题 · mid

  • A.写放大显著升高
  • B.读放大与空间放大升高← 正确答案
  • C.内存占用直接翻倍
  • D.无法支持删除操作

答案:B。Tiered 以低写放大换来了高读放大与高空间放大:同层多个重叠文件需读多份,删改空间回收慢。它是“囤积式管理员”,省了搬运却让找书变难,并非内存或删除功能的问题。

Q7. 写放大过大会带来哪些实际危害?(多选)

多选题 · hard

  • A.SSD 寿命被加速消耗← 正确答案
  • B.写入吞吐与 IO 带宽被挤占← 正确答案
  • C.后台合并造成写入延迟尖刺← 正确答案
  • D.数据压缩率自动下降

答案:ABC。写放大直接透支 SSD 的 P/E 次数、抢占 IO 带宽,后台合并还会引发延迟尖刺。压缩率由压缩算法与数据特征决定,与写放大无直接关系,属于干扰项。

Q8. 某库 N/M=10^6、T=10,按 Leveled 近似式估算,写放大约为多少?

单选题 · hard

  • A.约 10 倍
  • B.约 27 倍← 正确答案
  • C.约 60 倍
  • D.约 100 倍

答案:B。L = log_10(10^6) = 6,WA ≈ L×(T−1)/2 = 6×9/2 = 27 倍。选 10 倍只算了层数,选 60 或 100 倍则漏掉了 (T−1)/2 的系数。这类题先求层数再乘每层重写率即可。

Q9. 工程上实测写放大的常用口径是什么?

单选题 · easy

  • A.磁盘写入字节数 ÷ 应用写入字节数← 正确答案
  • B.内存占用 ÷ 磁盘占用
  • C.读次数 ÷ 写次数
  • D.文件数量 ÷ 层级数

答案:A。实测时用引擎统计或 iostat 拿磁盘写量,除以应用侧登记的写量即得放大幅度。内存比、读写比、文件比都与“多写了多少”这个核心问题无关。

Q10. RocksDB 等引擎降低写放大的工程手段包括哪些?(多选)

多选题 · hard

  • A.开启动态层级让每层保持 T 倍关系← 正确答案
  • B.组提交合并 WAL 的 fsync 次数← 正确答案
  • C.调大内存表缓冲突发写入压力← 正确答案
  • D.关闭 WAL 彻底放弃持久化

答案:ABC。动态层级维持层间满度、组提交摊薄 fsync、大内存表降低层级数,三者都是正规优化。关闭 WAL 是牺牲数据安全换速度的“拆保险”,不是工程上推荐的降放大手段。