Skip to content
团子云技术 Lite 1.048596
Go back

放弃「哈希」与「随机」:从 3FS 的数据放置策略看分布式系统的工程取舍

作为分布式存储工程师,我们在设计数据存放策略时,通常的直觉是采用基于哈希的算法(如一致性哈希)或伪随机算法(如 Ceph 的 CRUSH)。这些方案无状态、易扩展,在通用云计算场景中已经被证明是极为可靠的范式。

但最近在分析针对大模型训练场景的 3FS(DeepSeek 内部的高性能分布式文件系统)时,发现他们走了一条颇为少见的路径:在控制面引入整数规划(Integer Programming)求解器,离线计算数据放置拓扑

抛开”用运筹学解存储问题”的猎奇感,这种设计的本质其实是针对特定业务场景(AI 训练)的一次经典工程取舍(Trade-off)。本文尝试从架构设计的角度剖析其背后的逻辑,探讨在什么场景下,我们也可以借鉴这种思路。

场景痛点:当长尾延迟变得不可忍受

探讨任何架构设计都不能脱离业务场景。在通用的云环境中,单台存储节点由于负载不均产生少量长尾延迟是可以容忍的。但在千卡、万卡同步的 AI 训练集群中,著名的 Straggler(掉队者)效应会被放大——哪怕是一台存储节点的 I/O 拥塞,也会导致整个关联的 GPU 集群陷入等待。

3FS 的数据层使用的是基于 CRAQ(Chain Replication with Apportioned Queries)协议的变体,读请求可由链上任意节点提供。这就带来了一个直接问题:当某台节点宕机时,它原有的读流量和后续的数据恢复流量,该如何由集群内其他节点分摊?

如果采用经典的”随机分配 + 适量分片”,在概率上必然存在分配不均的情况。某些节点可能”倒霉”地和故障节点存在较多的链重叠,从而瞬间面临几倍于平均水平的 I/O 突增,直接成为系统瓶颈。

为什么不直接”加海量分片”?

在常规认知中,要解决随机分布的不均,大数定律是最好的武器:把分片(如 Placement Groups 或 vNode)的数量拉得极其巨大,流量自然就平滑了。

但在很多重度依赖强一致状态机管理的架构中,这会带来元数据膨胀的副作用。在 3FS 的设计中,每条链上的每个位置对应一个物理磁盘上的逻辑存储目标(Storage Target):

  1. 元数据服务(mgmtd)需要对每个 Target 进行独立的心跳管理。
  2. 每个 Target 拥有各自的状态机流转和强一致的版本号(chainVersion)。

如果切分出海量的 Target,mgmtd 的内存消耗、状态扫描的 CPU 占用以及心跳风暴都会让单机控制面不堪重负。

因此,摆在架构师面前的实际约束是:如何在切分数量(Target 数量)极少的前提下,依然实现故障时流量的相对均匀打散?

破局思路:BIBD 建模与数值求解

在这种特定约束下,3FS 选择放弃运行时的概率分布,转向了离线阶段的确定性组合数学——BIBD(均衡不完全区组设计,Balanced Incomplete Block Design)

在它的 DataPlacementModel 中,数据放置被抽象为一个二值关联矩阵,通过外部求解器(如 HiGHS)寻找合规解。其核心思路是加入一个硬约束:限制集群中任意两个物理节点共同出现的链的数量上限。

以一个极简的 6 节点、3 副本环境为例,求解器能计算出每块盘只需切分 5 个 Target,就能组成 10 条链。在这个拓扑下:如果一台机器宕机,它的读流量会被精确地分成 5 份,由剩下 5 台机器均摊。

这种设计的实际工程价值在于:它用离线计算求出的数学下限,替代了”海量分片”带来的运行时元数据开销。 牺牲了算法的简洁性,换取了元数据体量的极致压缩。

数据搬迁的副产品

除了处理故障时的流量均衡,这种将放置策略”建模化”的做法,在集群扩容时也提供了一种有趣的解决思路。

在传统哈希方案下增加节点,往往会引发较大范围的数据洗牌。而在 3FS 中,他们在原有的整数规划模型里引入了一个新的目标函数:

def total_rebalance_traffic(model):
    # 最大化保留现有 target 的位置,即最小化数据搬迁
    return self.total_existing_targets - num_existing_targets_not_moved(model)

model.obj = po.Objective(expr=total_rebalance_traffic, sense=po.minimize)

求解器在寻找满足新拓扑的 BIBD 均衡方案时,会在解空间中去寻找与旧拓扑重叠度最高的解。这其实是把分布式系统里让人头疼的”控制数据迁移量”问题,转化为了一个纯数学上的最优化求极值问题。

总结:控制面复杂化换取数据面确定性

客观来说,3FS 的这套机制并不适用于所有场景,它显著增加了控制面的研发复杂度和运维认知成本。对于节点频繁上下线、环境动态性强的通用公有云存储,这种每次变更都需要离线求解的方案显然过于笨重。

但它的架构思路非常值得我们玩味和借鉴:

  1. 重控制面,极轻数据面:在 AI 算力中心这种拓扑相对静态的场景中,将复杂的分布计算推迟到拓扑变更时的控制面。数据面的客户端在运行时无需执行任何哈希或分配逻辑,仅需 O(1) 的数组查表,将高频 I/O 的运行时开销降到了最低。
  2. 用算力换取空间与确定性:在扩缩容的几分钟里消耗 CPU 算力进行求解计算,换取的是长期运行中极小的元数据内存占用,以及应对故障时流量去向的绝对确定性。

在未来的特定场景架构选型中,当我们发觉常规的”哈希与随机”无法兼顾元数据开销与长尾延迟时,不妨跳出传统框架,把”寻找合适的拓扑”看作一个可以被离线求解的约束问题。这种跳出固有范式的思考方式,正是架构设计的乐趣所在。


Share this post on:

Previous Post
收费站与 Little's Law:分布式系统容量规划的数学底线
Next Post
3FS RDMA 内存搬运机制:Pull/Push 与大页共享内存的工程实践