面包屑图标 当前位置: 首页
AI资讯
热点详情

DeepSeek 3FS系统架构与设计解析

AI热点日报
AI热点日报时间:2026-07-01
热点解读

写在前面 现代深度学习对存储系统的要求,早已不是传统文件系统能轻松驾驭的。大模型训练中,数据访问模式、吞吐量需求、延迟敏感度都在倒逼存储架构的变革。DeepSeek 3FS这个并行文件系统的出现,正是为了回答一个问题:当数据规模达到PB级、训练集群成百上千节点时,文件系统该如何设计才能不成为瓶颈?

写在前面

现代深度学习对存储系统的要求,早已不是传统文件系统能轻松驾驭的。大模型训练中,数据访问模式、吞吐量需求、延迟敏感度都在倒逼存储架构的变革。DeepSeek 3FS这个并行文件系统的出现,正是为了回答一个问题:当数据规模达到PB级、训练集群成百上千节点时,文件系统该如何设计才能不成为瓶颈?

先看一组核心数字:一个由180个存储节点构成的3FS集群,每个节点配备2×200Gbps InfiniBand网卡和16块14TiB NVMe SSD,外加500多个客户端节点的读压测环境下,聚合读吞吐达到了惊人的约6.6TiB/s,单盘性能2.3GiB/s。更关键的是,这一切是在有训练作业背景流量的情况下实现的。

但数字背后,真正值得深挖的是设计理念的差异。

DeepSeek 3FS 系统设计

传统文件系统的设计往往是为顺序、线性访问模式服务的。这对关系数据库这类场景很友好。但预训练不一样:数据是以随机、短暂的方式被访问的。为什么?因为海量文本无法全部塞进GPU显存,但一次只处理一个token又会导致计算资源严重浪费。更合理的做法是一次训练一批数据。如果按顺序喂数据,模型可能“记住”数据的排列顺序,而不是从底层特征中学习——随机抽样正好能消除这种风险。

于是出现了一个有趣的错配:用传统文件系统去支撑大规模预训练,就像拿锤子去拧螺丝。另外,SSD在随机访问和顺序访问上的性能差距已经远小于HDD,理论上随机读不再是问题。但传统文件系统依然依赖内核的文件缓存、经过复杂的中间层——内核态的文件缓存不仅会带来不可预测的内存消耗和延迟抖动,还把简单的读请求变得复杂。DeepSeek的做法是:直接去掉中间人,客户端通过直接IO访问存储驱动器。这在数据库管理系统(如Postgres、OracleDB)里是常见技术,但用在分布式文件系统上,算是大胆的取舍。

3FS还专门为KV缓存做了优化。Transformer的核心是Q、K、V张量上的注意力计算。KV缓存是一种提升推理性能的常规手段——通过复用之前计算过的K和V张量,避免每层都重新算。过去KV缓存一般只存在GPU显存里,容量受限。3FS把KV缓存扩展到更大的容量,虽然牺牲了一点带宽,但换来整体性能的提升。

另外,3FS自带了一种高度优化的数据格式“FFRecord”,可以和PyTorch、JAX这些主流框架的数据加载器无缝集成。

1. 总体架构

3FS由四个组件构成:集群管理器、元数据服务、存储服务、客户端。所有组件通过RDMA网络(InfiniBand或RoCE)互联。元数据服务和存储服务会向集群管理器发送心跳。集群管理器负责处理成员变更,并把集群配置分发给其他服务和客户端。系统部署了多个集群管理器,其中一个被选举为主管理器;如果主管理器挂了,另一个会自动升为主管理器。集群配置信息一般存在可靠的分布式协调服务里,比如ZooKeeper或etcd。但在生产环境,他们直接用了存储文件元数据的同一KV存储,以减少外部依赖。

文件元数据操作(打开或创建文件/目录等)会发给元数据服务处理。元数据服务实现了文件系统语义,本身是无状态的——文件元数据存在支持事务的KV存储(比如FoundationDB)里。客户端可以连到任意一个元数据服务。每个存储服务管理若干本地SSD,提供分块存储接口。存储服务采用带分配查询的链式复制(CRAQ)算法保证数据强一致性。CRAQ是“全部写入、任意读取”的策略,能充分发挥SSD和RDMA网络的吞吐潜力。3FS文件会被拆成大小相等的数据块,并在多个SSD上复制。

应用可以使用两种客户端:FUSE客户端集成简单,适合大多数场景;原生客户端则为性能敏感应用提供更优的定制能力。

2. 文件系统接口

对象存储在数据分析和机器学习领域越来越流行,但文件系统语义以及基于目录的命名空间,给应用带来了更大的灵活性。具体体现在三个地方:

  • 原子化的目录操作:对象存储虽然可以用斜杠模拟目录层次,但无法原子化地移动文件/目录或递归删除整个目录。而3FS内部常见的模式是先建临时目录,写入文件后再移动到最终位置。当需要处理大量小文件时,递归删除目录的能力至关重要——否则只能遍历每个目录挨个删除。
  • 符号链接和硬链接:应用广泛使用符号链接和硬链接来对动态更新的数据集创建轻量级快照。新数据以单独文件的形式追加存储。
  • 熟悉的接口:文件系统接口是开发者熟悉的东西,无需学习新API。很多数据集本身就是CSV或Parquet文件,把基于文件的数据加载器适配到3FS的FUSE或原生客户端非常直接。

2.1 FUSE的局限性

FUSE(用户空间文件系统)通过内核模块把I/O重定向到用户空间进程,简化了客户端开发。应用看起来像在访问本地文件,但FUSE有几个性能瓶颈:

  • 内存拷贝开销:FUSE守护进程无法直接访问应用内存,数据在核心态和用户态之间传输时消耗大量内存带宽,增加延迟。
  • 线程模型受限:I/O请求被放入一个多线程共享队列,用自旋锁保护。锁争用导致FUSE的I/O处理能力无法随线程数线性扩展。基准测试显示,FUSE只能处理约40万次4KiB读/秒,增加并发反而因锁争用导致下降。
  • 并发写入受限:Linux 5.x内核中FUSE不支持对同一文件的并发写入。应用通常通过同时写多个文件来规避问题,以最大化吞吐。
  • 复杂读模式不擅:训练任务需要随机访问不同大小的样本,数据偏移往往不对齐4K。在FUSE挂载的3FS上做小规模随机读,性能很差,SSD和RDMA带宽都浪费了。

2.2 异步零拷贝API

把文件系统客户端实现为VFS内核模块能绕过FUSE的性能问题,但内核模块开发复杂:Bug调试难,一旦出问题可能导致生产环境崩溃且不留日志;升级时所有使用该文件系统的进程必须优雅终止,否则需要重启机器。权衡之下,他们选择了在FUSE守护进程内部实现原生客户端,提供服务异步零拷贝I/O接口:元数据操作(open/close/stat等)仍由FUSE守护进程处理,保持POSIX语义;数据I/O则通过原生客户端直接执行,绕过FUSE瓶颈。

应用打开文件后,可以用原生API注册,之后用原生客户端做I/O。这种设计既保证了元数据兼容,又大幅提升了数据读写性能。异步零拷贝API的设计灵感来自Linux io_uring,核心数据结构包括:

  • Iov(输入/输出缓冲区):一块大内存区域,由用户进程和原生客户端共享,用于零拷贝读写。InfiniBand内存注册由原生客户端管理。所有读出的数据写入Iov,所有待写的数据在调用API之前必须先存进Iov。
  • Ior(I/O请求环形缓冲区):一个小型共享环形缓冲区,用于用户进程与原生客户端之间的通信,类似io_uring:用户进程将读写请求入队,原生客户端取出处理。读写请求按批次执行,批量大小由io_depth参数控制。多个批次可以并行处理,无论是来自不同Ior还是同一个Ior。但多线程应用建议使用多个Ior,因为共享一个Ior需要同步会影响性能。
  • 原生客户端的并行I/O处理:原生客户端内部创建多个线程,从Ior中获取请求,批量处理后统一发给存储服务,以减少小型随机读引发的RPC开销。

3. 文件元数据存储

3.1 文件块的位置

3FS把文件数据分成等大小的数据块(chunk),并条带化分布在多个复制链上。用户可以按目录指定chain table、块大小和条带大小。每个数据块独立存储在多个存储服务上,chunk ID由文件的inode ID和chunk index拼接而成。创建新文件时,元数据服务采用轮询策略从指定chain table中选择连续的复制链,依据条带大小分配,然后生成随机种子打乱所选链的顺序,确保数据在复制链和SSD间负载均衡。

当应用打开文件时,客户端查询元数据服务获得文件的数据布局信息,之后就可以独立计算chunk ID和对应的复制链,无需频繁依赖元数据服务,减少关键路径的依赖。

3.2 文件元数据

3FS用FoundationDB作为分布式元数据存储。FoundationDB提供键值存储接口,支持可序列化快照隔离(SSI)事务。所有元数据存储为键值对,元数据服务采用无状态架构,方便维护者无缝升级或重启服务。客户端在请求失败或超时时可以自动切换到其他可用的元数据服务。

文件系统的元数据主要由inode和目录项组成。inode存储文件、目录和符号链接的属性,每个inode由全局唯一的64位标识符标识(单调递增)。inode的键由前缀"INOD"和inode ID拼接而成,inode ID以小端字节序编码以便分散到多个FoundationDB节点。inode的值根据类型不同:所有类型都包含所有权、权限、时间;文件额外包含长度、块大小、chain table选中的范围、随机种子;目录额外包含父目录的inode ID、子目录/文件的默认布局配置;符号链接额外包含目标路径字符串。

目录项的键由前缀"DENT"、父目录inode ID和条目名称组成,值存储目标inode ID和类型。同一目录的所有条目自然形成一个连续的键范围,可高效范围查询。元数据操作利用FoundationDB的事务机制:只读事务用于查询,读写事务用于更新。写事务中FoundationDB会跟踪读写键集形成冲突检测集,并发冲突时自动重试。这使得多个元数据服务可并行处理请求,同时保持一致性。

3.3 动态文件属性

文件会话管理

大多数本地文件系统中,删除正在打开的文件会被延迟到所有文件描述符关闭。因此系统需要跟踪所有文件描述符。但训练任务启动时会打开大量文件,存储所有fd会给元数据服务和FoundationDB带来巨大负担。由于训练任务不依赖该特性,3FS不追踪以只读模式打开的文件描述符。对于以写入模式打开的文件,3FS维护文件会话,防止并发写入时删除文件导致垃圾块无法回收。当仍有活跃写入会话的文件被删除,元数据服务会延迟删除直到所有相关fd关闭。同时,元数据服务会定期检查客户端存活状态,清理离线客户端的会话。

文件长度管理

文件长度存储在inode中。但对于正在写入的文件,inode存储的长度可能和实际不一致。客户端每5秒(默认)向元数据服务报告每个写入文件的最大写入位置。如果该位置超过inode记录的长度且没有并发truncate操作,则该位置被更新为新的文件长度。由于多个客户端可能同时写入同一文件,这种方法只能保证最终一致性。在close/fsync操作时,元数据服务会向存储服务查询最后一个数据块的ID和长度,获取精确长度。但由于数据分布在多个复制链上,这一过程可能产生较大开销。

并发文件长度更新优化

如果多个元数据服务同时更新同一文件的长度,可能引发事务冲突导致重复计算。为优化此过程,3FS使用inode ID结合Rendezvous哈希算法在多个元数据服务间分配文件长度更新任务,减少冲突。生产中采用较大的条带尺寸(stripe size=200),小文件的数据块链数通常远小于200。为优化长度更新时的链数查询,3FS在文件inode中存储一个链数提示值,初始为16,每当额外数据块写入新链,该值翻倍。这避免在更新小文件长度时查询所有200条链,减少不必要的开销。同样优化也用于小文件删除。

4. 块存储系统

块存储系统的设计目标是在存储介质故障时仍实现最高带宽。3FS的读写吞吐应随SSD数量和网络带宽线性扩展。应用无感知数据位置地访问存储服务。

4.1 数据分布

每个文件块通过链式复制与分配查询(CRAQ)在一组存储目标之间复制。写请求发到链的头部目标,沿链传播;读请求可发到链中任意目标,通常均匀分布以均衡负载。每个SSD上创建多个存储目标,这些目标加入不同链。例如6个节点A-F,每节点一个SSD,每SSD创建5个目标(A1、A2…F5),共30个目标。如果每个块有3个副本,链表的构建方式可灵活设计。每条链有版本号,链变化(如目标下线)版本递增。只有主集群管理器可修改链表。可构建多个链表满足不同数据分布需求(如批处理/离线任务和在线服务互不重叠)。每条链状态独立变化,可包含在多个链表中。

4.2 恢复期间的流量均衡

假设读流量均匀分布,当节点A故障时,其读请求被重定向到B和C。高负载下B和C的读带宽立即饱和。更换故障SSD并同步数据可能耗时数小时。为减少影响,可让更多SSD分担重定向的流量。通过构造平衡不完全区组设计(BIBD)并用整数规划求解,可在恢复期间实现最大读吞吐。

4.3 数据复制

CRAQ是“写全读任意”协议,适合读密集型负载。全闪存系统中充分利用所有副本的读带宽至关重要。存储服务收到写请求时:检查链版本是否匹配;发起RDMA读拉取写数据;从锁管理器中获取待更新块的锁(同一块的并发写被阻塞,所有写在链头部串行化);将块的已提交版本读入内存,应用更新,存为待定版本;如果服务是链尾部,则用待定版本原子替换已提交版本并向前驱发确认,否则转发给后继。当确认消息到达时,服务用待定版本替换已提交版本并传播。

读请求时:如果只有已提交版本则直接返回;如果有待定版本则返回特殊状态码,客户端可等待后重试或发起宽松读请求获取待定版本。

4.4 故障检测

集群管理器依赖心跳检测故障。T秒内未收到心跳则宣告服务故障;服务在T/2秒内无法与集群管理器通信则停止处理并退出。心跳可视为对租约的续租。元数据服务无状态,集群管理器提供的在线元数据服务列表是一种简单服务发现。如果一个元数据服务下线,客户端可切换到其他服务。集群管理器在存储服务成员变更中更关键:它维护链表的全局视图,每个存储目标有公共状态和本地状态。公共状态与链表一起分发,本地状态仅由存储服务和集群管理器知晓。如果存储目标发生介质故障,相关服务在心跳中设置本地状态为离线;如果存储服务下线,其管理的目标标记为离线。集群管理器定期扫描每条链,根据状态转换表更新公共状态。如果某个存储目标被标记为离线,它会被移到链末尾。如果存储服务发现任何本地目标的公共状态为lastsrv或offline,则立即退出。一旦同步的存储目标完成数据恢复,服务在心跳中将本地状态设为up-to-date。

4.5 数据恢复

当存储服务退出或介质故障时,集群管理器将相关目标标记为离线并移到链末尾。服务重启后,每个目标独立进入恢复过程,与正常活动重叠。离线服务启动时:定期拉取最新链表,但所有目标在链表中被标记为离线前不发送心跳,确保经历恢复;恢复期间收到写请求总是全块替换,本地已提交版本更新;前驱节点向恢复服务发送dump-chunkmeta请求,服务遍历本地元数据回复。当收到sync-done消息,服务将目标本地状态设为up-to-date。

当前驱节点发现后继节点上线时:开始转发正常写请求(全块替换);向后继节点发送dump-chunkmeta;比较元数据决定需要传输哪些块;通过全块替换写请求传输,完成后发送sync-done。传输规则:块仅存在于本地则需传输;仅存在于远程则需删除;本地链版本大于远程则需传输;链版本相同但本地已提交版本号不等于远程待定版本号则需传输;否则相同或正在更新。

4.6 块与元数据

文件块存储在块引擎中。每个SSD上,持久化由固定数量的数据文件(存块数据)和一个RocksDB实例(维护块元数据和其他系统信息)组成。块引擎还维护块元数据的内存缓存以提高查询性能。块引擎实现块分配器用于快速分配新块。接口提供线程安全操作:open/close从RocksDB加载元数据并重建分配器状态;get通过哈希表缓存检索元数据和引用计数句柄,O(1)并发访问;update通过分配新块实现写时复制,旧块在所有句柄释放前仍可读;commit通过写批次原子更新RocksDB并刷新缓存。

块数据存储在物理块上,大小从64KiB到64MiB,按2的幂递增共11种。分配器分配最接近的物理块。为每种物理块大小构建资源池,每池256个物理文件,通过位图维护使用状态。回收时将位图标志置0,空间保留优先用于后续分配。无可用物理块时使用fallocate分配连续大空间创建256个新物理块以减少碎片。写操作时分配器先分配新物理块,将旧块数据读入缓冲区,应用更新后写入新块。对于追加操作,实现了优化:直接在现有块末尾就地添加数据,从新块位置和现有元数据构建新元数据副本,随后原子更新RocksDB。

热点追踪提示词
你是一名 AI 行业编辑,请围绕下面这条热点输出一份资讯解读:
热点:DeepSeek 3FS系统架构与设计解析要求:
1. 先用一句话解释这条热点在讲什么
2. 再总结它为什么重要
3. 说明会影响哪些 AI 产品或内容方向
4. 最后给出 3 个适合资讯站使用的标题
来源:https://www.53ai.com/news/OpenSourceLLM/2025030204691.html
ai 人工智能

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关热点
AI热点2026-07-02 14:27
Huddlenow Insights 谷歌Meet商业企业视频会议服务全方位深度解析

GoogleMeet是面向商业与企业的视频会议服务,支持屏幕共享、实时字幕及与GoogleWorkspace集成,适用于项目讨论、网络研讨和线上教学等多种会议场景,具备扎实的安全与隐私保护。

AI热点2026-07-02 14:27
一款实用的YouTube视频高亮标注Chrome浏览器扩展插件

Lanter是Chrome扩展,利用AI将YouTube视频语音转为带时间戳的文字笔记,支持一键抓取高光、自动标点排版、书签管理、全局搜索及每日邮件汇总,方便高效回顾视频关键内容。

AI热点2026-07-02 14:27
WhisperNotes智能音频笔记应用

一款AI驱动的Chrome扩展音频笔记应用,支持录音自动转文字、标签分类与全文搜索,将语音转化为可检索的数字资产,显著提升信息定位与管理效率。

AI热点2026-07-02 14:27
Sharpen AI:Chrome扩展秒转Google Meet为笔记邮件任务

专为GoogleMeet设计的AIChrome扩展,实时转录会议内容,自动生成摘要并提取行动项与决策,无缝同步至Google文档、任务及Gmail,省去手动整理时间,显著提升协作效率。

延伸阅读