字节跳动首创DisCoGC架构,重塑EB级分布式存储GC范式

FAST(USENIX Conference on File and Storage Technologies )是全球计算机存储领域最权威的顶级学术会议,代表着国际存储技术的最高风向标。字节跳动基础设施团队与清华大学合作的最新论文《Discard-Based Garbage Collection for Distributed Log-Structured Storage Systems in ByteDance》成功被FAST'26会议收录。本文将简要解读该论文的核心技术与工程实践。

在字节跳动,每天有海量的数据洪流涌向底层存储系统:抖音的短视频内容与推荐引擎倒排索引、大模型的数据、飞书的实时协作文档、番茄小说的内容库,甚至火山引擎服务万千企业的存储服务,这些业务的底层,都站着同一个分布式存储底座——ByteStore

作为字节跳动完全自研的分布式Append-Only存储系统,ByteStore支撑着EB级数据的稳定运行,管理着数十万台存储服务器,是整个字节业务高速发展的基石。而我们存储团队每天要面对的,除了超大规模数据的可靠性、性能挑战,还有一个困扰存储行业数十年的「老大难」问题:日志结构存储中,垃圾回收(GC )带来的写放大与空间放大的权衡

ByteStore 与 ByteDrive(块存储 )团队、清华大学联合,基于在块存储上收集的 Trace 信息,提出 DisCoGC 算法,一种融合 Discard 和 Compaction 的 GC 范式,在不使用 Compaction 移动数据的情况下直接将数据 Discard 掉,从根本上打破了这一权衡。

一、困局:写放大与空间放大的权衡难题,带来巨额额外成本

日志结构(Log-Structured )架构凭借极致的写入性能、简洁的一致性保障、天然适配快照与版本控制的优势,早已成为分布式存储、数据库领域的主流架构,ByteStore的核心设计也正是基于Append-Only的日志结构理念。

但成也日志结构,困也日志结构。这种「只追加、不原地修改」的写入模式,必然会随着数据覆盖更新,产生大量的无效旧数据。想要回收这些无效数据释放存储空间,传统方案只有一条路:Compaction(合并 )式GC

这套机制的逻辑很简单:扫描旧的日志文件,把其中仍有效的数据读出来,重新写入新的日志文件,再把整个旧文件删掉,以此完成无效空间的回收。但这个看似顺理成章的过程,却藏着一个行业级的两难困局:

picture.image

  • 想快速回收空间、降低空间放大,就要更频繁地执行Compaction,代价是写放大急剧飙升 。为了回收1GB的无效数据,往往要重写数GB的有效数据,不仅会抢占前台业务的IO与CPU资源,造成业务延迟抖动,更会大幅加速SSD的磨损,缩短硬件寿命,导致更高的总成本 (TCO)。

picture.image

  • 想降低写放大、减少对业务的影响,就要放缓Compaction的频率,代价是大量无效数据长期占用SSD空间 ,空间放大居高不下。在字节的超大规模体量下,哪怕是10%的空间放大,都会转化成巨额的硬件成本浪费。

在DisCoGC落地前,这个困局给我们带来了最直接的成本压力:仅Compaction GC带来的写放大与空间放大,每月就会产生数百万美元的额外TCO开销。

更棘手的是,ByteStore作为字节统一的存储底座,需要适配的业务场景远比专用存储系统更复杂:

  • 有在线服务带来的碎片化随机写,IOPS高、写入粒度小,无效数据零散分布,GC难度极高;

  • 有搜索广告推荐(SAR )场景的倒排索引构建、词典更新与相关性分数重计算,写入顺序性极强,同时伴随高频的全量覆盖更新;

  • 还有离线计算场景的Spark/Flink分布式任务,写入流量波动极大,突发式的批量写入与覆盖写并存。

传统一刀切的Compaction优化,根本无法同时适配如此多元的场景。我们试过无数种调优方式,调整Compaction的触发阈值、优先级、并发度,却始终跳不出「按下葫芦浮起瓢」的循环:优化了空间放大,写放大就上去了;控制了写放大,存储空间又不够用了。

我们意识到,想要彻底打破这个权衡魔咒,不能再在Compaction的框架里修修补补,必须找到一条全新的路。

二、破局:从PB级生产Trace里,找到藏在数据里的答案

路在哪里?我们没有先急着做方案设计,而是沉下心来,回到问题的源头:字节真实的业务场景里,无效数据到底是怎么产生的?GC的压力到底来自哪里?

为了回答这个问题,我们启动了一次全维度、超大规模的生产IO Trace分析。我们采集了字节三大核心场景——在线服务、搜索广告推荐(SAR )、离线分布式计算 的全量IO Trace,覆盖了数PB的写入流量、超十亿级的IO请求,时间跨度长达数天,既包含了业务高峰期的流量波动,也覆盖了低峰期的稳态运行。我们给每一条IO请求打上了场景标签,从写入大小、顺序性、覆盖写频率、热点分布等十几个维度,做了精细化的拆解与统计。

在海量的Trace数据里,我们发现了几个颠覆传统认知的关键规律,也最终找到了破局的核心方向。

第一个发现:不同场景的写入特征天差地别,「一刀切」的GC方案从根源上就走不通

我们把三大场景的Trace数据做了对比,发现它们的IO行为几乎是两个极端:

  • 在线服务场景: 写入极度碎片化,即使合并了时间连续、地址连续的写入,仍有超过60%的写入是4KiB的最小粒度,超过256KiB的连续写入仅占12%。覆盖写的热点分散,无效数据大多是零散的碎片,很难形成连续的无效段。

  • SAR与离线计算场景: 写入的顺序性极好,合并连续写入后,超过55%-65%的写入都是大于256KiB的连续范围 ,4KiB的碎片化写入仅占15%以内。更关键的是,这类场景伴随极高频率的覆盖写,往往前一次写入的大范围数据,短短几秒内就会被新的全量数据覆盖,直接产生一整段长连续的无效数据。

而从整体的写入占比来看,这些能产生长连续无效数据的场景,贡献了字节存储系统里超过70%的写入流量,也是GC成本开销的主要来源。这意味着,只要能高效回收这些长连续的无效数据,就能解决绝大多数的GC成本问题。

picture.image

第二个发现:传统Compaction,做了大量「无用功」

我们对Compaction过程做了Trace级的拆解,发现在SAR和离线场景中,一次Compaction操作,超过80%的IO开销,都花在了搬运「未来很快就会失效」的有效数据上。

比如在倒排索引更新的场景中,一个日志文件里,可能只有不到20%的数据是长期有效的,剩下80%都是连续的无效数据。但传统Compaction为了回收这80%的无效空间,必须把那20%的有效数据读出来、重新写一遍,为了回收垃圾,反而产生了大量的额外写入,这正是写放大的核心来源。

更讽刺的是,很多刚被重写的有效数据,很快又会被新的覆盖写标记为无效,下一次Compaction又要被搬运一次,陷入「反复重写、反复失效」的恶性循环。

第三个核心洞察:无效数据的形态,决定了我们完全可以跳出「搬运数据」的老路

Trace数据清晰地告诉我们:在字节的主流业务场景中,超过90%的无效数据,都是大于128KiB的连续范围,其中70%以上超过1MiB

picture.image

这个发现让整个团队豁然开朗:既然无效数据是连续的,我们为什么非要去搬运那一小部分有效数据?为什么不能直接把这段连续的无效空间标记回收,完全不动有效数据?

这就是我们最终的核心思路:放弃以Compaction为核心的GC体系,转而构建一套以Discard(丢弃 )为核心,Discard与Compaction协同的全新GC机制——DisCoGC

用Discard机制直接回收长连续的无效数据,从根源上避免有效数据的重写,写放大自然就消失了;再用低频的Compaction做兜底,回收碎片化的无效数据,解决Discard带来的碎片化问题。二者能力互补,彻底打破写放大与空间放大的权衡魔咒。

三、落地:从想法到全量上线,我们跨过了这些工程化的坑

想法的方向有了,但要把Discard机制真正落地到ByteStore的多层分布式架构中,绝非易事。从上层的ByteDrive块存储,到中层的ByteStore分布式引擎,再到底层的UFS自研用户态文件系统,最终到SSD硬件,整个链路有太多的坑要填。

我们遇到的第一个拦路虎,就是跨层边界损耗问题 。Discard操作要想成功回收空间,必须匹配每一层的分配单元,但ByteStore的多层架构里,各层的分配单元完全不匹配:

  • 上层ByteDrive的Discard请求,是基于用户逻辑地址的任意偏移与长度;

  • 中层ByteStore的空间分配,以EC条带为单位,比如4+1的EC方案,条带对齐要求是64KiB的倍数;

  • 底层UFS文件系统,以4个4KiB扇区组成的Cluster为最小分配单元,回收必须以Cluster为单位;

  • 再加上ByteDrive层会对数据做块级压缩,压缩后的数据长度与原始逻辑地址完全错位,进一步加剧了对齐难题。

如果直接按原始范围发起Discard,边界上的无效数据根本无法回收,极端情况下,单条Discard请求的边界损耗能超过50%。日积月累,这些收不回来的边界垃圾,会造成严重的空间浪费,让Discard的效果大打折扣。

picture.image

为此,我们设计了两层核心优化来彻底解决边界问题:

  • 边界扩展机制: 在发起Discard请求时,我们会先检查当前范围是否与已丢弃的范围相邻,如果相邻,就对当前范围做适度的重叠扩展,一次性把历史残留的边界垃圾和本次的无效范围一起回收,既避免了新的边界损耗,又清理了历史的垃圾残留。

picture.image

  • Discard友好的EC条带设计: 我们重新设计了EC条带的单元大小,让它与底层UFS的Cluster分配单元原生对齐,从根源上消除了集群级别的边界损耗,让每一条Discard请求都能完整回收对应空间。

picture.image

第二个难题,是如何避免Discard操作冲击前台业务 。Discard操作需要修改各层的元数据,尤其是底层UFS的MetaPage更新,会产生SSD写入,消耗CPU与IO资源。如果遇到业务突发写入,产生大量的无效数据,集中的Discard请求很可能抢占前台业务的资源,造成延迟抖动。而字节的在线业务,对哪怕几百微秒的延迟波动都极其敏感。

我们的解决方案,是构建了一套**「批量-调度-流控」** 的三层资源管控体系:

  • 同文件批量合并: 把同一个日志文件里的多个零散Discard范围,合并成一个批量请求下发,把多次元数据更新合并成一次,大幅降低CPU与IO开销;

  • 并行度感知的任务调度: 严格限制Discard任务的并发数,同时优先选择可回收范围最大的段优先处理,让有限的资源能回收最多的空间,最大化回收效率;

  • IOPS流控兜底: 设置了严格的Discard最大IOPS阈值,即使遇到极端的写入突发,也不会让Discard操作冲击前台业务,从机制上杜绝性能抖动。

第三个挑战,是碎片化与元数据膨胀问题 。频繁的Discard操作,会让原本连续的日志文件变得稀疏碎片化,导致日志文件和Chunk的数量急剧增加,不仅会放大ByteStore元数据管理的开销,还会让读操作的寻址链路变长,影响读性能。

picture.image

我们的应对思路,是让Discard与Compaction形成完美的能力互补

  • 高频轻量化的Discard作为主力,承担绝大多数的空间回收工作,把写放大降到最低;

  • 低频的Compaction作为兜底,一方面合并碎片化的日志文件,缓解元数据管理压力,另一方面回收小碎片的无效数据,进一步压低空间放大。

我们还设计了双模式的Compaction调度策略:常规场景下,优先选择垃圾率最高的段做合并,最大化空间回收效率;当检测到日志文件数量超过阈值、元数据压力升高时,自动切换到碎片化治理模式,优先选择日志文件最多的段做合并,从根源上缓解元数据开销。

picture.image

最后,我们还要解决底层SSD硬件的Trim适配问题 。软件层的Discard标记,最终要靠SSD的Trim指令,通知硬件完成物理空间的回收。但我们在生产环境中发现,不同型号SSD的Trim能力天差地别:有的高性能SSD Trim IOPS能达到160K,而部分企业级SSD的Trim IOPS仅为6K,不到写IOPS的3%。

picture.image

如果Trim指令下发不合理,会直接导致两个严重问题:一是SSD物理空间无法及时释放,出现「软件层显示空间已回收,硬件层仍被占用」的情况,甚至引发空间耗尽的系统风险;二是无效数据长期留存,会导致SSD内部GC更加激进,反而升高物理写放大,劣化前台性能与SSD寿命。

为此,我们在UFS自研用户态文件系统中,设计了Trim Filter与Trim Merger双机制 :Filter过滤掉过小的Trim范围,从源头减少Trim指令的数量;Merger将LBA地址相邻的小范围Trim合并成大范围指令,用最少的指令完成最大范围的空间回收。同时,我们可以根据不同SSD的硬件特性,灵活调整过滤阈值,让DisCoGC在不同硬件环境下都能稳定发挥效果。

四、成果:超大规模生产验证,TCO降低20%,业务性能零影响

从Trace分析里的核心洞察,到技术方案的设计,再到工程化的落地打磨,DisCoGC最终在字节跳动的大规模生产集群完成了全量部署,覆盖了在线服务、搜索广告推荐、离线计算的混合业务负载,经过了字节最严苛的业务场景与并发压力的全面验证。

生产集群的监控数据,给了我们一份远超预期的答卷:

  1. 综合成本大幅下降: 在混合负载的生产集群中,我们将系统空间放大从1.37降至1.23,同时逻辑写放大降低了32%,最终实现了约20%的存储系统TCO降低 。在字节的超大规模体量下,这带来了极其可观的硬件成本节约,同时大幅延长了SSD的使用寿命,进一步降低了长期运维成本。

  2. 全场景适配,收益覆盖全面: 对于特征处理、倒排索引构建、分布式计算这类高顺序写、频繁覆盖写的场景,DisCoGC的优势最为突出,TCO降低幅度超过25% ;即使是碎片化随机写为主的在线业务场景,DisCoGC依然能带来2%-5%的TCO节约 。系统会根据负载特性自动适配,极端场景下可回退到Compaction为主的模式,具备极强的鲁棒性。

  3. 前台业务性能零损耗 :生产环境的全量监控显示,DisCoGC部署前后,业务的平均响应延迟、P99/P999尾延迟、单卷带宽等核心性能指标,均无任何劣化。真正实现了「降本不影响性能」,这也是DisCoGC能快速完成全量落地的核心前提。

  4. 系统资源效率显著优化 :DisCoGC让GC相关的CPU使用率,降至纯Compaction方案的82.9%,大幅降低了后台GC操作的CPU开销;同时通过Roaring Bitmap等极致的内存优化,Discard相关的元数据内存开销仅增加了2.9%,几乎可以忽略不计。

更重要的是,DisCoGC的落地,让我们彻底跳出了写放大与空间放大的权衡困局。过去我们需要花费大量精力,针对不同业务场景做Compaction参数的精细化调优,而现在,DisCoGC能自动适配不同的业务负载,在极低的写放大下,实现高效的空间回收,大幅降低了运维成本,也让ByteStore的架构适应性迈上了一个新的台阶。

picture.image

五、技术背后:ByteStore,在业务土壤里生长出来的存储底座

DisCoGC的技术创新与成功落地,并非一次单点的优化,而是字节跳动存储团队多年来在分布式存储领域技术沉淀的集中体现,更是ByteStore作为统一存储底座的架构优势的一次集中释放。

从诞生的第一天起,ByteStore就不是一个实验室里的「完美产品」,而是在字节跳动海量、多元、严苛的业务场景里,一步步打磨、迭代、成长起来的工业级分布式存储系统。我们的所有技术创新,都遵循着「从业务中来,到业务中去」的理念:核心驱动力来自业务真实的痛点需求,最终的成果也100%落地到生产环境,为业务带来可量化的实际价值。

经过多年的业务打磨与技术迭代,ByteStore已经形成了四大核心优势:

  1. 一套架构,全场景支撑: 基于统一的Append-Only核心架构,同时支撑了块存储、对象存储、NAS、分布式图数据库、NewSQL数据库、NoSQL数据库等全品类存储服务,避免了重复造轮子,保证了不同存储服务的底座一致性,大幅降低了研发、运维与迭代成本。

  2. 全链路极致性能优化: 从自研的用户态文件系统UFS,到高性能用户态网络协议、高效EC编码引擎、全链路数据零拷贝、智能IO调度机制,ByteStore做了存储全链路的深度优化,既适配了字节在线业务高并发、低延迟的严苛需求,也能充分释放高速SSD、高带宽网络的硬件性能。

  3. 全维度的成本优化能力: 除了本次DisCoGC带来的GC机制革新,ByteStore还在智能纠删码策略、高压缩比算法选型、冷热数据智能分层、硬件特性深度适配等多个维度持续深耕,不断挖掘存储成本优化的空间,为字节业务带来持续的降本收益。

  4. 超大规模验证的可靠性与扩展性: 基于字节多年的超大规模运维经验,ByteStore打造了完善的容错机制、强数据一致性保障、全自动化的故障自愈能力,可稳定支撑EB级数据的管理与运行;同时具备极强的水平扩展能力,能轻松应对业务的爆发式增长。

如今,ByteStore不仅支撑着字节内部业务的高速发展,也通过火山引擎,把我们多年沉淀的存储技术能力、大规模运维经验,完整开放给各行各业的企业客户,让更多企业能享受到经过超大规模场景验证的企业级存储服务。

这次DisCoGC的成果入选FAST 2026,是国际学术界对我们技术实力的认可,更是对我们「扎根生产场景,解决真实问题」技术理念的肯定。

六、加入我们

AI时代的浪潮下,大模型、生成式AI的爆发式发展,给存储系统带来了全新的挑战与机遇,也为存储技术人提供了前所未有的施展舞台。

我们是字节跳动存储团队,负责字节跳动统一存储底座ByteStore的研发与迭代,支撑着抖音、飞书、番茄等核心业务的存储需求,持续探索分布式存储、AI存储、高性能存储引擎等前沿技术方向。

如果你也热爱存储技术,希望在超大规模的生产场景里,打磨真正有工业价值的存储技术,欢迎加入我们,一起做更有挑战、更有价值的事情!

招聘岗位

https://jobs.bytedance.com/experienced/position/6816652050676336903/detail

我们也欢迎在校同学投递日常实习与暑期实习岗位,一起在真实的工业场景中,成长为顶尖的存储技术人才。

0
0
0
0
评论
未登录
暂无评论