<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>JuiceFS Blog</title><link>https://www.juicefs.com/zh-cn/blog/</link><description>Latest news from JuiceFS</description><atom:link href="http://juicefs.com/zh-cn/blog/latest/feed/" rel="self"/><language>zh-cn</language><lastBuildDate>Wed, 27 May 2026 03:43:05 +0000</lastBuildDate><item><title>共绩科技：跨云弹性推理场景下，模型分发如何跟上算力调度</title><link>https://www.juicefs.com/zh-cn/blog/user-stories/gongji-tech-cross-cloud-elastic-inference-model-distribution</link><description>&lt;div class="block-markdown"&gt;&lt;p&gt;共绩科技 2023 年成立于清华，面向 AIGC 企业和科研机构提供算力平台与 MaaS 服务，致力于缓解弹性算力需求与供给之间的错配。平台通过聚合 IDC 闲置资源和边缘资源，以容器化服务为主，为 AI 推理、视频渲染、数据处理和数据合成等波动性场景提供可快速调度的算力资源。&lt;/p&gt;
&lt;p&gt;在跨云弹性推理场景中，计算任务可以调度到不同地域、云环境和集群，但模型文件和业务数据体积较大，难以像计算资源一样快速迁移。尤其是在线推理场景，模型仓库以读为主且访问频繁，存储访问能力会直接影响服务启动、弹性扩容和请求延迟。&lt;/p&gt;
&lt;p&gt;为此，共绩科技基于 JuiceFS 封装了“对象存储加速”方案，将用户已有对象存储接入弹性推理集群，并通过统一命名空间、元数据导入、FUSE 挂载、分布式缓存和数据预热，提升模型仓库在跨云、跨集群环境中的访问效率。以一家头部文生图模型社区实践为例，该方案支撑了几十 TB 级模型仓库、checkpoint 与 LoRA 动态加载，以及高峰期数百卡弹性资源扩容，并将弹性集群的额外延迟控制在客户验收范围内。&lt;/p&gt;
&lt;h2&gt;01 弹性需求广泛存在，供给却难以匹配&lt;/h2&gt;
&lt;p&gt;随着 AI 应用快速发展，算力需求持续增长，但不同场景的资源使用特征并不相同。&lt;strong&gt;相比训练任务相对稳定的资源需求，AI 推理、数据处理和数据合成等场景通常具有更强的波动性&lt;/strong&gt;：办公类应用可能在白天流量更高，娱乐类应用可能在傍晚或周末迎来高峰；项目制的数据处理任务则可能在短时间内集中消耗大量算力，任务结束后又进入空窗期。对于中小团队或探索型业务而言，弹性算力还能帮助其更清晰地评估单次请求成本与商业收益之间的关系。&lt;/p&gt;
&lt;p&gt;但在供给侧，算力基础设施建设属于重资产投入。资源方通常并非不具备弹性服务能力，而是更倾向于通过长期整租回收成本、降低风险。这使得市场上低价、稳定、弹性三者难以同时满足：整租资源价格较低且供应稳定，但缺乏弹性；Spot 资源价格低且具备弹性，但供应不确定；On-demand 资源弹性和稳定性较好，但成本较高。在中国市场，这种矛盾进一步表现为交易主要集中在整租订单，弹性资源供给占比较低。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;弹性算力供给的三角权衡&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;弹性算力供给的三角权衡&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;共绩科技希望解决的，正是弹性算力需求与供给之间的错配问题。&lt;strong&gt;通过聚合 IDC 闲置资源及更分散的边缘资源，平台以容器化服务为主，为 AI 推理、视频渲染、数据处理和数据合成等场景提供可快速调度的算力资源&lt;/strong&gt;，在较低资源成本基础上，帮助用户在业务高峰时快速拉起任务、调度至不同集群并承接弹性需求。资源方也可以在整租之外，提高闲置资源的利用率和变现效率。&lt;/p&gt;
&lt;h2&gt;02 算力可以调度，存储如何跟上？&lt;/h2&gt;
&lt;p&gt;随着弹性算力平台的发展，计算资源的调度相对容易实现。容器镜像可以通过镜像仓库和分发网络同步到不同集群，计算任务可以由调度系统在不同资源池中拉起，业务流量也可以通过统一接入层和流量治理能力进行分发。&lt;/p&gt;
&lt;p&gt;但模型和数据文件通常体积较大，跨云、跨集群迁移成本高、耗时长，难以匹配计算资源秒级拉起和释放的节奏。因此，&lt;strong&gt;在跨云弹性推理架构中，真正限制系统弹性的往往不是算力调度，而是数据和模型的分发效率&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;不同业务场景对存储的要求并不相同。&lt;strong&gt;第一类是模型训练、开发和调试场景&lt;/strong&gt;。这类场景通常涉及复杂的读写需求，包括代码仓库、模型文件、实验结果和中间状态等。同时，开发调试对环境稳定性要求很高，用户无法接受主机频繁切换导致状态丢失。因此，在这类场景中，平台通常会为用户提供长期稳定的计算资源和运行环境，相关存储需求也可以通过集群内已有的稳定存储体系来承载。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二类是数据处理场景&lt;/strong&gt;。这类业务又可以分为两种情况：如果单次数据处理的业务价值较高，能够覆盖跨云网络传输成本，就可以直接构建数据处理流水线，从 S3 或其他对象存储持续拉取数据，在计算集群内处理后再流式写回。此时系统不必依赖大规模本地存储。如果数据规模更大，或者单次处理的经济价值较低，本地存储更多也只是一次性缓存，数据在处理流程中流过即可，并不需要长期沉淀在计算集群内。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;真正更具挑战的是在线推理场景&lt;/strong&gt;。在线推理业务不能接受服务中断，但弹性算力平台所使用的资源可能来自闲置资源池，存在被撤出的可能。一旦某个机房或集群资源不可用，平台必须能够及时将任务迁移到其他供应商或其他集群。这意味着不仅计算任务要能够迁移，模型文件和相关存储访问能力也必须能够同步迁移。&lt;/p&gt;
&lt;p&gt;在线推理虽然对服务连续性和跨集群迁移能力要求更高，但它的存储访问模式也相对更明确。与训练、开发和调试场景相比，推理业务通常以读为主，核心需求集中在高效加载模型、读取模型权重和访问模型仓库上。对于大型模型和在线应用而言，模型加载速度直接影响服务启动时间、弹性扩容效率和请求响应稳定性。因此，推理场景并不适合简单沿用传统读写混合型存储架构，而更适合围绕模型分发、只读访问和缓存加速进行专门优化。&lt;/p&gt;
&lt;p&gt;此外，弹性算力平台通常并不承载用户完整的业务系统。用户的主云账号、业务数据库、模型管理系统，甚至部分固定算力资源，往往已经存在于其他云或自有环境中。平台要接入用户业务，就必须与其现有模型仓库和模型管理流程兼容，不能要求用户重新迁移整套系统。&lt;/p&gt;
&lt;p&gt;因此，&lt;strong&gt;要支撑跨云弹性推理，需要的不只是计算调度能力，而是一套面向模型推理场景的跨云高性能存储与模型分发方案&lt;/strong&gt;：既要支持大模型仓库的托管和高性能读取，又要适配用户已有的模型管理体系，并能够在资源跨云、跨集群迁移时提供稳定的数据访问能力。&lt;/p&gt;
&lt;h2&gt;03 Why JuiceFS：跨云统一访问、强一致元数据与高性能缓存&lt;/h2&gt;
&lt;p&gt;面对跨云弹性推理场景，存储系统需要同时满足几个条件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;能够在不同云和不同集群之间提供统一访问入口，支持共享读写和统一元数据管理；&lt;/li&gt;
&lt;li&gt;能够兼容用户已有的对象存储和模型仓库，避免用户迁移现有数据；&lt;/li&gt;
&lt;li&gt;同时还要具备较低的运维复杂度和较好的读性能。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在存储方案选型过程中，我们曾评估过 Ceph。Ceph 技术成熟，适合在单一数据中心或相对稳定的资源域内构建统一存储。但在跨云弹性推理场景下，Ceph 对网络稳定性和运维能力要求较高，整体接入成本相对更高，因此没有作为最终方案。&lt;/p&gt;
&lt;p&gt;Alluxio 也曾进入评估范围。但在多云环境下，多个集群需要并发访问同一份底层对象存储数据，且业务并非完全只读，也存在少量写入。该场景对数据强一致性要求较高，因此 Alluxio 最终未作为生产方案。&lt;/p&gt;
&lt;p&gt;最终选择 JuiceFS，主要是因为它以对象存储作为数据底座，并通过独立元数据服务提供统一命名空间和一致的文件系统视图，能够让多个集群以文件系统方式访问同一份模型数据。这种架构既适合跨云、跨集群的模型分发和共享读取，也能够较好兼容用户已有的对象存储和模型仓库，降低数据迁移和业务接入成本。&lt;/p&gt;
&lt;p&gt;进一步采用 JuiceFS 企业版，则主要看重其分布式缓存能力和元数据托管能力。在这个场景中，JuiceFS 的价值并不只是提供一个文件系统接口，而是把对象存储、统一命名空间、元数据管理和缓存加速组合成一套更适合跨云弹性推理的存储访问层。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 企业版架构图&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 企业版架构图&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;h2&gt;04 实践方案：基于JuiceFS 的对象存储加速&lt;/h2&gt;
&lt;p&gt;基于 JuiceFS，平台封装了“对象存储加速”产品，用于将用户已有的对象存储接入弹性推理集群，并以高性能文件系统的形式提供给业务使用。整体流程如下。&lt;/p&gt;
&lt;p&gt;首先是创建文件系统。用户提供对象存储的访问凭证，例如 S3 兼容存储的 AK/SK。凭证权限可以根据业务需求配置为只读或读写，平台基于该对象存储创建对应的 JuiceFS 文件系统。&lt;/p&gt;
&lt;p&gt;其次是导入元数据。平台通过 JuiceFS import 能力扫描对象存储中的文件元数据，并将其导入 JuiceFS 元数据服务。这样，用户原本存放在对象存储中的模型文件，就可以在 JuiceFS 中以文件系统目录的形式被访问。&lt;/p&gt;
&lt;p&gt;第三是建立缓存组。在可能承载任务的各个集群内，平台会建立 JuiceFS Cache Group，形成分布式缓存组。任务运行前，平台可以先对模型文件进行数据预热，将热点数据提前缓存到目标集群，减少推理服务启动时从远端对象存储拉取数据的耗时。&lt;/p&gt;
&lt;p&gt;第四是挂载到业务 Pod。用户业务运行时，平台通过 FUSE 客户端将 JuiceFS 文件系统挂载到业务 Pod 中。对于应用而言，模型文件表现为本地文件系统路径，因此通常不需要改造原有的模型读取逻辑。&lt;/p&gt;
&lt;p&gt;第五是启用节点缓存。除了集群级 Cache Group，FUSE 客户端所在节点也可以提供本地缓存，用于提升重复读取和模型加载性能，进一步降低对远端对象存储的直接访问。&lt;/p&gt;
&lt;p&gt;这个“对象存储加速”产品，本质上是将 JuiceFS 的元数据导入、分布式缓存、数据预热和 FUSE 挂载流程产品化，使用户已有的对象存储能够以更接近本地文件系统的方式服务于跨云推理任务。&lt;/p&gt;
&lt;p&gt;此外，JuiceFS 的 Cache Group 与文件系统访问入口相对独立。这个特性一方面会增加平台侧的管理复杂度，因为平台需要同时管理文件系统、缓存组、挂载入口和任务调度之间的关系；另一方面，也为后续按集群、按用户或按业务场景进行缓存隔离、独立调度和精细化管理提供了基础。&lt;/p&gt;
&lt;h2&gt;05 业务实战：头部文生图模型社区&lt;/h2&gt;
&lt;h3&gt;场景、挑战与验收标准&lt;/h3&gt;
&lt;p&gt;在这套对象存储加速方案中，一个比较典型的实践案例来自国内头部文生图模型社区，其托管了几十 TB 规模的模型数据，既包括体积较大的 checkpoint 基座模型，也包括数量更多、体积相对较小的 LoRA 模型。在实际推理过程中，业务通常需要先加载 checkpoint，再加载一个或多个 LoRA，完成组合推理。&lt;/p&gt;
&lt;p&gt;该公司自身已经拥有较大规模的算力资源，规模达到数千卡级别。但由于其面向创意设计等生产场景，&lt;strong&gt;业务负载具有明显波动性，整体平均利用率不到 50%。在工作日的上午和下午高峰时段，负载甚至可能达到常规承载水位的 140%，导致服务体验下降&lt;/strong&gt;。因此，客户需要一种高度弹性的算力供给方式。&lt;/p&gt;
&lt;p&gt;共绩为其提供的是一种高弹性的资源模式：仅在工作日高峰时段，即上午 10:00–12:00 和下午 14:00–18:00，提供数百卡规模的算力支持，其余时间资源规模降为 0。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;扩缩容效果&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;闲时调度在业务峰谷场景中的扩缩容效果&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;这意味着平台需要在分钟级时间窗口内完成数百卡资源的快速扩容，而在非高峰时段完全不占用资源。对客户而言，这种模式可以在峰值时段获得大量算力支持，同时避免为低谷资源付费；对平台而言，也可以更高效地利用闲置算力资源，具备较好的商业价值。&lt;/p&gt;
&lt;p&gt;但这一场景的技术挑战也非常突出。首先，这类几十 TB 级模型仓库无法简单复制到每一个弹性集群。其次，推理服务并不是在启动时一次性加载全部模型，而是会随着用户请求持续发生模型读取和切换，访问频率较高。这意味着对象存储加速方案不仅要支持大规模模型仓库访问，还要在持续动态加载场景下保持稳定的读取性能。&lt;/p&gt;
&lt;p&gt;与此同时，该公司对性能要求非常严格。在验收过程中，会将部分生产流量引入弹性集群进行测试，并要求弹性集群与其自有集群相比，推理耗时的中位数和平均值差异都必须控制在 2 秒以内。考虑到单次推理耗时本身在几十秒量级，这一要求意味着对象存储加速方案几乎不能引入额外延迟。在最初几轮测试中，弹性集群的推理耗时中位数和平均值均比客户自有集群高出约 10 秒，未能通过验收。&lt;/p&gt;
&lt;h3&gt;性能优化：降低弹性集群的额外延迟&lt;/h3&gt;
&lt;p&gt;优化首先从中位数入手。&lt;strong&gt;中位数偏高意味着有相当比例的请求都存在性能损耗，而不是少量偶发请求造成的长尾问题&lt;/strong&gt;。通过 JuiceFS 监控发现，集群缓存命中率没有达到预期。在当前架构下，一旦缓存未命中，请求就需要跨公网访问客户在阿里云上的对象存储进行回源，这会显著拉高模型加载耗时，并进一步影响推理请求延迟。&lt;/p&gt;
&lt;p&gt;针对这一问题，平台利用 JuiceFS Cache Group 的隔离能力，为该客户分配专属缓存节点，并预留充足缓存空间，对核心模型数据进行充分预热。完成预热后，核心模型访问路径基本实现 100% 缓存命中，有效避免了跨公网回源带来的性能损失。&lt;/p&gt;
&lt;p&gt;第二个影响中位数的因素是元数据访问延迟。由于平台采用跨集群统一架构，元数据服务需要通过公网访问，例如使用 JuiceFS 云服务或部署在其他云主机上，因此元数据访问延迟会影响整体模型读取性能。&lt;/p&gt;
&lt;p&gt;针对这一问题，平台采取了两项措施：一是开启 JuiceFS 的 open cache，将元数据尽可能缓存到本地内存中。由于该场景以只读访问为主，适合通过缓存降低元数据访问开销。二是优化集群网络限流策略。尽管平台无法直接控制边缘机房的网络设备，但可以通过节点级限流，避免单个节点占满带宽，从而提升整体网络稳定性。完成这些优化后，集群整体性能明显提升，中位数逐步达到客户要求。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;当中位数达标后，平均值仍然存在偏差。这说明系统中仍存在长尾请求，即少量请求耗时显著高于正常水平，并拉高了整体平均值&lt;/strong&gt;。进一步分析发现，这主要与节点本地缓存，也就是 FUSE 缓存配额有关。由于缓存容量较小，相比客户自有集群，弹性集群更容易发生缓存换出，导致部分请求需要重新加载模型数据，从而拉高平均推理耗时。针对这一问题，平台在生产环境中扩大了 FUSE 本地缓存配额，降低缓存换出频率，改善长尾表现，最终使平均值指标也满足验收要求。经过上述优化，系统顺利通过验收，并稳定运行。&lt;/p&gt;
&lt;h3&gt;多租户缓存治理&lt;/h3&gt;
&lt;p&gt;场景验证通过后，这套能力也进一步进入多租户运行阶段。随着不同租户按时间片复用同一批弹性节点，新的问题开始暴露出来，即节点缓存竞争问题。&lt;/p&gt;
&lt;p&gt;在弹性资源模型下，FUSE 客户端退出时不会主动清理节点缓存。这个设计在单租户场景下是合理的，因为历史缓存可以被后续任务复用，从而提高命中率。&lt;strong&gt;但在多租户场景下，前一个租户的数据可能长期占用节点缓存空间，使后续租户无法获得足够缓存资源，最终不得不回源访问对象存储，导致性能明显下降&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;为了解决这一问题，共绩在每个节点上部署了独立的守护进程，由该进程在业务 FUSE 客户端启动前执行全局缓存垃圾回收。具体策略参考 JuiceFS FUSE 客户端的实现，采用 2-random 策略，在回收效率和性能之间取得平衡。同时，各节点之间通过 Kubernetes 分布式锁进行协调，只有抢到锁的客户端才执行 GC，避免多个客户端同时回收缓存，从而造成额外的网络和 I/O 压力。&lt;/p&gt;
&lt;p&gt;通过这一机制，我们有效缓解了多租户场景下缓存资源被历史任务占用的问题，使不同租户在共享弹性资源时，仍然能够获得相对稳定的缓存性能。&lt;/p&gt;
&lt;h2&gt;06 结语&lt;/h2&gt;
&lt;p&gt;弹性算力要稳定承接生产流量，不能只依赖计算调度，还需要模型数据和热点数据在跨云、跨集群环境中保持稳定访问。&lt;/p&gt;
&lt;p&gt;基于 JuiceFS，共绩科技将对象存储、统一命名空间、元数据管理、分布式缓存和 FUSE 挂载能力组合起来，形成了一套面向弹性推理场景的对象存储加速方案。它并不是简单地把对象存储挂载成文件系统，而是围绕模型推理的访问模式，提供可预热、可缓存、可隔离、可治理的数据访问层。&lt;/p&gt;
&lt;p&gt;以上是共绩科技在弹性算力与跨云存储加速方向上的阶段性探索和实践。随着 AI 推理场景持续演进，模型分发、缓存治理和多集群数据访问仍会不断出现新的工程问题。我们也希望与更多开发者、AI 应用团队和基础设施从业者交流，共同探讨弹性算力场景下更稳定、更高效的数据访问方案。&lt;/p&gt;&lt;/div&gt;</description><pubDate>Wed, 27 May 2026 03:43:05 +0000</pubDate><guid>https://www.juicefs.com/zh-cn/blog/user-stories/gongji-tech-cross-cloud-elastic-inference-model-distribution</guid></item><item><title>降低数据存储成本：JuiceFS v1.4 分层存储设计解析</title><link>https://www.juicefs.com/zh-cn/blog/engineering/juicefs-v1-4-tiered-storage-design-reduce-cost</link><description>&lt;div class="block-markdown"&gt;&lt;p&gt;JuiceFS 社区版 1.4 增强了分层存储能力，支持以单文件或目录为粒度指定对象存储类型，使用户可以在文件系统语义下管理不同数据的存储层级。本文将围绕这一能力，介绍其应用背景、方案演进、使用模型、实现思路以及后续演进方向。&lt;/p&gt;
&lt;h2&gt;01 核心背景&lt;/h2&gt;
&lt;p&gt;在实际业务中，不同文件的访问频率和性能要求往往差异明显：一部分数据需要被频繁读取或写入，对访问延迟和吞吐较为敏感；另一部分数据写入后很少再被访问，更多关注长期保存成本。分层存储正是为了解决这一问题，即根据数据的访问特征，将其匹配到更合适的存储层，从而兼顾性能与成本。&lt;/p&gt;
&lt;p&gt;通常可以根据访问特征将数据分为几类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;热数据&lt;/strong&gt;：访问频繁，通常要求低延迟和较高吞吐；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;低频数据&lt;/strong&gt;：访问频率较低，但在需要时仍希望能够快速读取；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;归档数据&lt;/strong&gt;：主要用于长期保存，访问频率极低，可以接受一定的恢复等待时间，以换取更低的存储成本。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对象存储本身已经提供了类似的分层能力。以 Amazon S3 为例，S3 Standard 适合频繁访问的数据，S3 Standard-IA 适合低频访问但仍需要毫秒级读取的数据，而 Glacier / Deep Archive 更适合长期归档场景。不同存储类型在访问延迟、最低存储时长和费用模型上存在差异。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-table"&gt;

&lt;table&gt;
    
        &lt;caption&gt;S3 主要存储类对比表&lt;/caption&gt;
    
    
        &lt;thead&gt;
            &lt;tr&gt;
                
                    
                        
                        
                            &lt;th scope="col"  &gt;
                                
                                    
                                        存储类型
                                    
                                
                            &lt;/th&gt;
                        
                    
                
                    
                        
                        
                            &lt;th scope="col"  &gt;
                                
                                    
                                        使用案例
                                    
                                
                            &lt;/th&gt;
                        
                    
                
                    
                        
                        
                            &lt;th scope="col"  &gt;
                                
                                    
                                        首字节延迟
                                    
                                
                            &lt;/th&gt;
                        
                    
                
                    
                        
                        
                            &lt;th scope="col"  &gt;
                                
                                    
                                        最低存储持续时间费用
                                    
                                
                            &lt;/th&gt;
                        
                    
                
            &lt;/tr&gt;
        &lt;/thead&gt;
    
    &lt;tbody&gt;
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                S3 Standard
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                用于对经常访问的数据进行通用存储
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                毫秒
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                不适用
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                S3 Standard-IA
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                需要毫秒级访问的不经常访问的数据
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                毫秒
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                30 天
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                S3 Glacier Deep Archive
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                存档非常少访问且成本非常低的数据
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                小时
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                180 天
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;对于构建在对象存储之上的 JuiceFS 来说，关键是将这些能力转化为文件系统层面的分层管理能力：用户按文件、目录或数据集设置存储层级，JuiceFS 负责映射到底层对象存储，并处理写入、迁移和归档恢复等操作。&lt;/p&gt;
&lt;h2&gt;02 JuiceFS 分层方案的演进&lt;/h2&gt;
&lt;p&gt;JuiceFS 分层能力的演进，本质上是从“被动不感知对象存储类型”，逐步发展到“可在文件和目录粒度管理主动存储层级”。&lt;/p&gt;
&lt;p&gt;在 v1.1 以前，JuiceFS 尚未提供存储类型配置能力。用户虽然可以在对象存储侧手动调整对象的 Storage Class，但这些变化不会被 JuiceFS 在文件系统层面统一感知和管理。对于标准层、低频层等支持实时访问的对象，通常不会影响正常读写；但如果对象被转入归档类存储，则可能因无法直接读取而导致访问异常。&lt;/p&gt;
&lt;p&gt;从 v1.1 开始，JuiceFS 支持通过 &lt;code&gt;--storage-class&lt;/code&gt; 设置对象存储类型。例如，可以在 format 时指定文件系统的默认 Storage Class，也可以在 mount 时覆盖当前挂载点写入数据所使用的存储类型。这使 JuiceFS 开始具备使用对象存储分层能力的基础，但配置粒度仍主要停留在文件系统默认值或挂载点级别，无法针对具体目录、单个文件或不同业务数据集进行精细化管理。&lt;/p&gt;
&lt;p&gt;v1.4 进一步将分层能力推进到文件和目录粒度。用户可以根据数据冷热程度，为单个文件或目录设置对应的存储层级；当目录设置了特定层级后，后续在该目录下新建的文件和子目录也可以自动继承这一配置。相比此前的默认值或挂载点级设置，v1.4 更适合按项目、目录、数据集或文件冷热程度进行分层管理。&lt;/p&gt;
&lt;h2&gt;03 分层存储如何配置&lt;/h2&gt;
&lt;p&gt;JuiceFS v1.4 分层存储的关键在于：将对象存储的 Storage Class 转化为文件系统可管理的存储在使用层面，JuiceFS v1.4 分层存储可以理解为两个步骤：&lt;strong&gt;先建立 Tier ID 与对象存储 Storage Class 的映射关系，再将文件或目录设置到对应的 Tier ID&lt;/strong&gt;。通过这一方式，用户可以按文件、目录或数据集组织分层策略，而不需要在每次写入时直接指定底层对象的存储类型。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;映射示意图&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;Tier ID 与 Storage Class 映射示意图&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;例如，可以将 Tier ID 1–3 分别映射到不同的对象存储类型：&lt;/p&gt;
&lt;pre class="codehilite"&gt;&lt;code class="language-shell"&gt;juicefs config redis://localhost --tier-id 1 --tier-sc STANDARD_IA -y
juicefs config redis://localhost --tier-id 2 --tier-sc INTELLIGENT_TIERING -y
juicefs config redis://localhost --tier-id 3 --tier-sc GLACIER_IR -y
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;完成映射后，可以为单个文件或目录设置存储层级：&lt;/p&gt;
&lt;pre class="codehilite"&gt;&lt;code class="language-shell"&gt;juicefs tier set redis://localhost --id 1 /path/to/file
juicefs tier set redis://localhost --id 2 /path/to/dir
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;目录级设置具有继承语义。为目录设置 &lt;code&gt;tier-id&lt;/code&gt; 后，后续在该目录下新建的文件或子目录会自动继承父目录的存储层级；如果需要处理目录下已有的数据，则可以使用 &lt;code&gt;-r&lt;/code&gt; 参数递归设置：&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;继承与存量递归&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;目录继承与存量递归设置&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;pre class="codehilite"&gt;&lt;code class="language-shell"&gt;juicefs tier set redis://localhost --id 2 /path/to/dir -r
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;对于 Glacier 等归档类存储，读取前通常需要先发起恢复请求：&lt;/p&gt;
&lt;pre class="codehilite"&gt;&lt;code class="language-shell"&gt;juicefs tier restore redis://localhost /path/to/dir -r
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;04 技术实现原理&lt;/h2&gt;
&lt;p&gt;从实现角度看，JuiceFS v1.4 分层存储的关键，是将文件或目录的分层信息纳入元数据管理，并在写入、迁移和读取流程中根据 &lt;code&gt;tier-id&lt;/code&gt; 选择相应的对象存储行为。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;各行为流程&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;写入、迁移与归档读取流程&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;&lt;strong&gt;元数据设计&lt;/strong&gt;
JuiceFS 使用 &lt;code&gt;tier-id&lt;/code&gt; 记录文件或目录所属的存储层级。&lt;code&gt;tier-id&lt;/code&gt; 取值为 0 时，表示使用默认存储层；取值为 1–3 时，则对应用户配置的对象存储 Storage Class。&lt;/p&gt;
&lt;p&gt;这样，存储层级不再只是对象存储侧的外部状态，而是成为 JuiceFS 可以在文件系统语义下感知和管理的元数据信息。后续写入新数据、迁移存量数据或检查文件状态时，JuiceFS 都可以基于这一元数据判断目标存储类型。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;存量数据迁移&lt;/strong&gt;
对于已有数据，修改存储层级不仅需要更新元数据中的 &lt;code&gt;tier-id&lt;/code&gt;，还需要改变对象存储中已有对象的实际 Storage Class。递归设置目录时，JuiceFS 会处理目标目录下的文件和子目录，并通过对象存储的复制能力，将已有对象迁移到新的存储类型。&lt;/p&gt;
&lt;p&gt;如果只是修改某个 &lt;code&gt;tier-id&lt;/code&gt; 对应的 &lt;code&gt;tier-sc&lt;/code&gt; 映射，已有对象的实际存储类型不会自动变化。此时需要使用 &lt;code&gt;tier set --force&lt;/code&gt; 显式触发变更，使存量对象改为新的 Storage Class。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;写入流程&lt;/strong&gt;
新文件写入时，JuiceFS 会根据文件自身或父目录继承得到的 &lt;code&gt;tier-id&lt;/code&gt;，确定数据应写入的对象存储类型。对于已经设置存储层级的目录，新建数据可以直接进入对应的存储层，避免先写入默认层后再迁移。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;读取流程&lt;/strong&gt;
对于标准层、低频层等支持实时访问的存储类型，读取过程对业务基本透明，JuiceFS 可以按正常流程从对象存储中读取数据。&lt;/p&gt;
&lt;p&gt;对于 Glacier、Deep Archive 等归档类存储，对象通常不能直接实时读取。需要用 &lt;code&gt;juicefs tier restore&lt;/code&gt; 命令先解冻文件，该命令会向对象存储服务发起恢复请求，对象能否读取以及何时可读，取决于云厂商的恢复机制；恢复完成后，业务再重新发起读取。&lt;/p&gt;
&lt;p&gt;因此，归档层更适合长期保存、极低频访问的数据，不适合仍需随时在线读取的业务路径。实际使用时，需要同时评估存储成本、恢复时间和恢复成本。&lt;/p&gt;
&lt;h2&gt;05 后续演进方向&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;降低归档类存储的操作成本&lt;/strong&gt;：归档类存储虽然具有较低的长期存储成本，但在写入、恢复、提前删除和生命周期转换等方面通常存在更复杂的成本模型。如果直接将数据写入归档类型，在频繁变更或批量迁移场景下，可能带来额外的操作成本。&lt;/p&gt;
&lt;p&gt;后续，JuiceFS 可结合对象存储的生命周期管理机制，先将数据写入标准存储类型，并在对象上附加相应的 Object Tag。用户随后可以通过云厂商的生命周期规则，根据标签自动、批量地将数据转换到低频或归档存储层。这样既能保留 JuiceFS 在文件系统层面的分层管理能力，也可以利用对象存储原生的批量转换机制，降低批量归档和层级转换过程中的额外开销。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;扩展到多桶、多云的分层管理&lt;/strong&gt;：当前分层存储主要基于同一对象存储后端内的不同 Storage Class。后续，JuiceFS 也可以进一步将“层级”概念扩展到不同存储桶、不同对象存储服务，甚至不同云之间，使分层管理不再局限于单一存储后端。&lt;/p&gt;
&lt;p&gt;例如，可以将热数据放置在以本地高性能 SSD 为后端的 MinIO 中，将冷数据或归档数据放置在云厂商的低成本归档存储桶中，并通过策略将数据从热层逐步迁移到冷层。通过这种方式，JuiceFS 有机会在统一文件系统命名空间下，实现跨桶、跨云、跨介质的数据分层管理。&lt;/p&gt;&lt;/div&gt;</description><pubDate>Fri, 22 May 2026 06:20:12 +0000</pubDate><guid>https://www.juicefs.com/zh-cn/blog/engineering/juicefs-v1-4-tiered-storage-design-reduce-cost</guid></item><item><title>AI 战略下架构演进：小米基于 JuiceFS 的统一存储实践</title><link>https://www.juicefs.com/zh-cn/blog/user-stories/xiaomi-unified-ai-storage-practice-juicefs</link><description>&lt;div class="block-markdown"&gt;&lt;p&gt;小米存储团队自 2021 年起推进基于 JuiceFS 的文件存储平台建设，最初主要面向云原生及部分业务场景提供文件存储能力。2024 年，小米提出全面 AI 战略后，原有异构存储体系在选型接入、数据流转和研发运维等方面的问题进一步显现。基于多协议接入、弹性扩展、多云适配和高性能访问等能力，团队最终确立了以 JuiceFS 为核心建设统一文件存储基座的方向，用于统一支撑大数据、云原生和 AI 等业务场景。&lt;/p&gt;
&lt;p&gt;围绕这一目标，平台进一步建设了容量层、性能层和缓存层等核心能力，在降低多系统接入和数据流转复杂度的同时，兼顾大规模存储与高性能访问需求。&lt;strong&gt;过去两年，随着生成式 AI 和智能驾驶等业务快速发展，该平台已支撑大模型、智驾训练、推理加速和大数据上云等典型场景。目前，平台已具备支撑千亿级文件数量和 EB 级存储规模的能力，并可覆盖从原始数据、训练数据到模型文件分发的 AI 存储链路&lt;/strong&gt;。&lt;/p&gt;
&lt;h2&gt;01 AI 战略下存储架构挑战&lt;/h2&gt;
&lt;p&gt;2023 年之前，小米与大多数公司类似，在不同业务场景中分别建设了多套存储系统。其中，大数据领域主要基于 HDFS 构建数据平台；AI 相关业务由于当时大模型尚未大规模兴起，主要依赖云上的 PFS/NAS 等高性能文件存储服务。&lt;/p&gt;
&lt;p&gt;在此期间，我们也开始引入 JuiceFS，并配套建设内部自研 FDS（File Storage Service），通过 CSI Driver 等组件为云原生及部分业务场景提供文件存储能力。
随着业务需求持续演进，这些存储系统在各自场景中独立迭代、独立维护，逐渐形成了较为复杂的异构存储格局。&lt;/p&gt;
&lt;p&gt;2024 年，小米正式提出全面 AI 战略。原有存储架构在选型、接入、数据流转和研发运维等方面的短板开始集中显现，主要体现在以下几个方面：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;选型与接入成本高&lt;/strong&gt;：存储系统类型多、能力边界不一，业务团队需要分别理解和适配，使用门槛较高；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据流转效率低&lt;/strong&gt;：系统间缺乏统一访问方式，跨系统数据拷贝频繁，影响研发效率；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;研发运维力量分散&lt;/strong&gt;：多套系统独立维护和演进，资源难以聚焦到 AI 战略所需的核心基础设施建设中。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;针对这些问题，我们在 2024 年进行了深入的内部讨论和架构调整，开始重新梳理面向 AI、大数据和云原生场景的统一存储架构。&lt;/p&gt;
&lt;h2&gt;02 基于 JuiceFS 建设统一文件基座&lt;/h2&gt;
&lt;h3&gt;选型思考：多协议支持、弹性、多云、高性能&lt;/h3&gt;
&lt;p&gt;JuiceFS 是一款天然支持多协议、具备弹性扩展能力、提供高性能读写的分布式文件系统，能够完整适配原生 AI 场景与大数据场景的存储需求。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;1JuiceFS 架构图.drawio&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 社区版架构图&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;在云原生领域，我们自 2021 年起已开始引入 JuiceFS，并持续进行内部自研与迭代优化。同时，我们也与 JuiceFS 开源社区保持了紧密的合作关系，共同推动技术演进与场景落地。&lt;/p&gt;
&lt;p&gt;在 AI 场景中，模型训练与推理大量依赖 POSIX 语义，这与 JuiceFS 的能力天然契合。与此同时，在大数据领域，我们原本就在推进大数据上云过程中的 HDFS 替代工作，业内已有诸多成熟实践，基于 HDFS 协议进行适配改造同样具备可行性。&lt;/p&gt;
&lt;p&gt;综合多协议支持、弹性扩展、多云适配和高性能读写等因素，我们最终选择以 JuiceFS 作为统一文件存储基座的核心组件，解决此前多平台、多业务使用不同文件系统带来的数据流转复杂、接入成本高和运维分散等问题。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;小米存储架构演进&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;基于 JuiceFS 的统一文件存储基座架构演进&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;h3&gt;存储层能力建设&lt;/h3&gt;
&lt;p&gt;我们的核心目标，是基于 JuiceFS 构建统一的文件存储层，对外提供大容量、高性能的存储能力和标准化接入接口，统一支撑大数据、云原生和 AI 三类核心业务场景。&lt;/p&gt;
&lt;p&gt;在客户端层面，我们充分利用 JuiceFS 的多协议能力，提供 POSIX、Hadoop SDK、Python SDK、S3 网关等多种接入方式，目前这些方式已经在内部业务中得到实际应用。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;存储基座技术架构&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 统一文件存储基座技术架构&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;在数据面，整体架构主要分为容量层、性能层和缓存层：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;容量层：以公有云对象存储为基础，面向 EB 级存储规模建设，支持多云部署，可覆盖不同战略机房和多家云厂商环境。&lt;/li&gt;
&lt;li&gt;性能层：基于 Ceph 和全闪机器进行大规模调优，用于承载 AI 训练等对吞吐和时延要求较高的场景。&lt;/li&gt;
&lt;li&gt;缓存层：针对 AI 训练数据集“一次写入、多次读取、极少修改”的特点，基于 NVMe 和 RDMA 自研高性能分布式缓存系统，用于降低重复读取成本并提升训练数据访问效率。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在控制面，我们对社区版能力进行了定制化改造。元数据方面，自研了基于 Raft 协议的分布式元数据服务，以满足内部基建系统打通和多系统接入需求，并提升系统可靠性与扩展性；后台管理方面，建设了统一管理服务，负责数据生命周期管理、分层存储、垃圾回收，以及热数据从容量层向性能层或缓存层的预热等能力。&lt;/p&gt;
&lt;p&gt;通过上述建设，JuiceFS 在小米内部逐步成为统一文件存储基座，既能支撑大规模容量型存储，也能满足 AI 训练场景下的高性能访问需求。目前，相关架构已经在线上生产环境运行，并支撑了大模型训练所需的高吞吐访问能力。&lt;/p&gt;
&lt;h2&gt;03 业务实践&lt;/h2&gt;
&lt;p&gt;在统一文件存储基座建设过程中，JuiceFS 已逐步覆盖小米内部的大数据、云原生和 AI 等核心业务场景。&lt;strong&gt;从整体规模看，该方案能够支撑 EB 级存储规模和千亿级文件数量；从能力建设看，则通过容量层、性能层和缓存层的协同设计，兼顾大规模存储与高性能访问需求&lt;/strong&gt;。下面将结合大数据上云和 AI 存储链路两个典型场景，介绍 JuiceFS 在小米内部的具体实践。&lt;/p&gt;
&lt;h3&gt;场景 1： 大数据上云与湖仓存储统一&lt;/h3&gt;
&lt;p&gt;早期，小米大数据体系主要基于 Hadoop 生态建设，其中 HDFS 采用的是上一代存算耦合架构。在实际运行过程中，这一架构逐渐暴露出性能波动、运维复杂、综合成本偏高等问题。相比之下，云存储在弹性扩展、资源利用和成本控制方面具有更明显的优势。因此，自 2021 年起，小米开始系统推进大数据上云。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;大数据上云&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;大数据上云&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;h4&gt;上云路径：从冷数据到湖仓层&lt;/h4&gt;
&lt;p&gt;小米大数据上云整体经历了三个阶段。&lt;/p&gt;
&lt;p&gt;第一阶段是&lt;strong&gt;冷数据上云&lt;/strong&gt;。我们首先将 HDFS 中的冷数据迁移至云存储，这一过程持续了两年多。&lt;/p&gt;
&lt;p&gt;第二阶段是&lt;strong&gt;湖仓层上云&lt;/strong&gt;。在这一阶段，我们自研了统一的湖仓层文件系统，推动大数据存储架构从存算耦合向存算分离演进。&lt;/p&gt;
&lt;p&gt;第三阶段是&lt;strong&gt;基于 JuiceFS 建设统一存储基座&lt;/strong&gt;。在完成 JuiceFS 技术选型后，我们将湖仓层整体迁移至 JuiceFS。湖仓建设本身可以利用 Iceberg 社区原生支持的对象存储接入能力，例如 OSS、S3 等协议。但小米业务覆盖国内外多个区域，并同时使用多家云服务，如果逐一适配不同云厂商，接入和维护成本都会较高。&lt;/p&gt;
&lt;p&gt;因此，我们最终选择通过 JuiceFS 统一接入不同云存储。上层服务只需通过 SDK 切换后端存储地址，即可完成不同云环境下的访问适配，从而大幅降低多云接入复杂度。&lt;/p&gt;
&lt;p&gt;在数据迁移方面，小米自研的数据工厂平台支持将表的底层存储透明切换至新架构，并在后台逐步完成原有数据向云上的迁移，整个过程对业务方基本无感知。同时，JuiceFS 支持多云和本地化部署。如果未来出于成本或战略考虑需要切换至自建存储，也可以通过 JuiceFS 将数据平滑迁回，为业务保留更高的架构灵活性。&lt;/p&gt;
&lt;h4&gt;热表缓存加速，计算提效&lt;/h4&gt;
&lt;p&gt;数据上云后，我们进一步分析了湖仓层的数据访问模式。对于日常报表和分析任务，计算通常集中在天级或周级的热数据上，并不需要频繁扫描全量数据。因此，湖仓层的性能优化重点并不是简单提升全量读取能力，而是提升热数据的访问效率和任务执行稳定性。&lt;/p&gt;
&lt;p&gt;基于这一特点，我们与湖仓层协同建设了热表预热能力。系统会根据每日访问统计识别热点表及其热分区，并在任务执行前通过预热接口将相关数据提前加载至缓存层。对于每天早上 8 点前需要完成的周期性报表任务，热数据可以在计算开始前完成缓存预热，从而减少任务执行过程中的远端读取和重复访问。&lt;/p&gt;
&lt;p&gt;经线下和线上测试，热表缓存后，相关计算效率提升约 10%–20%，计算耗时和计算资源消耗均有所下降。目前，缓存规模已达到 PB 级，平均吞吐量约为 200 GB/s。缓存层的引入也降低了跨云专线压力和云存储 API 调用成本：通过提高热数据命中率，可以减少重复跨云读取，从而降低带宽消耗和访问费用。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;热表预热架构&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;热表预热架构&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;h4&gt;大数据应用收益&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;性能方面&lt;/strong&gt;：切换至 JuiceFS 后，顺序读写性能明显提升，部分场景下提升超过 1 倍。相关计算任务上线后，整体任务耗时降低约 10%–30%。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;成本方面&lt;/strong&gt;：从小米内部成本口径看，统一存储架构显著降低了存储成本。其中，国内场景存储成本降低约 70%，海外场景降低约 90%。海外原方案主要基于云主机和 EBS 构建 HDFS 三副本，副本率较高，导致整体存储成本偏高。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;稳定性与运维方面&lt;/strong&gt;：在原有混部架构下，大量计算任务运行时容易挤占节点资源，导致节点负载升高，并进一步影响存储性能。采用存算分离架构后，计算任务运行在独立计算节点上，任务耗时更加稳定，后续扩容和规模化管理也更加灵活。&lt;/p&gt;
&lt;h3&gt;场景 2： AI 一站式存储&lt;/h3&gt;
&lt;p&gt;AI 存储分为三个阶段：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原始数据阶段&lt;/strong&gt;：需存储大量原始数据，经处理（如 ETL 处理）后用于训练，产出训练数据集，再投入高性能训练环境供训练任务运行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;训练阶段&lt;/strong&gt;：训练任务需要高吞吐、低延迟的数据访问能力，以降低 IO 等待时间并提升 GPU 利用率；训练完成后产出模型文件，用于后续推理任务。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;推理阶段&lt;/strong&gt;：模型文件需快速分发至具体节点，以便推理任务启动时快速拉取。&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;AI存储流程&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;AI 存储流程&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;此前，数据在多个系统间流转，业务方与自身均感受不便。统一采用 JuiceFS 后，可基于不同类型满足多样化深度需求。&lt;/p&gt;
&lt;h4&gt;各阶段需求与方案对比&lt;/h4&gt;
&lt;p&gt;AI 一站式存储需要覆盖原始数据、训练数据和模型文件三个阶段，不同阶段对容量、性能、成本和分发效率的要求各不相同。下表对各阶段的业务需求、此前方案和当前方案进行了对比。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-table"&gt;

&lt;table&gt;
    
        &lt;caption&gt;方案比对&lt;/caption&gt;
    
    
        &lt;thead&gt;
            &lt;tr&gt;
                
                    
                        
                        
                            &lt;th scope="col"  &gt;
                                
                                    
                                        使用场景
                                    
                                
                            &lt;/th&gt;
                        
                    
                
                    
                        
                        
                            &lt;th scope="col"  &gt;
                                
                                    
                                        业务需求
                                    
                                
                            &lt;/th&gt;
                        
                    
                
                    
                        
                        
                            &lt;th scope="col"  &gt;
                                
                                    
                                        前期方案
                                    
                                
                            &lt;/th&gt;
                        
                    
                
                    
                        
                        
                            &lt;th scope="col"  &gt;
                                
                                    
                                        当前方案
                                    
                                
                            &lt;/th&gt;
                        
                    
                
            &lt;/tr&gt;
        &lt;/thead&gt;
    
    &lt;tbody&gt;
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope="row"  &gt;
                                        
                                            
                                                原始数据
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                • 大容量、低成本存储&lt;br&gt;• 支持高并发数据处理&lt;br&gt;• 适配百 PB 级及以上数据规模
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                • 直接使用对象存储&lt;br&gt;• HDFS&lt;br&gt;• 其他低成本存储系统
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                JuiceFS 容量型存储&lt;br&gt;• 底层依托多云对象存储，屏蔽云厂商差异&lt;br&gt;• 支撑 EB 级容量和千亿级文件规模&lt;br&gt;• 支持百万级并发任务处理
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope="row"  &gt;
                                        
                                            
                                                训练数据
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                • 高吞吐、低延迟访问&lt;br&gt;• 降低 IO 同步等待时间&lt;br&gt;• 提升 GPU 利用率
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                • PFS、NAS 等高性能文件存储&lt;br&gt;• 性能较好，但系统成本较高
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                JuiceFS 性能型 / 缓存型存储&lt;br&gt;• 支持 TB/s 级吞吐和低延迟访问&lt;br&gt;• 结合异步 checkpoint 机制，降低 IO 同步耗时&lt;br&gt;• 通过缓存加速提升训练数据访问效率
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope="row"  &gt;
                                        
                                            
                                                模型文件
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                • 模型文件快速分发&lt;br&gt;• 支持高效拉取和加载&lt;br&gt;• 保障推理服务快速启动
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                • P2P 分发&lt;br&gt;• 工作流分发&lt;br&gt;• PFS 等高性能文件存储
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                JuiceFS 缓存加速分发&lt;br&gt;• 利用缓存机制提升模型加载效率&lt;br&gt;• 单机顺序加载性能最高可达 16 GB/s&lt;br&gt;• 相比本地盘、FDS 等方案，加载耗时可降低数倍
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;h4&gt;高性能缓存加速，提效降本&lt;/h4&gt;
&lt;p&gt;在 AI 训练场景中，训练数据集通常具有“一次写入、多次读取、极少修改”的特点，属于典型的读多写少访问模式，适合通过缓存提升数据访问效率。&lt;/p&gt;
&lt;p&gt;以内部智驾训练场景为例，数据集在成熟后，一个版本周期内数据量可能继续增长，但已有数据通常很少修改。此前采用的高性能文件存储虽然能够满足训练性能要求，但对于这类以重复读取为主的数据访问模式而言，存在一定的性能冗余和成本浪费。因此，我们开始推进基于 JuiceFS 的高性能缓存加速方案。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;训练流程&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;智驾场景训练流程&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;缓存方案具备多方面优势：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IO 路径短&lt;/strong&gt;：客户端直接操作文件，IO 路径大幅缩短，响应迅速。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能优化&lt;/strong&gt;：通过 RDMA 和零拷贝优化，性能显著提升。与之前的高性能存储相比，吞吐量提升 20%以上，且仍在持续优化。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;成本降低&lt;/strong&gt;：原基于 PFS 的存储采用副本机制，虽部分场景使用 EC 编码，但副本因稳定性更高而应用更普遍。采用缓存方案后，可实现单副本存储，成本降低 60%以上。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;资源整合利用&lt;/strong&gt;：在支持 CPU 训练时，GPU 机器通常挂载有 NVMe 盘，单机约有 10TB 左右空间。此前这些资源在业务场景中分散使用，利用率不高。现在，我们将分散的 NVMe 资源统一纳入缓存池，为就近的 GPU 训练和数据处理任务提供加速能力。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;04 未来规划&lt;/h2&gt;
&lt;p&gt;面向未来，我们将重点围绕以下三个方向持续演进。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;首先，持续提升统一文件存储基座的稳定性、性能和扩展性&lt;/strong&gt;。随着 AI 业务快速发展，训练、推理和数据处理任务对存储系统的吞吐、时延和可靠性提出了更高要求。后续我们将继续优化底层架构和关键链路，提升系统在大规模并发访问场景下的服务能力。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;其次，加强海量数据的生命周期管理&lt;/strong&gt;。当前业务数据规模持续增长，但不同类型数据在存储层级、访问频率和保留周期上的管理仍有进一步优化空间。我们将结合数据冷热特征、业务访问模式和成本模型，优化分层存储、数据归档、预热和清理策略，降低单位存储成本，提升整体资源利用率。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最后，持续完善数据管理与分析能力&lt;/strong&gt;。在统一文件存储基座之上，我们将进一步建设面向业务的数据管理能力，帮助用户更清晰地理解数据分布、访问行为和资源使用情况，为后续的数据治理、成本优化和业务决策提供支撑。&lt;/p&gt;
&lt;p&gt;以上是小米在统一文件存储基座建设中的阶段性实践。我们也期待与业界同行持续交流，共同探索更多技术实践。&lt;/p&gt;&lt;/div&gt;</description><pubDate>Tue, 12 May 2026 08:08:00 +0000</pubDate><guid>https://www.juicefs.com/zh-cn/blog/user-stories/xiaomi-unified-ai-storage-practice-juicefs</guid></item><item><title>分布式架构下配额设计：JuiceFS 的实现与典型案例</title><link>https://www.juicefs.com/zh-cn/blog/engineering/juicefs-distributed-quota-design-and-case-studies</link><description>&lt;div class="block-markdown"&gt;&lt;p&gt;在分布式存储环境中，存储资源通常由多个用户、项目和业务共享使用。如果缺乏有效的约束机制，单一主体的异常写入或误操作，可能迅速消耗大量空间或 inode，进而影响系统稳定性与成本控制。配额管理正是为共享环境建立可预测资源边界的重要手段。&lt;/p&gt;
&lt;p&gt;但在分布式系统中，配额管理并不只是“设置上限”这么简单。系统需要在多客户端并发写入、元数据异步更新和整体吞吐之间取得平衡；同时，配额规则也需要落实到不同层级的管控对象上。为此，JuiceFS 提供了覆盖全局、目录以及用户维度的多层级配额能力，以支持从整体容量控制到个体与团队约束的不同场景。&lt;/p&gt;
&lt;p&gt;本文将介绍这套配额机制的设计与实现，包括核心数据结构、同步模型，以及写入与删除流程中的校验与统计更新逻辑；同时，也会结合典型案例，说明配额统计、空间释放和超限写入等场景中的常见现象。&lt;/p&gt;
&lt;h2&gt;01 JuiceFS 支持的配额类型与资源维度&lt;/h2&gt;
&lt;p&gt;JuiceFS 配额支持两类资源维度：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Space：表示已使用的存储空间。这里的统计采用文件系统侧的占用口径，并按块粒度进行对齐计算；后文“写入链路”部分将进一步解释 4 KiB 对齐下的增量估算方式。  &lt;/li&gt;
&lt;li&gt;Inodes：表示已使用的 inode 数量。在大量小文件场景下，inode 往往比 space 更早成为约束瓶颈，因此也必须纳入配额治理范围。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;围绕这两类资源，JuiceFS 当前支持四种配额类型。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;配额类型&lt;/th&gt;
&lt;th style="text-align: left;"&gt;作用范围&lt;/th&gt;
&lt;th style="text-align: left;"&gt;主要解决问题&lt;/th&gt;
&lt;th style="text-align: left;"&gt;典型使用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;文件系统总配额&lt;/td&gt;
&lt;td style="text-align: left;"&gt;整个文件系统&lt;/td&gt;
&lt;td style="text-align: left;"&gt;防止整体资源失控&lt;/td&gt;
&lt;td style="text-align: left;"&gt;成本预算控制、容量上限&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;子目录配额&lt;/td&gt;
&lt;td style="text-align: left;"&gt;目录子树&lt;/td&gt;
&lt;td style="text-align: left;"&gt;阻断异常写入行为&lt;/td&gt;
&lt;td style="text-align: left;"&gt;防止误操作、小文件风暴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;用户配额&lt;/td&gt;
&lt;td style="text-align: left;"&gt;单个用户&lt;/td&gt;
&lt;td style="text-align: left;"&gt;不同业务互不影响&lt;/td&gt;
&lt;td style="text-align: left;"&gt;多租户数据管理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;用户组配额&lt;/td&gt;
&lt;td style="text-align: left;"&gt;项目或部门&lt;/td&gt;
&lt;td style="text-align: left;"&gt;成本分摊与团队限制&lt;/td&gt;
&lt;td style="text-align: left;"&gt;AI 项目共享环境&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;其中，用户配额和用户组配额预计将在社区版 1.4 中发布。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在实际使用中，一个常见、有效的组合策略是：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文件系统总配额做兜底；  &lt;/li&gt;
&lt;li&gt;目录配额专治“个体滥用”和“小文件风暴；  &lt;/li&gt;
&lt;li&gt;用户/组配额用于多租户管理。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种分层限制既能控制整体资源上限，也能避免单个主体的异常增长影响其他业务。&lt;/p&gt;
&lt;h2&gt;02 配额实现机制&lt;/h2&gt;
&lt;h3&gt;同步模型与数据结构&lt;/h3&gt;
&lt;p&gt;配额实现的难点在于“如何在多客户端并发写入下，以可接受的代价完成检查、统计和收敛”。JuiceFS 的客户端分布在多个节点上，会持续发起创建、写入、截断、删除等资源变更操作；如果每次变更都要求后端执行强一致检查与更新，写入路径将承担难以接受的额外开销。&lt;/p&gt;
&lt;p&gt;因此，配额机制需要同时满足两个目标：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;性能：避免每次写入都触发一次后端强一致更新。  &lt;/li&gt;
&lt;li&gt;一致性：多客户端并发写入时，确保系统用量最终收敛，并尽可能在写入前阻止超限操作。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;基于这一权衡，JuiceFS 采用了“本地累计、周期 flush、定期 refresh”的同步模型&lt;/strong&gt;：客户端先在本地内存中累计资源增量，由后台任务定期批量持久化到元数据后端；同时，客户端再周期性从后端拉取最新配额配置和基准用量，逐步对齐各自的全局视图。客户端之间不直接通信，而是以元数据后端作为统一的状态汇聚点。换句话说，JuiceFS 的配额并不追求每次操作上的强一致，而是在周期同步下实现最终一致的资源管控。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;存储架构&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;在当前实现中，配额增量每 &lt;strong&gt;3 秒&lt;/strong&gt;持久化一次（&lt;code&gt;flushQuotas&lt;/code&gt;）；客户端约每 12 秒从后端重新加载一次最新的配额配置和基准用量（随挂载心跳触发的 &lt;code&gt;refresh&lt;/code&gt; 调用）。这意味着，在极端情况下，不同客户端之间看到的全局视图可能存在约 12 秒的偏差，但会在后续同步过程中逐步收敛一致。&lt;/p&gt;
&lt;p&gt;配额信息由 &lt;code&gt;Quota&lt;/code&gt; 结构体统一管理，它表征单个配额实体，可适配目录、用户、用户组等不同类型的管控对象。其核心设计是将基准用量与增量用量解耦：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;UsedSpace / UsedInodes：表示“后端已持久化的基准用量”。  &lt;/li&gt;
&lt;li&gt;newSpace / newInodes：表示“本客户端本地累计的增量”，尚未 flush 到后端。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="codehilite"&gt;&lt;code class="language-go"&gt;type Quota struct {
    MaxSpace, MaxInodes   int64  // 最大空间和 inode 限制
    UsedSpace, UsedInodes int64  // 已使用的空间和 inode
    newSpace, newInodes   int64  // 待同步的新增使用量
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;在 inode 统计上，还需要特别考虑硬链接。不同配额类型对硬链接的计数语义并不相同。对于目录配额，统计按目录项进行：在某目录下创建一个硬链接，该目录的空间与 inode 用量各增加 1，删除时相应递减。对于用户配额和用户组配额，统计则按文件对象（inode）去重：同一文件即使存在多个硬链接，在 UID/GID 维度下也只计一次，因此创建或删除硬链接不会改变对应用户或用户组的用量。&lt;/p&gt;
&lt;h3&gt;配额存储&lt;/h3&gt;
&lt;p&gt;在配额存储机制方面，文件系统总配额作为全局“红线”，其容量与 Inode 上限直接持久化于元数据引擎中，由客户端在挂载时加载并执行硬限制拦截，确保底层资源不被穿透。&lt;/p&gt;
&lt;p&gt;相比之下，目录、用户和用户组配额的检查与增量累计更多依赖客户端侧完成。客户端在内存中维护以 inode、UID、GID 为键的索引结构，并周期性从后端同步对应的 &lt;code&gt;Quota&lt;/code&gt; 信息，从而在高频 I/O 场景下保持较低的查询开销。需要强调的是，客户端内存中的状态只是运行时缓存和增量视图，配额配置与基准用量的权威来源仍然是元数据后端。&lt;/p&gt;
&lt;h3&gt;配额检查&lt;/h3&gt;
&lt;p&gt;仅有同步模型和存储结构还不够，配额逻辑还必须嵌入具体的资源变更路径中。一次写入并不只是简单的数据追加，它可能同时伴随 inode 创建、块分配、目录项变化以及父级统计更新；在多客户端并发条件下，这些变化会共同作用于同一组配额约束。因此，只有把检查和统计更新真正放入写入、创建、截断、删除等操作路径，才能避免执行层面的超限写入和统计失真。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;22&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;写入文件： Quota 检查与更新流程图&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;h4&gt;写入前：增量估算与多维配额检查&lt;/h4&gt;
&lt;p&gt;当用户发起写入、创建或截断等可能改变资源用量的操作时，客户端首先估算该操作带来的资源增量，包括空间占用与 inode 变化。&lt;/p&gt;
&lt;p&gt;空间增量基于底层数据块的实际分配粒度（如 4 KiB 对齐）进行估算，因此需要进行块级对齐计算。inode 的增量主要发生在创建类操作中，例如新建文件或目录。&lt;/p&gt;
&lt;p&gt;在获得本次操作的资源增量后，客户端会在实际写入前执行配额校验。校验范围覆盖多个维度，包括用户与用户组配额、文件系统总配额以及所在目录树的目录配额。若任一维度在本次操作后可能超出限制，则请求会被拒绝，并返回配额超限或空间不足等错误。&lt;/p&gt;
&lt;p&gt;通过在写入路径前置校验，可以在资源变更发生前阻断风险，避免后续清理或回滚带来的复杂处理。&lt;/p&gt;
&lt;h4&gt;写入后：本地累计增量与后台批量同步&lt;/h4&gt;
&lt;p&gt;写入成功后，本次操作产生的资源增量将被纳入相应的用量统计，并按既定收敛机制与全局状态对齐。具体来说，三类统计都会受到影响：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;全局层面：文件系统整体用量会增加（或减少）；  &lt;/li&gt;
&lt;li&gt;目录层面：相关目录子树的用量也会随之变化；  &lt;/li&gt;
&lt;li&gt;用户/用户组层面：对应主体的用量同样需要累加。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些更新首先反映在客户端本地累计的增量中，而不会立即以强一致方式写回后端；随后再由后台任务批量 flush，并通过周期性的 refresh 与其他客户端逐步对齐，最终完成全局收敛。&lt;/p&gt;
&lt;h2&gt;03 用量统计（stats）：实现配额系统的基础&lt;/h2&gt;
&lt;p&gt;配额机制要发挥作用，前提是系统能够以较低开销掌握当前资源用量。无论是规模庞大的目录树，还是数量众多的用户与用户组，如果每次检查都依赖实时全量扫描，性能成本都会难以接受。因此，高效且可靠的用量统计机制，是配额系统得以落地的前提。&lt;/p&gt;
&lt;h3&gt;目录 stats&lt;/h3&gt;
&lt;p&gt;目录配额约束的是整个目录子树的空间与 inode 总量，而不是单个文件的大小，因此需要依赖目录级用量统计作为支撑。&lt;/p&gt;
&lt;p&gt;需要特别注意的是，目录统计（DirStats）与目录配额（Quota）的统计口径并不相同：目录统计仅计算当前目录下一级子目录和子文件的用量总和，属于单层统计；而目录配额统计的是整个目录子树的总用量，属于递归统计。这一设计使得目录统计能够以更低的开销维护，而目录配额则提供完整的子树用量视图。&lt;/p&gt;
&lt;p&gt;实现这类统计的关键，&lt;strong&gt;在于大规模目录树下保持低开销与高可用性。&lt;/strong&gt;JuiceFS 延续了与配额机制一致的思路：本地高频更新、后台批量持久化。客户端在内存中维护目录用量增量；当写入、删除等操作发生时，先在本地记录变化，再由后台任务定期批量同步到元数据后端。&lt;/p&gt;
&lt;p&gt;同时，系统不会在挂载时全量加载目录树统计。在目录规模较大时，全量加载会带来显著的耗时与内存开销。因此目录统计采用按需获取策略：仅在配额检查、用量汇总、运维查询等需要精确用量的场景下，才从后端加载对应目录的统计数据。&lt;/p&gt;
&lt;p&gt;当用户通过 &lt;code&gt;df&lt;/code&gt; 或应用通过 &lt;code&gt;statfs&lt;/code&gt; 获取用量信息时，JuiceFS 在性能与准确性之间做了折中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;优先使用本地缓存的已用空间和 inode 进行快速计算；  &lt;/li&gt;
&lt;li&gt;如果本地基准不完整（如刚启动）或需要更高实时性，再从后端拉取最新的全局计数进行校准；  &lt;/li&gt;
&lt;li&gt;最后叠加本地未同步的增量，以使结果更贴近当前节点的真实写入状态。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在得到已用量之后，客户端再结合是否配置了总容量上限来计算 &lt;code&gt;total&lt;/code&gt; 和 &lt;code&gt;avail&lt;/code&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;若已配置上限，总容量按该值，剩余可用容量为“上限减去已用”；  &lt;/li&gt;
&lt;li&gt;若未配置上限，则返回动态估算的总容量，确保 &lt;code&gt;df&lt;/code&gt; 等工具正常显示。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;另外，从根目录查询配额时，系统会展示最大空间和 inode 上限，便于管理员了解全局资源限制。&lt;/p&gt;
&lt;p&gt;此外，JuiceFS 将在 1.4 版本中支持对回收站（Trash）的目录统计进行实时更新。当文件被删除移入回收站或从回收站恢复、清理时，系统会即时更新回收站目录的统计信息，确保管理员能够准确掌握回收站的空间占用情况。&lt;/p&gt;
&lt;h3&gt;用户、用户组 stats&lt;/h3&gt;
&lt;p&gt;用户和用户组统计只会在对应的配额特性开启后才开始采集。开启前，内核路径中的 &lt;code&gt;updateUserGroupStat&lt;/code&gt; 调用会直接返回，不产生实际统计。开启后，客户端会在本地以内存 map 维护用量数据，以 uid 和 gid 作为 key，并在所有可能引起用量变化的路径上更新相应统计。&lt;/p&gt;
&lt;p&gt;需要特别注意的是，首次通过 &lt;code&gt;juicefs quota set --uid&lt;/code&gt; 或 &lt;code&gt;--gid&lt;/code&gt; 为某个用户或用户组设置配额时，系统会立即执行一次全局扫描，对已有文件进行全量遍历，以初始化存量统计数据。完成初始化后，后续的新增写入和删除操作则转为增量更新，无需再次执行全量扫描。&lt;/p&gt;
&lt;h2&gt;04 常见案例&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;1. 文件已删除，为什么文件系统总配额没有下降？对象存储账单为什么也没有变化？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这通常并不是统计错误，而是文件系统语义与统计模型共同作用的结果。&lt;/p&gt;
&lt;p&gt;例如，在 JuiceFS 中启用回收站后，删除操作并不会立即释放空间，而是先将文件移动到回收站以便后续恢复。因此，回收站中的文件仍会计入文件系统总配额和用户组配额，但不再计入原目录配额。&lt;/p&gt;
&lt;p&gt;另一个常见原因，是文件系统统计与对象存储侧计费之间本来就存在时间差。JuiceFS 的配额统计采用“本地累计 + 后台周期同步”的模型，短时间内不同客户端或不同统计接口之间可能尚未完全收敛；与此同时，对象存储侧也可能尚未完成垃圾回收（GC）或生命周期清理。因此，在短时间内看到文件系统用量、配额统计与对象存储账单不完全一致，通常属于预期现象，只要后续能够逐步收敛，一般不视为系统异常。&lt;/p&gt;
&lt;p&gt;此外，还需要注意，配额和 &lt;code&gt;statfs&lt;/code&gt; 展示的是文件系统视角下的空间占用与剩余容量，而对象存储账单则基于底层对象的实际存储模型，受分片、合并、延迟回收和生命周期规则等因素影响，两者本就不一定完全一致。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 配额已满，为什么追加写入已有文件时没有立即报错？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这通常与 JuiceFS 某些写入路径中的异步提交流程有关。对应用而言，&lt;code&gt;write&lt;/code&gt; 系统调用可能先成功返回，而实际的数据提交与相应的配额判定会在后续阶段完成。因此，从调用方视角看，追加写入似乎“成功”了，但最终数据未必真正持久化；如果后续提交阶段判定超出配额，对应写入仍可能失败。&lt;/p&gt;
&lt;p&gt;换句话说，应用看到 &lt;code&gt;write&lt;/code&gt; 返回成功，并不等价于这次写入已经完成最终提交。在涉及配额限制的场景中，更稳妥的做法是结合后续错误处理、关闭文件时的返回状态以及实际文件大小变化来判断写入是否真正生效。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 配额还没用满，为什么创建文件却失败了？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这类现象通常与最终一致统计模型下的短暂视图偏差有关。&lt;/p&gt;
&lt;p&gt;例如，某个卷设置了 2000 个 inode 的总配额，系统中已经存在 1999 个文件，按理说还可以再创建 1 个文件。但在极端并发或刷新时序特殊的情况下，客户端本地缓存与后端基准计数之间可能出现短暂不一致，从而导致内存中的已用 inode 统计暂时偏大，最终提前拒绝了原本合法的创建请求。&lt;/p&gt;
&lt;p&gt;这类问题本质上来源于“本地累计 + 周期同步”的收敛模型：它避免了每次操作都依赖后端强一致更新的高开销，但也意味着在极端情况下，系统可能出现短时间的误判。通常这类误判会随着后续同步逐步消失，必要时也可以通过重试来缓解。&lt;/p&gt;
&lt;p&gt;这也说明，在分布式环境下，配额限制更适合被理解为一种高效且近实时的约束机制，而不是对每一次并发操作都做完全同步的强一致判断。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. 写入超出配额后，为什么“失败”的文件还留在目录里？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这并不是 JuiceFS 独有的行为，在遵循 POSIX 语义的文件系统中，这类现象并不罕见。&lt;/p&gt;
&lt;p&gt;例如，用户为某个目录设置了 1 GiB 配额，然后使用 &lt;code&gt;dd&lt;/code&gt; 尝试写入一个 2 GiB 文件。文件系统会先允许前 1 GiB 的合法写入；直到后续写入触发配额上限时，才返回 &lt;code&gt;Disk quota exceeded&lt;/code&gt;。因此，最终留下一个大小约为 1 GiB 的“未写完文件”，并不意味着系统行为异常，而是说明前半部分数据已经成功写入，后续部分才因超限而失败。&lt;/p&gt;
&lt;p&gt;文件系统负责报告错误，但不会替应用程序决定是否删除已经成功写入的数据。是否清理这种不完整文件，应由应用程序自行处理。这也是标准的 POSIX 语义：文件系统负责返回错误，应用程序负责后续清理与恢复。&lt;/p&gt;
&lt;h2&gt;05 小结&lt;/h2&gt;
&lt;p&gt;在分布式文件系统中，配额并不是一个简单的“计数器功能”，而是一套需要在性能、一致性与治理粒度之间权衡的系统设计。JuiceFS 通过写前校验、本地累计以及后台周期同步，在尽量降低写入路径开销的同时，使各类用量统计在最终一致模型下逐步收敛。基于这一机制，配额控制既覆盖文件系统全局容量，也支持目录、用户和用户组等多个层级，从而满足多租户隔离、个体约束和团队资源治理等典型场景的需求。&lt;/p&gt;
&lt;p&gt;如果在实际使用中遇到问题，或有不同的实践思路，欢迎在评论区分享与交流。&lt;/p&gt;&lt;/div&gt;</description><pubDate>Thu, 23 Apr 2026 04:48:05 +0000</pubDate><guid>https://www.juicefs.com/zh-cn/blog/engineering/juicefs-distributed-quota-design-and-case-studies</guid></item><item><title>浅析 Amazon S3 Files：工作机制、性能边界与 JuiceFS 对比</title><link>https://www.juicefs.com/zh-cn/blog/engineering/amazon-s3-files-vs-juicefs</link><description>&lt;div class="block-markdown"&gt;&lt;p&gt;4 月 7 日，AWS 官方发布了一项新服务——Amazon S3 Files，允许用户无需搬迁数据，即可将 S3 存储桶作为高性能共享文件系统挂载到计算节点上。&lt;/p&gt;
&lt;p&gt;这不是业界第一次尝试让 S3 以文件系统方式被访问：从早期的 s3fs，到 AWS 后来推出的 Mountpoint for Amazon S3，再到今天的 S3 Files，S3 “像文件系统一样被访问”这条路，其实已经走了很多年。区别在于，前两者更多是在访问层做文章，而这一次，AWS 终于把共享访问、文件系统语义和托管高性能层真正捏成了一个原生方案。&lt;/p&gt;
&lt;p&gt;这也让 S3 Files 成为一个值得单独分析的新选项。对于希望以文件方式访问现有 S3 数据的业务来说，它提供了原生、轻量的方案；但放到 AI 模型训练、大数据分析等更复杂的场景中，它的实际表现究竟如何，仍需要结合其底层实现与运行机制来看。&lt;/p&gt;
&lt;p&gt;本文将围绕 S3 Files 的底层实现、性能边界以及与 JuiceFS 的差异展开分析。&lt;/p&gt;
&lt;h2&gt;01 S3 Files ：以 EFS 为高性能层的 S3 原生文件系统方案&lt;/h2&gt;
&lt;p&gt;从底层实现看，S3 Files 使用 Amazon EFS（Elastic File System）作为托管的高性能存储层，用来承接需要低延迟访问的数据和相关元数据，并在此基础上为 S3 提供完整的文件系统语义，包括一致性、文件锁和 POSIX 权限。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;可以把它理解为：AWS 在对象存储之上增加了一层基于 EFS 的文件系统访问面，使原本只能通过对象接口访问的数据，也能以目录、文件和挂载点的形式被计算节点直接使用；而文件系统与 S3 之间的数据变化，则由服务在后台自动同步。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;基于这种架构，S3 Files 并不会搬迁全量数据，而是只将当前工作集中的一部分数据按需放到高性能层中；而数据的“Source of Truth”依然保留在 S3 中。&lt;/p&gt;
&lt;h2&gt;02 S3 Files 如何工作：挂载、导入与同步机制&lt;/h2&gt;
&lt;p&gt;对 S3 Files 来说，挂载只是开始，真正影响体验的是挂载之后的数据路径：作用域如何确定，首次访问会导入什么，哪些请求会进入高性能层，写入后又会如何同步回 S3。这些机制，也直接决定了后文要讨论的性能边界与成本结构。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;S3 Files 挂载架构&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;S3 Files 挂载架构示意图&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;以 EC2 挂载现有 S3 bucket 为例，真正需要看清的不是挂载命令本身，而是挂载之后数据会如何被导入、访问与同步。下面是几个关键的技术细节与步骤。&lt;/p&gt;
&lt;h3&gt;a) 先确定作用域：导入全量 S3 桶，还是指定部分目录&lt;/h3&gt;
&lt;p&gt;两者皆可。 S3 Files 支持将整个 S3 存储桶作为文件系统挂载，也支持通过 Prefix（前缀） 限制作用域，&lt;/p&gt;
&lt;p&gt;例如只挂载 &lt;code&gt;s3://my-bucket/data/ml/&lt;/code&gt; 目录下。对于包含数千万个对象的庞大 S3 桶尤为重要，因为过大的作用域会增加元数据同步的负担。&lt;/p&gt;
&lt;p&gt;在计算节点上使用 S3 Files 时，AWS 提供了定制的挂载客户端 &lt;code&gt;amazon-efs-utils&lt;/code&gt;。挂载时使用的并不是存储桶名称，而是 AWS 为 S3 Files 分配的 file system ID。&lt;/p&gt;
&lt;p&gt;创建一个本地挂载目录，并使用专用的 &lt;code&gt;s3files&lt;/code&gt; 文件系统类型进行挂载：&lt;/p&gt;
&lt;pre class="codehilite"&gt;&lt;code class="language-plain"&gt;sudo yum -y install amazon-efs-utils
sudo mkdir /mnt/s3files
sudo mount -t s3files fs-1234567890abcdef0:/ /mnt/s3files
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;如果只希望访问某个子目录，也可以在挂载路径中进一步指定。但从实践上看，更推荐在创建 S3 Files 时就把作用域限定到明确的 prefix，而不是在一个过大的存储桶上再做后置控制。&lt;/p&gt;
&lt;h3&gt;b) 首次访问时会发生什么：导入触发方式与大小阈值&lt;/h3&gt;
&lt;p&gt;S3 Files 并不会在挂载后立即把整个数据集搬入高性能层。它的数据导入由访问事件触发，默认模式是 &lt;code&gt;ON_DIRECTORY_FIRST_ACCESS&lt;/code&gt;：当你第一次访问某个目录时，系统会导入该目录下文件的元数据，并将符合条件的小文件数据异步导入 EFS 高性能层。&lt;/p&gt;
&lt;p&gt;如果配置为 &lt;code&gt;ON_FILE_ACCESS&lt;/code&gt;，则首次遍历目录时只导入元数据，只有在文件第一次被实际读取时，数据才会进入高性能层。这种方式更节省空间和导入成本，但首读延迟也会更高。&lt;/p&gt;
&lt;p&gt;这里最关键的控制参数是 &lt;code&gt;sizeLessThan&lt;/code&gt;。默认情况下，只有小于 128 KB 的文件才会在导入时进入高性能层；更大的文件通常只导入元数据，内容仍然主要通过 S3 获取。&lt;strong&gt;换句话说，S3 Files 优先优化的是小文件和低延迟访问&lt;/strong&gt;，而不是把所有数据都预热到高性能层中。对于 AI 训练这类以 10 MB 级图片、音视频文件为主的数据集来说，这一点尤其关键：即使完成了目录遍历，这些大文件在默认配置下也未必会真正进入高性能层。&lt;/p&gt;
&lt;h3&gt;c) 同步周期与冲突解决机制&lt;/h3&gt;
&lt;p&gt;S3 Files 会在后台自动维护文件系统与 S3 之间的双向同步。S3 侧发生变化后，文件系统视图会随之更新；而在计算节点上的写入，则会先落到 EFS 高性能层，再由后台批量同步回 S3。默认情况下，系统会对修改进行一段时间的聚合，再执行回写。&lt;/p&gt;
&lt;p&gt;冲突处理的原则也很明确：&lt;strong&gt;S3 始终是 Source of Truth。&lt;/strong&gt; 如果文件系统侧的修改尚未同步回 S3，而对应对象已经在 S3 中被其他应用更新，系统会以 S3 中的最新版本为准，并将冲突文件移入 &lt;code&gt;.s3files-lost+found-*&lt;/code&gt; 目录。&lt;/p&gt;
&lt;h2&gt;03 S3 Files 的性能边界与成本结构&lt;/h2&gt;
&lt;p&gt;上一节解释的是 S3 Files 如何运行，这一节进一步讨论的，则是这种运行方式会带来怎样的性能边界与成本结构。高性能层占用、大文件读取路径、写入流转，以及局部更新和目录操作带来的放大效应，是实际选型中最需要重点考量的四个方面。&lt;/p&gt;
&lt;h3&gt;a) EFS 高性能层的占用、回收与成本&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;S3 Files 的高性能层并不是按容量上限做 LRU 淘汰，而是按访问时间进行生命周期管理。&lt;/strong&gt; 默认情况下，已同步到 S3 且 30 天未被读取的数据会从 EFS 高性能层中移除；这一时间由 &lt;code&gt;daysAfterLastAccess&lt;/code&gt; 控制，可配置范围为 1–365 天。&lt;/p&gt;
&lt;p&gt;这意味着，&lt;strong&gt;它的成本取决于有多少数据需要驻留在 EFS 中，以及驻留多久。&lt;/strong&gt; 如果工作集很大且长期保持活跃，相关费用就会持续上升。&lt;/p&gt;
&lt;h3&gt;b) 大文件直读与随机读：其实是客户端在“穿透”读取&lt;/h3&gt;
&lt;p&gt;S3 Files 对大文件的处理，并不是把所有读取都留在 EFS 高性能层中完成。默认情况下，&lt;code&gt;sizeLessThan&lt;/code&gt; 的值为 128 KB，它决定的是哪些文件会在导入时把数据放入高性能层；而对于已经同步到 S3 的数据，128 KB 及以上的读取会直接从 S3 流式返回。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;S3 Files 基于 128 KB 阈值的数据路由机制&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;S3 Files 基于 128 KB 阈值的数据路由机制&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;&lt;strong&gt;也就是说，S3 Files 的优化重点更偏向小文件和低延迟访问，而不是让大文件读取长期稳定命中高性能层。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这条直读路径依赖于计算资源本身具备读取源存储桶的权限。AWS 官方文档明确要求相关角色拥有 &lt;code&gt;s3:GetObject&lt;/code&gt; 和 &lt;code&gt;s3:GetObjectVersion&lt;/code&gt; 等权限；否则，客户端就无法直接从 S3 读取数据。&lt;/p&gt;
&lt;h3&gt;c) 顺序写的代价：大规模写入会引入额外流转成本&lt;/h3&gt;
&lt;p&gt;S3 Files 的写路径并不是直接落到 S3。&lt;strong&gt;所有写操作都会先进入 EFS 高性能层，再由后台同步回 S3。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这意味着，如果你的场景会持续产生大量结果数据，例如顺序写入数百 TB 的训练产物或分析结果，那么这些数据在流经 S3 Files 时，会额外引入两类成本：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;数据流转成本：写入先进入高性能层，随后再同步回 S3。相比直接写入 S3，这条路径会多出一层中间流转开销。  &lt;/li&gt;
&lt;li&gt;短期驻留成本：数据同步完成后，并不会立刻从高性能层中移除，而是要等到满足过期条件后才会清理。默认情况下，这意味着大批量写入产生的临时数据，可能在一段时间内持续占用 EFS 容量。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以某一区域当前价格为例，写入 EFS 约为 $0.06/GB，后台同步回 S3 的读取约为 $0.03/GB，仅数据流转这一层，每 1 TB 写入就大约会多出 $90 的附加成本。如果这些数据在同步完成后仍然继续驻留在 EFS 中，还会进一步产生对应的高性能层存储费用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这也是为什么，S3 Files 更适合读取现有数据，而不适合长期承接大规模、持续性的结果写入。&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;d) 局部更新与目录操作：对象模型带来的放大效应&lt;/h3&gt;
&lt;p&gt;S3 Files 底层不对数据进行切块，而是尽量保持文件与 S3 对象之间的直接映射。&lt;strong&gt;这带来的代价是：一旦涉及大文件的局部随机写或追加写，应用层看起来只是一次很小的更新，底层同步回 S3 时却更容易放大为显著的对象写入与版本开销。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;例如，用户通过 S3 Files 在一个 &lt;strong&gt;100 GB&lt;/strong&gt; 的 &lt;code&gt;lmdb&lt;/code&gt; 文件中追加了一条 &lt;strong&gt;100 KB&lt;/strong&gt; 的图片 key，应用侧看到的只是一次很小的写入；但这类修改并不会立刻回写到 S3，而是会在&lt;strong&gt;大约 60 秒&lt;/strong&gt;内先做聚合，再同步回存储桶。&lt;strong&gt;它不会像块存储那样只改动一个离散块，而更可能放大为对象写入、同步时延和版本存储成本。&lt;/strong&gt; 文件越大、修改越频繁，这种代价就越值得警惕。&lt;/p&gt;
&lt;p&gt;目录重命名同样受 S3 扁平命名空间限制。S3 本身没有传统文件系统中的目录元数据，因此执行 &lt;code&gt;rename&lt;/code&gt; 或 &lt;code&gt;mv&lt;/code&gt; 时，S3 Files 不能只改一条元数据，而是必须在 S3 侧为目录中的每个文件写入新对象并删除旧对象。对于拥有千万级对象的目录，这会显著拉长同步时间，并增加 S3 请求成本；在同步完成前，文件系统视图与 S3 视图之间还可能暂时不完全一致。&lt;/p&gt;
&lt;p&gt;总体来看，S3 Files 的优势在于原生接入、零数据迁移，以及对现有 S3 资产的良好兼容。它的代价则在于：一旦场景转向大文件读取、持续写入、频繁局部更新或大目录操作，性能和成本都会更快被放大。也正因为如此，S3 Files 的优势更适合发挥在轻量共享访问场景中；而在训练、数据生产和大规模分析等重负载场景下，它的代价往往会更早暴露出来。&lt;/p&gt;
&lt;h2&gt;04 JuiceFS vs S3 Files：两种不同的架构思路&lt;/h2&gt;
&lt;p&gt;前一节已经看到，S3 Files 的很多边界并非偶然，而是这类方案的共性结果。无论是早期的 s3fs、主打高吞吐读取的 Mountpoint for Amazon S3，还是今天的 S3 Files，它们都尽量保持文件与 S3 对象之间的直接映射，以换取对现有 S3 数据的透明访问能力。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这条路线的优势是透明和低改造，代价则是先天受制于 S3 的对象模型。&lt;/strong&gt; 这也是为什么目录操作更容易退化为对象级请求，大文件的局部更新也更容易演化为写放大、同步延迟和额外成本。&lt;/p&gt;
&lt;p&gt;也正因为如此，JuiceFS 与这类方案的差异，并不是某个功能点或单项指标的差别，而是两条架构路线的根本区别。&lt;strong&gt;JuiceFS 不是“把 S3 挂出来用”的访问层，而是构建在对象存储之上的云原生分布式文件系统。&lt;/strong&gt; 它采用数据与元数据解耦的架构：文件数据存放在底层对象存储中，元数据则由高性能键值数据库独立管理，因此更适合承接训练、分析和数据生产等更重的生产型负载。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;1JuiceFS 架构图.drawio&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 社区版架构图&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;为了让大家能更直观地进行架构选型，我们从底层架构到高阶特性，将 JuiceFS 与 S3 Files 进行了全方位对比：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;对比维度&lt;/th&gt;
&lt;th style="text-align: left;"&gt;JuiceFS&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Amazon S3 Files&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;整体架构&lt;/td&gt;
&lt;td style="text-align: left;"&gt;数据与元数据分离，文件切块后写入对象存储&lt;/td&gt;
&lt;td style="text-align: left;"&gt;基于 EFS 代理，数据不切块，1:1 动态根据设置的文件大小来映射对象（默认&amp;lt;128KB）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;核心成本&lt;/td&gt;
&lt;td style="text-align: left;"&gt;软件开源免费，主要成本来自对象存储、元数据引擎和缓存资源&lt;/td&gt;
&lt;td style="text-align: left;"&gt;除 S3 存储外，需额外支付 EFS 存储费($0.30/GB)及数据读写 Sync 费&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;读写放大(随机写)&lt;/td&gt;
&lt;td style="text-align: left;"&gt;部分场景极低。数据切块后，局部随机写通常只更新受影响的数据块，无需重写全量数据&lt;/td&gt;
&lt;td style="text-align: left;"&gt;数据生产场景会很高，大文件随机修改会导致整个对象的重传重写&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;冷热分层策略&lt;/td&gt;
&lt;td style="text-align: left;"&gt;基于容量与访问热度，将热数据自动预热至计算节点的本地盘/内存缓存中&lt;/td&gt;
&lt;td style="text-align: left;"&gt;基于文件大小与访问时间。小文件(&amp;lt;128K)热数据缓存在 EFS，大文件绕过 EFS 直接读写 S3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;小文件性能&lt;/td&gt;
&lt;td style="text-align: left;"&gt;依赖全内存的独立元数据引擎(Redis/TiKV 等)，更适合大量小文件与元数据操作&lt;/td&gt;
&lt;td style="text-align: left;"&gt;依赖 EFS 性能与 NFS 协议&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;大文件吞吐&lt;/td&gt;
&lt;td style="text-align: left;"&gt;可结合本地 NVMe / 内存缓存提升吞吐&lt;/td&gt;
&lt;td style="text-align: left;"&gt;依赖 EFS 网关或 S3 直连性能，大规模并行吞吐与容量配额绑定&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;缓存一致性&lt;/td&gt;
&lt;td style="text-align: left;"&gt;强一致性 (Close-to-open)。由独立元数据服务统一仲裁&lt;/td&gt;
&lt;td style="text-align: left;"&gt;NFS Close-to-open。但遇到底层 S3 和文件系统并发修改冲突时，本地 EFS 数据会被丢弃至 lost+found，S3 强行作为 Truth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;POSIX 兼容性&lt;/td&gt;
&lt;td style="text-align: left;"&gt;几乎 100% 兼容。 支持 Hard Links、原子级 Rename、各类锁语义&lt;/td&gt;
&lt;td style="text-align: left;"&gt;支持 NFSv4.1/4.2 子集。 不支持硬链接(Hard links)、不支持原子重命名&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;权限管理&lt;/td&gt;
&lt;td style="text-align: left;"&gt;支持标准 POSIX 权限、ACL、Extended ACL 等多种鉴权&lt;/td&gt;
&lt;td style="text-align: left;"&gt;支持标准 POSIX 权限、ACL、Extended ACL 等多种鉴权&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;加密与安全&lt;/td&gt;
&lt;td style="text-align: left;"&gt;传输加密、静态加密、并提供国密支持&lt;/td&gt;
&lt;td style="text-align: left;"&gt;传输级 TLS 加密、静态 SSE-KMS 密钥加密&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;AI 场景优化&lt;/td&gt;
&lt;td style="text-align: left;"&gt;深度优化了 LMDB、Safetensors 等 AI 常见格式的 mmap 读取与本地预热机制&lt;/td&gt;
&lt;td style="text-align: left;"&gt;无专门针对 AI 格式的底层优化，依赖基础文件流式读取&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;05 小结&lt;/h2&gt;
&lt;p&gt;没有绝对完美的银弹，只有最适合特定场景的方案。&lt;/p&gt;
&lt;p&gt;S3 Files 的面世，填补了 AWS 官方生态中“无缝、免搬迁将 S3 原生转换为文件系统”的空白。它的设计非常明显：&lt;strong&gt;S3 对象生态的 100% 格式透明，并针对性优化 AI 场景的小文件（&amp;lt;128KB）的读写性能。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;什么时候选择 S3 Files？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果核心诉求是在不改动现有架构的前提下，让旧应用、Shell 脚本或传统软件直接以文件方式访问现有 S3 数据；或者需要一个通用的共享文件空间，且以只读、小文件、顺序读写为主，那么 S3 Files 会是更自然的选择。它的原生托管、即插即用和零数据迁移能力，可以显著降低接入门槛（但是为了这个便利性可能需要付出高昂的 EFS 存储和同步成本来交换）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;什么时候选择 JuiceFS？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果业务面向 AI 模型训练、数据生产、高性能计算（HPC）或大数据分析，面临千万级小文件、TB 级大文件随机读写，或对 mmap、缓存命中率和整体吞吐有更高要求，那么 JuiceFS 会更适合。相比 S3 Files，JuiceFS 的数据切块、独立元数据引擎和更灵活的缓存体系，更适合承接重负载和长期运行的生产型和 AI 训推文件系统场景。&lt;/p&gt;&lt;/div&gt;</description><pubDate>Tue, 14 Apr 2026 08:29:00 +0000</pubDate><guid>https://www.juicefs.com/zh-cn/blog/engineering/amazon-s3-files-vs-juicefs</guid></item><item><title>一文解锁 JuiceFS 在 AI 场景中的性能优化</title><link>https://www.juicefs.com/zh-cn/blog/engineering/juicefs-ai-workload-performance-optimization</link><description>&lt;div class="block-markdown"&gt;&lt;p&gt;大模型训练的算力规模持续扩张，GPU 算力不断提升的同时，数据访问瓶颈对系统整体性能的影响愈发突出。本地存储性能优异但扩展性有限，对象存储在成本与扩展性上具备优势，却在海量小文件、高并发场景下面临吞吐不足的问题，团队往往需要在二者之间艰难取舍。&lt;/p&gt;
&lt;p&gt;为此，分布式文件系统成为平衡高性能与可扩展性的关键方案。JuiceFS 已在多行业 AI 场景中广泛落地，其分布式架构能够在大规模数据访问场景下，同时兼顾高性能、强扩展与低成本。&lt;strong&gt;本文将从性能角度介绍 JuiceFS 的架构设计，分析不同访问模式下的核心性能瓶颈与优化方法。文中关键知识点均附对应详情链接，为用户理解 JuiceFS 性能机理、掌握常见调优方向提供参考。&lt;/strong&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 在 AI 场景中的应用&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 在 AI 场景中的应用&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;h2&gt;01 从架构看 JuiceFS 的性能基础&lt;/h2&gt;
&lt;p&gt;JuiceFS 分为社区版与企业版，二者整体架构一致，均采用元数据与数据分离的存储架构。客户端采用富客户端设计，承载包括部分元数据处理在内的多项核心逻辑，并同时提供元数据缓存与数据缓存能力，各模块协同工作以实现数据的高效定位与访问。底层数据存储基于对象存储构建，并可借助本地缓存进一步提升访问性能。对外接口上，JuiceFS 支持多种接入方式，其中 FUSE 最为常用，同时也兼容各类 SDK 与 S3 网关。&lt;/p&gt;
&lt;p&gt;社区版定位为通用文件系统，用户可根据需求选择不同的元数据引擎。小规模部署可选择 Redis，实现轻量、高响应的数据管理；大规模文件场景可选择 TiKV，以获得良好的横向扩展能力。（&lt;a href="https://juicefs.com/zh-cn/blog/solutions/juicefs-metadata-engine-selection-guide"&gt;参考：JuiceFS 元数据引擎选型指南&lt;/a&gt;）&lt;/p&gt;
&lt;p&gt;企业版面向复杂高性能场景，相较于社区版，最大的差异有两方面：企业版采用自研多分区元数据引擎，基于 Raft 构建纯内存集群，延迟低且横向扩展能力强，可支持 5,000 亿文件规模。相比社区版需多次 KV 请求完成的操作，企业版通常仅需一次或两次，并可在元数据集群内部处理复杂逻辑。其次，企业版支持分布式缓存共享：同组客户端可在同一区域内互访本地缓存，基于一致性哈希实现，提高缓存命中率和访问效率。在多节点高并发场景下，缓存空间可横向扩展，任务执行前可预热大部分所需数据，从而加速 AI 训练与推理，提高系统性能和稳定性。（&lt;a href="https://juicefs.com/zh-cn/blog/release-notes/juicefs-enterprise-5-3-500b-files-rdma-support"&gt;JuiceFS 企业版 5.3 特性详解：单文件系统支持超 5,000 亿文件，首次引入 RDMA&lt;/a&gt;）&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 社区版和企业版架构&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 社区版和企业版架构&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;h3&gt;数据分块设计&lt;/h3&gt;
&lt;p&gt;JuiceFS 将数据切块后存储于对象存储，这一设计是其提升性能的关键，将影响数据读取效率、缓存命中率及高并发访问下的吞吐能力。&lt;/p&gt;
&lt;p&gt;JuiceFS 会将文件拆分为多个 chunk。在每个 chunk 内部，系统维护管理结构 slice，用于跟踪数据写入和更新。当文件发生写入时，新数据不会覆盖已有 slice，而是以新的 slice 追加到 chunk 上层。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;chunk&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;理想情况下，每个 chunk 最终只应包含一个 slice。每个 slice 由若干 4 MB 的 block 组成，这些 block 是最终存储到对象存储的最小单元。默认情况下，缓存系统也以 block 为单位进行管理。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;block&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;从右上方示意图可以看出，文件更新采用追加式写入：红色部分为已有 slice，新数据以新的 slice 叠加。读取时，系统组合各层 slice 形成当前视图；碎片过多时，再通过 compaction 合并，以优化访问性能。更多关于数据分块的细节可参考&lt;a href="https://juicefs.com/docs/zh/community/architecture#how-juicefs-store-files"&gt;文档&lt;/a&gt;。&lt;/p&gt;
&lt;h3&gt;缓存体系&lt;/h3&gt;
&lt;p&gt;相较于直接访问对象存储，JuiceFS 的性能提升在很大程度上得益于其缓存体系。JuiceFS 客户端配备了高性能的本地缓存模块，与之相关的配置项如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cache-dir&lt;/code&gt;：用于指定缓存目录；  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;cache-size&lt;/code&gt;：用于设定用于缓存的空间大小；  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;prefetch&lt;/code&gt;：这是缓存模块中的一个参数，负责预取功能。当某一请求命中某个 block 时，会启动一个后台线程，将整个块完整拉取下来；  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;write back&lt;/code&gt; 相关配置：用于提高写 IOPS，将需要上传至对象存储的数据块，先写入本地缓存，再异步上传至对象存储。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;企业版还具备一些进阶配置，例如通过 cache group 指定一批客户端，将它们的本地缓存配置为同一个分布式缓存组，实现缓存数据的共享。此外，no sharing 是与缓存组相关的配置，启用 no sharing 后，客户端仅从指定的缓存组读取数据，但不作为缓存组成员提供数据读取服务。如此一来，便形成了两级缓存：第一级是本地缓存，第二级是缓存组中其他节点上的缓存。&lt;/p&gt;
&lt;p&gt;另一个提升性能的机制是内存 buffer（读 buffer），具有以下作用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;合并 IO 请求&lt;/strong&gt;：可内存层面合并多个连续的 IO 请求。例如，系统发出三个 IO 请求，经内存缓存处理后，实际发出的可能仅有一个；  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自适应预读功能&lt;/strong&gt;：在大文件顺序读取场景下，自适应预读功能通过预读来提升请求并发度，从而充分利用缓存和对象存储资源，提高整体 I/O 性能。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;企业版还有一些进阶配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;max read ahead&lt;/code&gt;：用于设定预读的最大范围。  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;initial read ahead&lt;/code&gt;： 用于设置开启预读时的预读窗口大小，默认以 4MB 块为单位。  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;read ahead ratio&lt;/code&gt;： 是去年新增的配置，用于控制大文件随机读取时的预读比例，减少读放大导致的带宽瓶颈。过于激进的预读可能对随机读取性能产生负面影响，&lt;code&gt;read ahead ratio&lt;/code&gt; 可用于缓解该问题。在 AI 场景中，遇到大文件顺序或随机访问导致的带宽或 IOPS 瓶颈时，可通过调整这些参数优化整体性能。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;02 JuiceFS 基准 I/O 测试与瓶颈分析&lt;/h2&gt;
&lt;p&gt;在介绍 JuiceFS 在常见 AI 场景下的性能调优之前，先通过连续读和随机读基准测试观察系统在理想条件下的 I/O 表现，以理解不同访问模式下的吞吐量与延迟，为后续 AI/ML 场景的读写模式提供参考。&lt;/p&gt;
&lt;h3&gt;连续读性能&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;在 JuiceFS 中，连续读的性能通常主要受带宽因素影响。在冷读场景下，性能主要受对象存储带宽约束；而在分布式缓存场景下，网络带宽可能成为瓶颈&lt;/strong&gt;。例如，一台配备 40 Gbps 网卡的机器，其实际可用带宽可能不足 5 Gbps。此外，FUSE 层的用户态与内核态转换开销也会限制单线程吞吐，经测试单线程读取文件的带宽约为 3.5 Gbps。要突破此限制，需要采用多线程或多并发策略以充分利用存储与网络资源。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;threads&lt;/th&gt;
&lt;th style="text-align: left;"&gt;bw(GB/s)&lt;/th&gt;
&lt;th style="text-align: left;"&gt;bw/threads&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;1&lt;/td&gt;
&lt;td style="text-align: left;"&gt;3.5&lt;/td&gt;
&lt;td style="text-align: left;"&gt;3.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;2&lt;/td&gt;
&lt;td style="text-align: left;"&gt;6.3&lt;/td&gt;
&lt;td style="text-align: left;"&gt;3.15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;3&lt;/td&gt;
&lt;td style="text-align: left;"&gt;9.5&lt;/td&gt;
&lt;td style="text-align: left;"&gt;3.16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;4&lt;/td&gt;
&lt;td style="text-align: left;"&gt;9.7&lt;/td&gt;
&lt;td style="text-align: left;"&gt;2.43&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;6&lt;/td&gt;
&lt;td style="text-align: left;"&gt;14.0&lt;/td&gt;
&lt;td style="text-align: left;"&gt;2.33&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;8&lt;/td&gt;
&lt;td style="text-align: left;"&gt;17.0&lt;/td&gt;
&lt;td style="text-align: left;"&gt;2.13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;10&lt;/td&gt;
&lt;td style="text-align: left;"&gt;18.6&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;15&lt;/td&gt;
&lt;td style="text-align: left;"&gt;21&lt;/td&gt;
&lt;td style="text-align: left;"&gt;1.4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;在性能测试中，单线程连续读带宽约为 3.5 Gbps，随着线程数增加，整体吞吐量可逐渐接近网络带宽上限。为了方便评估自身环境的性能上限，JuiceFS 提供了 &lt;code&gt;bj bench&lt;/code&gt; 子命令，可用于测试对象存储带宽。&lt;/p&gt;
&lt;p&gt;在实际业务中，缓存往往比直接访问对象存储更常见。此时，可通过增大 &lt;code&gt;buffer size&lt;/code&gt; 提高后台预读请求数，从而提升并发度并改善整体吞吐。例如，将 buffer size 调整至 400 MB（对应 100 个 4 MB 块的后台预读请求）后，并发度显著提升，整体吞吐量随之增强。&lt;/p&gt;
&lt;h3&gt;随机读性能&lt;/h3&gt;
&lt;h4&gt;低并发随机读&lt;/h4&gt;
&lt;p&gt;在低并发且非异步访问场景下，每个请求需等待前一个完成后才能发出，因此延迟对整体性能的影响尤为显著。&lt;strong&gt;I/O 延迟可能来源于多方面，包括元数据查询延迟、对象存储访问延迟，以及本地缓存或分布式缓存读取延迟&lt;/strong&gt;。在分析随机读性能时，需要重点关注这些延迟因素。&lt;/p&gt;
&lt;p&gt;在 4 KB 随机冷读场景下，若 IOPS 仅为 8，且对象存储延迟约 125 毫秒，则可计算出系统并发度约为 1（8 IOPS × 125 ms ≈ 1000 ms）。&lt;/p&gt;
&lt;p&gt;这表明当前处于近似单并发、请求串行阻塞的状态。在这种情况下，优化重点通常不在于进一步提升并发，而在于缩短访问路径、降低单次请求延迟，例如将数据预热至本地缓存。完成预热后，随机读路径可由对象存储切换至本地缓存，IOPS 可提升至约 12,000，接近本地磁盘的 I/O 水平。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;juicefs stats 命令查看性能&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;juicefs stats 命令查看性能&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;预热后性能&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;预热后性能&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;h4&gt;高并发随机读&lt;/h4&gt;
&lt;p&gt;高并发随机读通常发生在并发数较高或采用异步 I/O 的场景下，其性能瓶颈主要体现在 IOPS 限制上。IOPS 包括元数据 IOPS、对象存储 IOPS 以及缓存 IOPS。通过 JuiceFS，可以观察这些指标，从而确定性能瓶颈所在。此外，客户端机器的资源（如 CPU 和内存）也可能对性能产生影响，但这类瓶颈相对容易监测。&lt;/p&gt;
&lt;p&gt;在冷读场景下，以通过 Libaio 发起的随机读为例，对象存储侧的 IOPS 上限接近 7,000/s。若启用缓存并完成数据预热，访问路径将由对象存储切换至缓存层，IOPS 可进一步提升至 20,000 以上，说明高并发随机读的瓶颈会随访问路径变化而发生转移。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;预热前&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;预热前&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;预热后&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;预热后&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;有兴趣深入了解 JuiceFS 的完整数据访问链路，请参考博客：&lt;a href="https://juicefs.com/zh-cn/blog/engineering/juicefs-read-performance#05-%E8%BF%9E%E7%BB%AD%E8%AF%BB%E4%B8%8E%E9%9A%8F%E6%9C%BA%E8%AF%BB%E6%B5%8B%E8%AF%95"&gt;一文详解 JuiceFS 读性能——预读、预取、缓存、FUSE 和对象存储&lt;/a&gt;。&lt;/p&gt;
&lt;h2&gt;03 常见 AI 场景下的 I/O 特性与性能调优&lt;/h2&gt;
&lt;h3&gt;大文件顺序读场景&lt;/h3&gt;
&lt;p&gt;大文件顺序读取的典型应用场景之一是模型加载，例如通过 Pickle 序列化保存的 PT 文件。在此过程中，性能受到两方面限制：一方面，Pickle 的反序列化效率决定了数据处理速度；另一方面，数据读取通常为单线程，受 FUSE 带宽上限和 CPU 性能约束。为提升吞吐量，可通过增加并发度实现多线程或分片加载，从而充分利用 I/O 能力。在大文件顺序读取的场景下，若能够将数据集完全缓存至本地，可获得最佳性能；若仅需按需读取数据，则实现相对简单。&lt;/p&gt;
&lt;p&gt;关于大文件顺序读场景性能优化，可参考&lt;a href="https://juicefs.com/zh-cn/blog/solutions/building-high-throughput-cache-pool-resilience-with-juicefs"&gt;如何构建 70GB/s 吞吐的缓存池&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;海量小文件场景&lt;/h3&gt;
&lt;p&gt;在计算机视觉和多模态任务中，训练数据集通常由大量单独文件组成，例如单张图片、视频帧或文本标注文件。这类海量小文件场景对元数据服务的压力较大。&lt;/p&gt;
&lt;p&gt;海量小文件场景下，元数据性能影响显著。一方面，每个文件的数据量较小；另一方面，存放大量小文件的目录元数据访问效率较低。&lt;strong&gt;对于只读负载，可通过开启客户端元数据缓存并延长缓存周期来提升性能。此外，数据读取层的 IOPS 压力也更大，因为小文件无法充分利用预读机制，导致请求更加碎片化。常用的优化措施包括增加本地缓存容量，对于商业版本可进一步采用横向扩展的分布式缓存集群&lt;/strong&gt;。由于小文件难以受益于预读机制，其延迟表现也相对较高。&lt;/p&gt;
&lt;p&gt;该场景性能优化可参考：&lt;a href="https://juicefs.com/zh-cn/blog/user-stories/horizon-robotics-juicefs-small-file-multi-cloud-optimization"&gt;海量小文件 + 多云协同：地瓜机器人 JuiceFS 存储优化之路&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;大文件随机读场景&lt;/h3&gt;
&lt;p&gt;此类场景在 AI 训练中较为常见，例如按样本随机访问 TFRecord、HDF5 或 LMDB 格式的数据集等。以模型加载为例，若数据集格式为随机读且每次读取的大小为数据集样本大小（如 1MB 至 4MB 的图片或短视频），则预读机制可能导致带宽浪费。此类场景通常可通过多并发加载来突破 IOPS 瓶颈，可采取以下措施：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;增加数据加载的 reader 线程数。  &lt;/li&gt;
&lt;li&gt;使用异步 IO 提高并发度，尽量打满 IOPS。  &lt;/li&gt;
&lt;li&gt;完善缓存体系，如提前将数据映射至缓存以提高底层 IOPS 性能。  &lt;/li&gt;
&lt;li&gt;调整 read ahead ratio 参数（如设为 0.5），以降低预读带来的带宽浪费。例如，原本 4MB 的顺序读会预读 4MB 数据，调整后仅预读 2MB 数据。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;本文从性能角度分析了 JuiceFS 的架构设计、基准 I/O 测试以及在典型 AI 场景下的调优方法，为读者提供关于系统性能的入门参考。JuiceFS 已在大量生产环境中得到应用，其分布式架构在性能与成本之间提供了可行的平衡方案。&lt;/p&gt;
&lt;p&gt;欢迎在评论区分享或讨论实际使用中的经验与策略。&lt;/p&gt;&lt;/div&gt;</description><pubDate>Fri, 03 Apr 2026 02:50:00 +0000</pubDate><guid>https://www.juicefs.com/zh-cn/blog/engineering/juicefs-ai-workload-performance-optimization</guid></item><item><title>ARM 架构 JuiceFS 性能优化：基于 MLPerf 的实践与调优</title><link>https://www.juicefs.com/zh-cn/blog/engineering/arm-juicefs-performance-optimization-mlperf-tuning</link><description>&lt;div class="block-markdown"&gt;&lt;p&gt;随着国产芯片与 ARM 生态的快速发展，如何在 ARM 平台上构建高性能存储基础设施成为技术焦点。Linaro 是一个专注于 Arm 生态和开源软件的国际化技术组织，联合产业链上下游厂商解决共性问题，并协助企业客户在开源基础上完成产品化落地。Linaro 团队在 MLPerf Storage 测试中，对 JuiceFS 社区版（元数据采用 Redis）进行了系统压测，覆盖多种典型机器学习训练负载。&lt;/p&gt;
&lt;p&gt;测试结果显示，系统性能在很大程度上受内存带宽和元数据访问效率影响，JuiceFS 的吞吐能力直接决定 GPU 利用率及训练效率。通过 UNet3D、ResNet-50 和 CosmoFlow 等负载的测试，分析发现：单机场景下，GPU 利用率主要受内存拷贝延迟限制；在双机或多机场景下，元数据访问和节点间同步成为主要瓶颈。文章同时提供了针对这些瓶颈的调优思路与实践结果。&lt;/p&gt;
&lt;p&gt;总体来看，大规模 AI 训练性能调优是一个系统工程，需要从存储系统、内存带宽、CPU 调度、缓存策略等多方面协同优化，才能在 ARM 平台上实现高效的深度学习训练数据供给。&lt;/p&gt;
&lt;h2&gt;01 Arm64 与 x86_64 架构差异与并发特性概述&lt;/h2&gt;
&lt;p&gt;相比 x86，Arm 的应用范围不断扩大，已从移动端延伸至 IoT、可穿戴设备、PC、汽车和服务器，其高能效比（performance per watt）是广泛采用的关键原因。&lt;/p&gt;
&lt;p&gt;从架构设计上看，Arm 属于 RISC（Reduced Instruction Set Computer，精简指令集计算机），x86 属于 CISC（Complex Instruction Set Computer，复杂指令集计算机）。这种设计差异也影响了处理器的执行方式。Arm64 的指令长度固定为 4 字节，而 x86 指令长度可变，大约在 1–15 字节 之间，因此 x86 往往需要更复杂的译码器。相比之下，Arm 的指令更简洁，也更依赖编译器和代码生成阶段对指令的有效组织，所以需要更长的编译时间。&lt;/p&gt;
&lt;p&gt;从工程师可感知的角度来看，还有一些架构差异会直接影响程序行为。&lt;strong&gt;很多在 x86 上看起来符合直觉的代码，在 Arm 上未必如此，后面要讲到的几个容易踩坑的点，基本都与这些底层差异有关&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;其中一个典型问题是原子操作对地址对齐有要求。无论是 LL/SC（Load-Link/Store-Conditional），还是 LSE（Large System Extensions），在执行原子加减等读改写操作时，通常都要求访问地址满足对齐条件。较新的 LSE2 对这一限制有所放宽，开始支持 16-byte window 内的非对齐访问。数据对齐对于 x86 来说不是必须的，但保持良好对齐有助于提升性能。参考文档: &lt;a href="https://developer.arm.com/documentation/ddi0487/maa/-Part-B-The-AArch64-Application-Level-Architecture/-Chapter-B2-The-AArch64-Application-Level-Memory-Model/-B2-8-Alignment-support/-B2-8-2-Alignment-of-data-accesses?lang=en#chdffegj"&gt;Arm Architecture Reference Manual for A-profile architecture&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;另一个需要重点关注的特点是，Arm 采用的是弱内存序模型（weakly ordered / relaxed memory model），差别体现在对内存访问顺序的约束强弱不同。在多线程场景下，同样的读写操作，在 x86 上通常更容易表现为接近程序书写顺序，而在 Arm 上则允许更多重排序，因此其他线程观察到的读写顺序可能与源码顺序不一致。在 Arm 上出现的异常需要特别考虑内存序的影响。更多细节可参考 Arm 白皮书：&lt;a href="https://developer.arm.com/documentation/107630/1-0/?lang=en"&gt;Synchronization Overview and Case Study on Arm Architecture&lt;/a&gt;。&lt;/p&gt;
&lt;h2&gt;02 JuiceFS 与 MLPerf 概述&lt;/h2&gt;
&lt;p&gt;JuiceFS 是一款开源高性能分布式文件系统，基于对象存储构建，在充分利用对象存储低成本优势的同时，提供接近传统文件系统的使用体验。它支持 POSIX、HDFS SDK、Python SDK 以及 S3 兼容接口，并能适配不同类型的应用和数据处理框架；同时支持云原生扩展、数据安全与压缩，可广泛应用于 AI 训练、推理、大数据处理等场景。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;1JuiceFS 架构图.drawio&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 社区版架构图&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;为评估 JuiceFS 在 AI 训练等高负载场景下的数据供给能力，可采用 MLPerf Storage 基准测试。该测试由 MLCommons 开发，重点衡量存储系统能否持续高效向计算侧提供数据。&lt;/p&gt;
&lt;p&gt;2.0 版本将测试分为训练负载和检查点负载两类，其中训练负载包括 3D U-Net、ResNet-50 和 CosmoFlow，三者在样本大小和访问特征上存在显著差异，并设置了最低 GPU 利用率要求：3D U-Net 与 ResNet-50 为 90%，CosmoFlow 为 70%。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;MLPerf Storage 2.0 训练负载&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;MLPerf Storage 2.0 训练负载&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;在测试流程中，数据首先从存储系统读入主机内存，再进入计算阶段。训练耗时由模拟方式复现，以模拟真实训练场景的数据流，从而无需实际部署 GPU，降低实验门槛并提升操作便利性。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;MLPerf Storage 数据流&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;MLPerf Storage 数据流&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;h2&gt;03 MLPerf Storage v2.0 测试原理与调优&lt;/h2&gt;
&lt;p&gt;在介绍具体的模型测试结果之前，需要先了解分布式训练的数据访问原理，有助于读者明白 GPU 利用率、存储吞吐和性能瓶颈的成因，从而更好地理解后续的测试结果和调优策略。&lt;/p&gt;
&lt;p&gt;分布式机器学习通常采用数据并行方式，即多个并行进程共享同一数据集，每个进程分别负责读取和处理对应的训练批次。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;分布式训练数据访问原理示意图&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;分布式训练数据访问原理示意图&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;MLPerf Storage 的训练测试也遵循这一思路，每个训练进程按批次从存储系统读取数据，并通过模拟计算来评估存储系统的持续供数能力。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;MLPerf Storage 训练数据流示意图&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;MLPerf Storage 训练数据流示意图&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;为了理解测试中性能表现的来源，还需要理解 JuiceFS 客户端的数据处理链路。使用 JuiceFS 进行测试时，如图所示，其执行流程大致可分为三部分。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 客户端线程与数据流示意图&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 客户端线程与数据流示意图&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;ul&gt;
&lt;li&gt;左侧：应用侧 I/O 线程，例如 &lt;code&gt;fio&lt;/code&gt; 或 MLPerf Storage 的 &lt;code&gt;DataLoader&lt;/code&gt; 线程，负责发起 &lt;code&gt;read/write&lt;/code&gt; 请求并等待请求完成。  &lt;/li&gt;
&lt;li&gt;中间：FUSE 守护进程中的请求处理主 &lt;code&gt;goroutine&lt;/code&gt;，负责接收并处理来自内核态的 FUSE 请求，将文件数据放入内存缓冲区和缓存，并触发后端元数据与对象存储访问。  &lt;/li&gt;
&lt;li&gt;右侧：Meta client 和 ObjectStore client 的异步 &lt;code&gt;goroutine&lt;/code&gt;，负责与后端 MetaDB 和 ObjectStore 集群进行数据与元数据交互。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;从性能分析的角度看，这条链路需要重点关注两类问题。第一类是数据拷贝，对应图中的 2.1、3、4、5、6 等步骤，这些位置都会带来额外的内存复制开销，因此往往是分析延迟和 CPU 开销时的重点。&lt;/p&gt;
&lt;p&gt;第二类是同步与异步边界。从图中可以看出，1、2、3、4、5、6 这些步骤总体属于同步路径，也就是请求发起后，需要等待当前阶段完成才能继续向下推进；而 7 属于异步路径，由后台 &lt;code&gt;goroutine&lt;/code&gt; 负责与后端存储交互。&lt;/p&gt;
&lt;h3&gt;测试 1：Unet 3d&lt;/h3&gt;
&lt;p&gt;在这个测试中，样本为 146 MiB 的图像文件，我们主要关注大块数据的读取性能。测试结果显示：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;单机环境下最高可稳定运行 5 块 GPU，GPU 利用率约为 50%，  &lt;/li&gt;
&lt;li&gt;而双机场景可支持 10 块 GPU，GPU 利用率同样约为 50%。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为了提升数据读取效率，对训练参数进行了优化：将 &lt;code&gt;reader&lt;/code&gt; 并发线程数从 4 调整为 16，以加快数据生成速度，并将数据读取方式改为 direct I/O，以减少缓冲区和内存拷贝开销。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;业务指标显示，当单机挂载 6 块 GPU 时，GPU 利用率仅为 83%，对应带宽约为 15.1 GB/s，未达到预期的高利用率目标&lt;/strong&gt;。进一步使用 FIO 对存储侧进行测试后发现，其带宽同样约为 15.1 GB/s，&lt;strong&gt;说明此时系统瓶颈已经落在 JuiceFS 客户端带宽 上，而不是 GPU 计算侧本身&lt;/strong&gt;。&lt;/p&gt;
&lt;h4&gt;优化分析 1：绑定 CPU&lt;/h4&gt;
&lt;p&gt;为了深入分析客户端带宽受限的原因，我们对进程进行了 CPU 绑定，将其固定在 CPU1（NUMA 2、3 节点）运行。通过工具观察，48 个 CPU 核心几乎全部占满，进一步分析 top-down、memory 和 miss 指标发现，系统表现出明显 Memory Bound，主要耗时集中在内存拷贝上。这说明，在 CPU 绑定场景下，JuiceFS 性能瓶颈主要来自 CPU 处理能力和跨 NUMA 节点内存拷贝带来的额外延迟。&lt;/p&gt;
&lt;h4&gt;优化分析 2： 不进行 CPU 绑定&lt;/h4&gt;
&lt;p&gt;为了理解系统在更通用条件下的带宽限制，我们进一步观察了不绑定 CPU 的情况。通过观察可以看到，CPU 并未被完全用满，但 devkit tuner numafast 指标显示，系统中的 remote 内存访问比例高达约 80%。这意味着，大量内存访问已经跨越本地 NUMA 节点，甚至可能跨越 CPU socket，从而引入了显著的带宽损失和访问时延。&lt;/p&gt;
&lt;p&gt;从硬件带宽特性看，跨片内存访问本身就存在明显限制。例如，在 Arm 平台上，跨 socket 的理论物理带宽约为 60 GB/s；进一步通过实测，跨片 copy 带宽在 Arm1 上约为 48 GB/s，而在两组 x86 平台上分别约为 37 GB/s 和 28 GB/s。&lt;/p&gt;
&lt;p&gt;这说明，在不绑定 CPU 的情况下，虽然计算核表面上没有被完全耗尽，但大量跨节点、跨 socket 的远端内存访问已经成为新的主要开销来源。因此，可以推测，此时 JuiceFS 带宽无法继续提升，很可能并不是单纯受限于 CPU 算力，而是受限于跨片内存访问的带宽与时延。&lt;strong&gt;换言之，系统瓶颈已经从“本地 CPU 忙不过来”转移为“远端内存访问代价过高”&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;综合来看，在两种场景下，JuiceFS 带宽无法提升的原因并不相同：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;绑定 CPU 时，主要受限于 CPU 资源消耗以及大量内存拷贝带来的访问开销；  &lt;/li&gt;
&lt;li&gt;不绑定 CPU 时，主要受限于高比例 非本地内存访问，尤其可能是跨 socket 访问带来的带宽和时延损失。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;测试 2：Resnet50&lt;/h3&gt;
&lt;p&gt;ResNet-50 测试的单个样本较小，单个样本大小约为 150 KiB，每个 batch 包含 400 个样本，每个 batch 的总数据量约 58.5 MiB。本次 I/O 测试关注 GPU 高并发下的数据加载效率及训练吞吐。测试显示系统可在大规模 GPU 下维持较高利用率：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;单机：50 块 GPU，GPU 利用率 95%，带宽约 9.2 GB/s  &lt;/li&gt;
&lt;li&gt;双机：96 块 GPU，GPU 利用率 90%，带宽约 16.9 GB/s&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在测试过程中，我们将关键参数 &lt;code&gt;reader.read_threads&lt;/code&gt; 从 8 调整为 1，对于该模型（中等大小的图像模型），单线程即可满足数据供给需求。&lt;/p&gt;
&lt;h4&gt;优化分析 1： 单机性能瓶颈与内存带宽影响&lt;/h4&gt;
&lt;p&gt;在单机配置 55 块 GPU 时，GPU 利用率下降至 86%，带宽仍为 9.2 GB/s，表明系统瓶颈已转移至 JuiceFS 客户端带宽。&lt;/p&gt;
&lt;p&gt;进一步分析发现，ResNet-50 测试采用 Buffer I/O 模式，除了读取数据外，处理数据集时的 内存拷贝会消耗一部分内存带宽。&lt;/p&gt;
&lt;p&gt;系统内存拷贝带宽受内存通道数、内存频率及 CPU 频率影响。通过对多台配置不同的机器进行 stream 测试，得到的单机顺序读带宽与系统内存带宽测得的可比带宽一致，&lt;strong&gt;表明读数据吞吐能力在很大程度上取决于系统内存带宽。对于需要高吞吐、高 GPU 利用率的训练任务，建议优先选择内存带宽较高的机型，可显著提升数据供给能力和训练效率&lt;/strong&gt;。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;&lt;/th&gt;
&lt;th style="text-align: left;"&gt;单 CPU 内存拷贝带宽数据&lt;/th&gt;
&lt;th style="text-align: left;"&gt;JuiceFS 单机部署读带宽&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Arm3&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Arm3: 171 GB/s&lt;/td&gt;
&lt;td style="text-align: left;"&gt;25.3 GiB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Arm2&lt;/td&gt;
&lt;td style="text-align: left;"&gt;114 GB/s&lt;/td&gt;
&lt;td style="text-align: left;"&gt;21.6 GiB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;Arm1&lt;/td&gt;
&lt;td style="text-align: left;"&gt;106 GB/s&lt;/td&gt;
&lt;td style="text-align: left;"&gt;18.3 GiB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;x862&lt;/td&gt;
&lt;td style="text-align: left;"&gt;90 GB/s&lt;/td&gt;
&lt;td style="text-align: left;"&gt;17.9 GiB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;x861&lt;/td&gt;
&lt;td style="text-align: left;"&gt;82 GB/s&lt;/td&gt;
&lt;td style="text-align: left;"&gt;16.6 GiB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;优化分析 2：双机扩展瓶颈与分布式限制&lt;/h4&gt;
&lt;p&gt;在多节点部署中，除了单机性能限制外，跨节点内存访问、网络传输和元数据延迟会成为新的瓶颈，因此在单机分析之后进行双机测试，有助于识别这些分布式约束并指导系统优化。&lt;/p&gt;
&lt;p&gt;在双机场景下，理论上可以支持 100 块 GPU，但实际测试中只能达到 96 块 GPU。通过分析发现，每个操作的读取延迟有所增加。尽管文件数据已缓存在本地盘上，元数据访问延迟仍然成为主要限制因素。&lt;/p&gt;
&lt;p&gt;为解决这一问题，对系统进行了多方面优化：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;将 CPU 核心分组，保证训练线程与 I/O 线程在同一 NUMA 节点上运行。  &lt;/li&gt;
&lt;li&gt;将纯数据处理和元数据访问分别分配到不同 CPU 核心和存储路径上。  &lt;/li&gt;
&lt;li&gt;调整 Redis 缓存和本地缓存策略，减少高并发访问元数据时的延迟。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;经过上述调优后，双机场景能够稳定支撑 100 块 GPU 运行，GPU 利用率达到预期水平。&lt;/p&gt;
&lt;h3&gt;测试 3：cosmoflow&lt;/h3&gt;
&lt;p&gt;与之前的模型相比，这个模型的单样本数据量更小，这也意味着对 I/O 和元数据访问的要求更高。在单机和双机场景下，CosmoFlow 测试显示：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;单机：最高稳定 10 块 GPU（偶尔可撑到 12 块 GPU），GPU 利用率约 75%，带宽约 5.6 GB/s  &lt;/li&gt;
&lt;li&gt;关键参数调整：将 &lt;code&gt;reader.read_threads&lt;/code&gt; 从 4 调整为 1，每次读取 batch 数据量为 2 MiB，单线程即可满足数据供给需求。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;优化分析 1：单机瓶颈：内存拷贝限制 GPU 利用率&lt;/h4&gt;
&lt;p&gt;当尝试增加 GPU 数量超过 10 块时，发现 GPU 利用率下降。分析日志和性能数据后发现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;数据读取时间增加，而元数据访问延迟变化不大。  &lt;/li&gt;
&lt;li&gt;文件数据已缓存在本地盘上，磁盘队列未满，延迟也不高，因此瓶颈不在存储设备。  &lt;/li&gt;
&lt;li&gt;使用性能分析工具观察发现，关键瓶颈操作主要集中在 内存拷贝（memcopy），数据读取流程中多次拷贝操作的延迟累积，导致整体读取时间增加。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;由此推测，当系统使用更多内存带宽时，内存拷贝延迟成为限制读取性能和 GPU 利用率的主要因素。&lt;/p&gt;
&lt;h4&gt;优化分析 2：双机瓶颈：分布式同步与元数据延迟&lt;/h4&gt;
&lt;p&gt;在双机场景下，尝试 20 块 GPU 时，第一轮测试 GPU 利用率明显偏低。进一步分析发现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一台机器已开始训练，而另一台机器仍在进行 Dataset 预处理，包括读取文件列表和分片操作。  &lt;/li&gt;
&lt;li&gt;由于 CosmoFlow 数据量较大，高索引文件的读取耗时较长，导致两台机器未能同步开始训练，第一轮 GPU 利用率下降。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为解决该问题，在代码中加入同步机制，确保所有节点在开始训练前完成 Dataset 预处理。经过该调整后，双机测试能够稳定支撑 20 块 GPU，GPU 利用率达到预期水平。&lt;/p&gt;
&lt;h2&gt;04 总结&lt;/h2&gt;
&lt;p&gt;首先，MLPerf Storage 通过不同样本、文件和 batch 大小的组合，考察文件系统的各项能力，包括大中小块顺序读能力、文件并发性能、总读带宽、元数据访问时延、文件读取时延以及文件操作的稳定性。在只读文件场景下，充分利用高速近端缓存（包括原数据和元数据缓存）可以显著提升读取性能。需要注意，文件越小，对 IOPS 和延迟的要求越高。&lt;/p&gt;
&lt;p&gt;其次，我们发现系统的内存和带宽对性能影响显著。在 Memory copy 密集型的应用中，内存拷贝不仅消耗内存带宽，同时也占用 CPU，表面上会出现“CPU 忙”的假象，实际上 CPU 大部分时间是在等待数据。测试结果显示，系统内存带宽对 JuiceFS 的吞吐能力有决定性影响，这也为选择服务器提供了参考标准：内存带宽越高的系统，其存储吞吐性能也越好。&lt;/p&gt;
&lt;p&gt;第三，Go 运行时对 NUMA 的感知有限，对于大规模 CPU 核心运行场景，性能可能不如小规模核心运行。对于多 NUMA 系统，应尽量避免跨 NUMA，尤其是跨 CPU socket 的访问，因为跨 socket 内存带宽通常较低（约几十 GB/s），会增加延迟并影响整体性能。因此，实际部署时只需要分配足够的 CPU 核心即可，无需过度使用全部核心，以避免额外的内存访问延迟。&lt;/p&gt;
&lt;p&gt;第四，在系统层面还有一些潜在优化点。例如，对于 Memory copy 密集的操作，部分 Arm 新系统提供了针对内存访问的指令优化，我们与 Arm 社区合作，将配置提升推送到社区中，新系统可以显著提升内存拷贝效率，在部分场景中带宽提升可达数十个百分点。&lt;/p&gt;
&lt;p&gt;此外，对于涉及大量内核与用户态交互的操作，例如文件读写和元数据处理，可以通过优化用户态与内核态的交互，减少不必要的调用次数，从而降低延迟。实践中也发现，将文件处理尽量集中在同一生产节点内，避免跨 NUMA 或跨 socket 的访问，可以进一步提升性能和稳定性。&lt;/p&gt;
&lt;p&gt;最后，系统配置优化也体现在缓存策略上。例如，在单机高负载场景下，通过调整 JuiceFS 的内存缓存策略，减少无效内存带宽占用，可以有效提高 GPU 利用率和存储吞吐。整体来看，MLPerf Storage Benchmark 是一个系统工程，需要文件系统、内存带宽、CPU 调度和缓存策略等多方面配合，才能达到最优性能。关于此次测试详细信息，可&lt;a href="https://docs.qq.com/doc/DSWZtaFFNYVZVbXRX?nlc=1"&gt;查看文档&lt;/a&gt;。&lt;/p&gt;&lt;/div&gt;</description><pubDate>Fri, 27 Mar 2026 07:05:00 +0000</pubDate><guid>https://www.juicefs.com/zh-cn/blog/engineering/arm-juicefs-performance-optimization-mlperf-tuning</guid></item><item><title>韩国国民搜索 NAVER：使用 JuiceFS 打通 Hadoop 与 Kubernetes 存储实践</title><link>https://www.juicefs.com/zh-cn/blog/user-stories/naver-juicefs-hadoop-kubernetes-storage</link><description>&lt;div class="block-markdown"&gt;&lt;p&gt;NAVER 是韩国领先的互联网科技公司，运营着韩国最大的搜索引擎，并在人工智能、自动驾驶等高科技领域积极布局。作者 Nam Kyung-wan 来自 NAVER Infra 团队，自 2023 年参与 JuiceFS 社区代码贡献 (GitHub: &lt;a href="https://github.com/kyungwan-nam"&gt;kyungwan-nam&lt;/a&gt;)，为 Hadoop 场景提出了多项改进。本文是作者继“ &lt;a href="https://juicefs.com/zh-cn/blog/user-stories/naver-storage-solution-juicefs-ai-platforms"&gt;为 AI 平台引入存储方案 JuiceFS&lt;/a&gt;”后的第二篇博客。&lt;/p&gt;
&lt;p&gt;NAVER Infra 团队负责运营公共 Hadoop 集群，使用 Spark、Hive、MapReduce 等 Hadoop 应用处理数据，并将数据存储在 HDFS 中。HDFS 在 Hadoop 生态系统中通过数据本地性支持高性能，具备优异的容错性和可扩展性。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;随着人工智能服务的普及，数据规模急剧增长，对多样化数据存储的需求也日益增加。同时，如何高效地共享 Hadoop 集群外部 AI 平台（如 Kubernetes）中的数据，成为了一项重要挑战。在这一背景下，NAVER 探讨了对象存储是否可以替代 HDFS，并明确了 JuiceFS 结合对象存储的适用场景&lt;/strong&gt;。&lt;/p&gt;
&lt;h2&gt;01 HDFS 的局限&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;存储成本上升&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;AI 开发需要以高效且经济的方式存储不断增长的数据，并在某些情况下长期保留原始数据，以便进行模型改进和重新训练。&lt;/p&gt;
&lt;p&gt;然而，Hadoop 的计算和存储是紧密耦合的，导致存储扩展难以独立进行。当没有计算需求时，仅为扩展存储空间而增加节点会造成不必要的成本。此外，HDFS 默认保留三重副本，进一步增加了存储成本。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;文件数量限制&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;AI 开发涉及数千万个小文件，如图像、音频和文本等。HDFS 存在著名的&lt;a href="https://www.cloudera.com/blog/technical/the-small-files-problem.html"&gt;小文件问题&lt;/a&gt;，因为所有文件和块的元数据都存储在 NameNode 的内存中。例如，管理 1000 万个文件大约需要 3GB 的内存。因此，HDFS 可管理的文件数量受到单个 NameNode 内存容量的限制。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;数据中心容灾能力弱&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;HDFS 通常由单个数据中心的节点组成。为应对数据中心故障或灾难，需使用额外方案将数据复制到其他数据中心，从而产生增加成本。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;运营成本增加&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;NAVER 由专业人员运营公共 Hadoop 集群，负担相对较小，但通常 Hadoop 集群的构建和运营非常复杂且成本高昂。若要单独构建和运营稳定的 Hadoop 环境，需要专业知识和较高的维护成本。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kubernetes 中的生态兼容性差&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;NAVER AI 平台基于 Kubernetes 构建，并利用 Kubeflow、KServe 等多种 AI 开源工具及 GPU 支持。但 HDFS 不支持 POSIX API 和 CSI 驱动，无法作为 Kubernetes 常规存储方式（即 PersistentVolume）使用。因此，在 Kubernetes 中使用 HDFS 需在容器中准备 Hadoop 包、配置和认证信息，并编写 HDFS API 代码，非常繁琐且会降低 AI 开发效率。&lt;/p&gt;
&lt;h2&gt;02 对象存储的优势与劣势&lt;/h2&gt;
&lt;p&gt;Hadoop 通过数据本地性提供高性能，但由于 HDFS 与计算节点耦合，计算和存储资源难以独立扩展。因此，扩展存储空间时，仍需增加额外的计算节点。&lt;/p&gt;
&lt;p&gt;相比之下，云环境支持计算和存储的独立扩展。通常，数据存储在对象存储中而非 HDFS，计算可以通过托管服务（如 AWS EMR、Google Dataproc）或基于 Kubernetes 的数据处理引擎进行，数据则存储在 S3、GCS 等对象存储中。这种架构支持灵活扩展计算和存储资源。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;n1&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;此外，Hadoop 社区和云供应商提供了 &lt;a href="https://hadoop.apache.org/docs/r3.4.1/hadoop-aws/tools/hadoop-aws/index.html"&gt;S3A&lt;/a&gt;、&lt;a href="https://hadoop.apache.org/docs/r3.4.1/hadoop-azure/index.html"&gt;Azure Blob&lt;/a&gt;、&lt;a href="https://hadoop.apache.org/docs/r3.4.1/hadoop-aliyun/tools/hadoop-aliyun/index.html"&gt;Aliyun OSS&lt;/a&gt; 等 HDFS 兼容文件系统，使得对象存储可以像 HDFS 一样使用。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;n2&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;对象存储作为远程存储，虽然难以实现数据本地性，但具有以下优势：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;存储成本降低&lt;/strong&gt;：计算和存储分离，可独立扩展。对象存储通常成本较低，并能根据需要选择不同的存储类别。例如，对于访问频率低但需长期保留的数据，可使用低成本存储类别（如 S3 Glacier）。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;出色的扩展性和弹性&lt;/strong&gt;：对象存储设计上支持近乎无限的扩展。对象数量和容量无限制，可根据工作负载变化轻松扩展或缩减。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据中心灾难恢复支持&lt;/strong&gt;：S3 等对象存储提供跨区域复制功能，可防止数据中心故障或灾难导致的数据丢失。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;运营成本降低&lt;/strong&gt;：避免 Hadoop 集群的构建和运营负担，从而降低运营成本。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;但对象存储替代 HDFS 是好的选择吗？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不支持目录&lt;/strong&gt;：&lt;br&gt;
在文件系统中，文件通过目录进行组织，列出目录下的文件是一项基本操作，通常速度较快。&lt;br&gt;
而对象存储没有目录的概念，所有对象是独立的扁平结构。列出文件时需要通过对象前缀搜索，速度较慢。此外，为模拟目录结构而临时创建的 Directory Marker 对象也会影响性能。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;n3&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;&lt;strong&gt;不支持重命名&lt;/strong&gt;：&lt;br&gt;
在文件系统中，重命名是基本操作，以 O(1) 级别的原子事务快速执行。但对象存储不支持重命名，需通过复制全部数据再删除原数据的方式处理，导致速度非常慢且可能中途失败。&lt;/p&gt;
&lt;p&gt;这一问题对于 MapReduce 和 Spark 等大数据框架影响尤为明显(&lt;a href="https://hadoop.apache.org/docs/r3.4.1/hadoop-aws/tools/hadoop-aws/committers.html#Introduction:_The_Commit_Problem"&gt;Apache Hadoop Amazon Web Services support – Committing work to S3 with the S3A Committers&lt;/a&gt;)。文件输出操作通常依赖重命名来保证一致性，FileOutputFormatCommitter 就是基于重命名实现的。因此，在对象存储中直接使用 FileOutputFormatCommitter 会显著降低性能。&lt;/p&gt;
&lt;p&gt;为了解决这一问题，可以使用 &lt;a href="https://hadoop.apache.org/docs/r3.4.1/hadoop-aws/tools/hadoop-aws/committers.html#The_Magic_Committer"&gt;Magic Committer&lt;/a&gt;，它避免了重命名操作，并针对对象存储进行了优化。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;n4&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;来源: Improve s3 write performance with magic committer in Spark3&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;不支持文件权限&lt;/strong&gt;：&lt;br&gt;
HDFS 支持 POSIX 权限体系，可以设置文件和目录的所有者、组以及其他用户的权限。而对象存储不提供此功能，因此文件的所有者和组通常被视为当前用户，所有文件和目录的权限默认为 666 和 777（即文件可读写，目录可读写并可执行）(参考: &lt;a href="https://hadoop.apache.org/docs/r3.4.1/hadoop-project-dist/hadoop-common/filesystem/introduction.html#Object_Stores_vs._Filesystems"&gt;Object Stores vs. Filesystems&lt;/a&gt;).。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数据访问速度慢&lt;/strong&gt;：&lt;br&gt;
对象存储作为远程存储，无法保证数据本地性，并且每次访问都涉及网络传输，因此相较于 HDFS，其数据访问速度较慢，性能受到网络延迟和带宽限制的影响。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Kubernetes 中的低可用性&lt;/strong&gt;：&lt;br&gt;
一些工具，如 Mountpoint for Amazon S3 和 s3fs，支持通过 POSIX API 将对象存储挂载为类似本地文件系统的方式。AWS S3 还通过 Mountpoint for Amazon S3 CSI 驱动 支持将对象存储作为 Kubernetes 卷使用。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;然而，由于对象存储与传统文件系统存在根本差异，它无法完全兼容 POSIX API，且性能较低。因此，在使用这些工具时，需要充分了解它们的工作原理和局限性。最终，即使在 Kubernetes 环境中使用对象存储，低可用性问题仍然无法解决。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;S3 兼容对象存储的 API 兼容性&lt;/strong&gt;：&lt;br&gt;
S3 已成为对象存储的事实标准，被多种应用广泛支持。因此，许多云供应商和开源项目提供 S3 兼容对象存储。然而，S3 兼容对象存储并不完全等同于原生 S3 服务。在使用时，需要确认其是否与 S3AFileSystem 或其他应用所使用的 S3 API 兼容。&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;n5&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;综上，对象存储可以像 HDFS 一样使用，但需要充分理解其局限性。现有 Hadoop 应用难以直接迁移，仍需额外的开发和适配工作。对于直接使用 HDFS API 编写的代码，需要避免重命名操作，并减少文件列表操作，以适应对象存储的特性。为避免现有 Spark 应用性能下降，需考虑使用 Magic Committer，但它并非总是有效，特别是在不支持 Spark 动态分区覆盖的情况下。&lt;/p&gt;
&lt;p&gt;此外，虽然 Spark 和 Hadoop 社区持续改进对象存储相关问题，但更新软件包版本和解决问题仍然面临挑战。使用 S3 兼容的对象存储时，还需验证其与 S3 API 的兼容性。&lt;/p&gt;
&lt;h2&gt;03 在 Hadoop 中使用 JuiceFS&lt;/h2&gt;
&lt;p&gt;JuiceFS 是一款分布式文件系统，架构由客户端、元数据引擎和数据存储组成。对象存储仅用于存储数据块，而文件系统所需的元数据则由数据库管理。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;需注意 JuiceFS 是与 HDFS 类似的分布式文件系统。因此，与直接使用对象存储不同，JuiceFS 能完美支持 HDFS API、POSIX API 和 Kubernetes CSI 驱动&lt;/strong&gt;。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 架构图（第四版）-第 2 页-winfsp (2)&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 社区版架构&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;为了在速度慢且修改困难的对象存储上实现分布式文件系统，JuiceFS 引入了 chunk、slice 和 block 概念。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;chunk（64MB）：将文件分割为 64MB 单位，支持基于偏移的并行处理。  &lt;/li&gt;
&lt;li&gt;slice：chunk 内的修改单位，写入时创建新 slice 并优先使用最新版本。  &lt;/li&gt;
&lt;li&gt;block（默认 4MB）：实际存储在对象存储中的最小单位，通过并行处理缩短上传时间。&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;n6&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;来源: JuiceFS Document Center - Architecture&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;此外，从远程对象存储读取数据较慢，JuiceFS 支持多级缓存，以此弥补此性能不足。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;n7&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;来源: JuiceFS Document Center - Cache&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;NAVER 内部 AI 平台已使用 JuiceFS。更多关于 JuiceFS 的详细信息及 AI 平台引入过程可参考&lt;a href="https://juicefs.com/zh-cn/blog/user-stories/naver-storage-solution-juicefs-ai-platforms"&gt;为 AI 平台引入存储方案 JuiceFS&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;JuiceFS 支持 Hadoop SDK，通过配置 JuiceFS 后，用户即可在 Hadoop 环境中使用它。&lt;/p&gt;
&lt;h3&gt;配置 JuiceFS&lt;/h3&gt;
&lt;p&gt;为使 Hadoop 识别 JuiceFS 文件系统，需在 core-site.xml 文件中添加以下内容。其中 &lt;a href="https://juicefs.com/docs/community/hadoop_java_sdk/#core-configurations"&gt;fs.jfs.impl、fs.AbstractFileSystem.jfs.impl 和 juicefs.meta&lt;/a&gt; 是必需的。  &lt;/p&gt;
&lt;pre class="codehilite"&gt;&lt;code class="language-bash"&gt;&amp;lt;!-- Configure JuiceFS to be available via jfs:// --&amp;gt;    
  &amp;lt;property&amp;gt;  
    &amp;lt;name&amp;gt;fs.jfs.impl&amp;lt;/name&amp;gt;  
    &amp;lt;value&amp;gt;io.juicefs.JuiceFileSystem&amp;lt;/value&amp;gt;  
  &amp;lt;/property&amp;gt;  
  &amp;lt;property&amp;gt;  
    &amp;lt;name&amp;gt;fs.AbstractFileSystem.jfs.impl&amp;lt;/name&amp;gt;  
    &amp;lt;value&amp;gt;io.juicefs.JuiceFS&amp;lt;/value&amp;gt;  
  &amp;lt;/property&amp;gt;  
&amp;lt;!-- juicefs meta url --&amp;gt;    
  &amp;lt;property&amp;gt;  
    &amp;lt;name&amp;gt;juicefs.meta&amp;lt;/name&amp;gt;  
    &amp;lt;value&amp;gt;redis://:password@addr&amp;lt;/value&amp;gt;  
  &amp;lt;/property&amp;gt;  
&amp;lt;!-- In this example, grant access permissions to all users to avoid permission issues. --&amp;gt;    
  &amp;lt;property&amp;gt;  
    &amp;lt;name&amp;gt;juicefs.umask&amp;lt;/name&amp;gt;  
    &amp;lt;value&amp;gt;000&amp;lt;/value&amp;gt;  
  &amp;lt;/property&amp;gt;  
&amp;lt;!-- Cache up to 100 GiB. --&amp;gt;    
  &amp;lt;property&amp;gt;  
    &amp;lt;name&amp;gt;juicefs.cache-size&amp;lt;/name&amp;gt;  
    &amp;lt;value&amp;gt;102400&amp;lt;/value&amp;gt;  
  &amp;lt;/property&amp;gt;  
&amp;lt;!-- Cache under the temporary path of YARN containers, so the cache is removed when the container terminates.    
Since it's a shared Hadoop, caching is temporary only during job execution. --&amp;gt;  
  &amp;lt;property&amp;gt;  
    &amp;lt;name&amp;gt;juicefs.cache-dir&amp;lt;/name&amp;gt;  
    &amp;lt;value&amp;gt;${env.PWD}/tmp&amp;lt;/value&amp;gt;  
  &amp;lt;/property&amp;gt;  
&amp;lt;!-- Prometheus remote write configuration for metrics collection --&amp;gt;    
  &amp;lt;property&amp;gt;  
    &amp;lt;name&amp;gt;juicefs.push-remote-write&amp;lt;/name&amp;gt;  
    &amp;lt;value&amp;gt;http://host:port&amp;lt;/value&amp;gt;  
  &amp;lt;/property&amp;gt;  
  &amp;lt;property&amp;gt;  
    &amp;lt;name&amp;gt;juicefs.push-remote-write-auth&amp;lt;/name&amp;gt;  
    &amp;lt;value&amp;gt;username:password&amp;lt;/value&amp;gt;  
  &amp;lt;/property&amp;gt;  
&amp;lt;!-- Additionally collect Hadoop user and YARN container ID.    
For shared Hadoop to distinguish users and applications. --&amp;gt;  
  &amp;lt;property&amp;gt;  
    &amp;lt;name&amp;gt;juicefs.push-labels&amp;lt;/name&amp;gt;  
    &amp;lt;value&amp;gt;user:${env.USER};container_id:${env.CONTAINER_ID}&amp;lt;/value&amp;gt;  
  &amp;lt;/property&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;以上为单文件系统的默认配置，但也可根据需要配置多个文件系统同时使用。&lt;br&gt;
更多配置选项可参考“&lt;a href="https://juicefs.com/docs/community/hadoop_java_sdk/#client-configurations"&gt;客户端配置&lt;/a&gt;”。&lt;/p&gt;
&lt;h3&gt;Hadoop SDK&lt;/h3&gt;
&lt;p&gt;Hadoop SDK 的 JAR 文件可以通过下载预编译客户端或自行编译源代码获取。为了简化部署，通常可以在所有 Hadoop 节点的 Hadoop 发行版安装路径中预先安装。然而，在大规模 Hadoop 集群中，这种方法操作繁琐，尤其是对于公共 Hadoop 环境，它会限制所有用户使用特定版本。&lt;/p&gt;
&lt;p&gt;大多数 Hadoop 应用支持将所需 JAR 文件部署并添加到 classpath 中，用户可根据实际需要选择部署方式。以下是 HDFS CLI、MapReduce 和 Spark 中的具体部署方法。&lt;/p&gt;
&lt;h3&gt;HDFS CLI&lt;/h3&gt;
&lt;p&gt;配置完上述 &lt;code&gt;core-site.xml&lt;/code&gt; 文件后，需要在 &lt;code&gt;HADOOP_CLASSPATH&lt;/code&gt; 环境变量中设置 Hadoop SDK 文件路径。完成此设置后，您可以使用 &lt;code&gt;hdfs&lt;/code&gt; 命令操作 &lt;code&gt;hdfs://&lt;/code&gt; 和 &lt;code&gt;jfs://&lt;/code&gt; 文件系统。&lt;/p&gt;
&lt;pre class="codehilite"&gt;&lt;code class="language-bash"&gt;$ export HADOOP_CLASSPATH=/home/juicefs/juicefs-hadoop-1.2.3.jar  
$ hdfs dfs -ls hdfs://home/foo  
Found 6 items    
...  
drwx------   - foo users          0 2022-10-14 20:55 hdfs://home/foo/.Trash    
drwx------   - foo users          0 2022-01-06 10:18 hdfs://home/foo/dfsio    
drwx------   - foo users          0 2025-01-22 17:54 hdfs://home/foo/tpcds

$ hdfs dfs -ls jfs://default/  
2025-08-25 19:15:43,964 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 60 minutes, Emptier interval = 60 minutes.    
Found 8 items    
...  
drwxrwxrwx   - 10000 hadoop-admins       4096 2025-06-10 18:06 jfs://default/nyc    
drwxrwxrwx   - 10000 hadoop-admins       4096 2025-05-15 19:42 jfs://default/subdir    
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;MapReduce&lt;/h3&gt;
&lt;p&gt;MapReduce 在 Hadoop 的多个节点上并行运行，因此所有分配任务的节点都需要部署 JAR 文件。推荐的方法是通过分布式缓存进行部署。使用此方法时，任务执行时会自动将 &lt;code&gt;mapreduce.application.framework.path&lt;/code&gt; 中设置的 MapReduce 框架部署到任务节点。&lt;/p&gt;
&lt;p&gt;以下是 &lt;code&gt;mapred-site.xml&lt;/code&gt; 文件的示例配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mapreduce.application.framework.path&lt;/code&gt;：指定包含 Hadoop SDK 的 MapReduce 框架的 HDFS 路径。  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;mapreduce.application.classpath&lt;/code&gt;：配置为包含 Hadoop SDK 的路径。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="codehilite"&gt;&lt;code class="language-bash"&gt;&amp;lt;property&amp;gt;  
   &amp;lt;name&amp;gt;mapreduce.application.classpath&amp;lt;/name&amp;gt;  
   &amp;lt;value&amp;gt;$PWD/mr-framework/hadoop/share/hadoop/mapreduce/*:$PWD/mr-framework/hadoop/share/hadoop/mapreduce/lib/*:$PWD/mr-framework/hadoop/share/hadoop/common/*:$PWD/mr-framework/hadoop/share/hadoop/common/lib/*:$PWD/mr-framework/hadoop/share/hadoop/yarn/*:$PWD/mr-framework/hadoop/share/hadoop/yarn/lib/*:$PWD/mr-framework/hadoop/share/hadoop/hdfs/*:$PWD/mr-framework/hadoop/share/hadoop/hdfs/lib/*:$PWD/mr-framework/hadoop/share/hadoop/tools/lib/*&amp;lt;/value&amp;gt;  
 &amp;lt;/property&amp;gt;  
 &amp;lt;property&amp;gt;  
   &amp;lt;name&amp;gt;mapreduce.application.framework.path&amp;lt;/name&amp;gt;  
   &amp;lt;value&amp;gt;hdfs://mapred/framework/hadoop-mapreduce-3.1.2-juicefs-1.2.3.tar.gz#mrframework&amp;lt;/value&amp;gt;  
 &amp;lt;/property&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Spark&lt;/h3&gt;
&lt;p&gt;Spark 的基本配置文件是 &lt;code&gt;spark-defaults.conf&lt;/code&gt;。在该文件中，可以替代 &lt;code&gt;core-site.xml&lt;/code&gt; 进行如下设置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;任意 Hadoop 设置可以通过 &lt;code&gt;spark.hadoop.key=value&lt;/code&gt; 形式添加。  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;spark.jars&lt;/code&gt;：指定要部署到 Spark driver 和 executor，并包含在 classpath 中的 JAR 文件。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="codehilite"&gt;&lt;code class="language-bash"&gt;spark.hadoop.fs.jfs.impl io.juicefs.JuiceFileSystem    
spark.hadoop.fs.AbstractFileSystem.jfs.impl io.juicefs.JuiceFS    
spark.hadoop.juicefs.meta redis://:password@addr    
spark.hadoop.juicefs.umask 000    
spark.hadoop.juicefs.push-remote-write http://host:port    
spark.hadoop.juicefs.push-remote-write-auth username:password    
spark.hadoop.juicefs.push-labels user:${env.USER};container_id:${env.CONTAINER_ID}    
spark.hadoop.juicefs.cache-size 102400    
spark.hadoop.juicefs.cache-dir ${env.PWD}/tmp    
spark.jars hdfs://juicefs/juicefs-hadoop/juicefs-hadoop-1.2.3.jar  
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;04 JuiceFS 改进事项&lt;/h2&gt;
&lt;p&gt;JuiceFS 提供多种接口，支持跨平台的数据共享。例如，在 Hadoop 中使用 MapReduce 或 Spark 处理的数据存储到 JuiceFS 后，可以轻松在 Kubernetes 环境中访问和使用这些数据。&lt;/p&gt;
&lt;p&gt;为使 NAVER 公共 Hadoop 和基于 Kubernetes 的 AI 平台顺畅共享数据，需要进行一些改进。（已经全部贡献到社区版。）&lt;/p&gt;
&lt;h3&gt;&lt;a href="https://github.com/juicedata/juicefs/issues/5394"&gt;支持 all-squash 挂载&lt;/a&gt;（#5394）&lt;/h3&gt;
&lt;p&gt;NAVER 公共 Hadoop 与 LDAP 集成管理用户账户，因此 Hadoop 中创建的数据由相应用户的 LDAP UID 和 GID 所有。然而，在 Kubernetes 中，容器可以使用任意 UID 和 GID 运行，这可能导致访问 Hadoop 创建的数据时产生权限问题。&lt;/p&gt;
&lt;p&gt;为了解决这个问题，我们增加了挂载选项 &lt;code&gt;--all-squash&lt;/code&gt;。该选项使得访问挂载路径时，操作不会以当前账户的 UID 和 GID 进行，而是使用指定的 UID:GID。因此，设置 Hadoop 用户的 LDAP UID 和 GID 后，Kubernetes 中的容器可以无权限问题地访问数据。&lt;/p&gt;
&lt;h3&gt;&lt;a href="https://github.com/juicedata/juicefs/issues/4723"&gt;改进 juicefs.users 和 juicefs.group 设置方式&lt;/a&gt;（#4723）&lt;/h3&gt;
&lt;p&gt;如前所述，在 Hadoop 集群中执行任务时，数据归 Hadoop 用户的 LDAP UID 和 GID 所有。但在 Hadoop 集群外部使用 Hadoop SDK 时，数据归任意 UID 和 GID 所有。例如，在 Docker 容器中使用 HDFS 命令存储数据时，所有者为容器内部账户的 UID 和 GID。&lt;/p&gt;
&lt;p&gt;为了解决这个问题，用户需要通过 &lt;code&gt;juicefs.users&lt;/code&gt; 和 &lt;code&gt;juicefs.groups&lt;/code&gt; 设置指定所需的 UID 和 GID。之前，这要求用户编写 &lt;code&gt;&amp;lt;用户名&amp;gt;:&amp;lt;UID&amp;gt;&lt;/code&gt; 和 &lt;code&gt;&amp;lt;组名&amp;gt;:&amp;lt;GID&amp;gt;&lt;/code&gt; 格式的文件，并设置文件路径，这个过程非常繁琐。现在，我们增加了直接通过配置值来指定 UID 和 GID 的功能，简化了操作。&lt;/p&gt;
&lt;h3&gt;&lt;a href="https://github.com/juicedata/juicefs/issues/6096"&gt;支持 subdir&lt;/a&gt;（#6096）&lt;/h3&gt;
&lt;p&gt;在基于 Kubernetes 的 AI 平台中，JuiceFS 以动态供应方式使用。创建 PersistentVolumeClaim（PVC）时，会在 JuiceFS 文件系统内生成与该卷对应的子目录。若要在 Hadoop 中共享该 PVC，需仅安全地共享该卷对应的目录。&lt;/p&gt;
&lt;p&gt;然而，Hadoop SDK 并不提供类似 &lt;code&gt;--subdir&lt;/code&gt; 的挂载选项，无法限制 Hadoop 仅访问 JuiceFS 的特定子路径。为了解决这个问题，我们在 Hadoop SDK 中增加了 &lt;code&gt;juicefs.subdir&lt;/code&gt; 设置，使用此设置可以限制仅访问指定路径。&lt;/p&gt;
&lt;h3&gt;&lt;a href="https://github.com/juicedata/juicefs/issues/5937"&gt;通过 hdfs 命令查看配额&lt;/a&gt;（#5937）&lt;/h3&gt;
&lt;p&gt;JuiceFS 可以为整个文件系统或特定目录设置配额。在 Kubernetes 中，PVC 的 &lt;code&gt;spec.resources.requests.storage&lt;/code&gt; 值将设置为该目录的配额。&lt;/p&gt;
&lt;p&gt;在 Hadoop 与 PVC 共享时，也需要查看配额信息。然而，原有的 HDFS 命令 &lt;code&gt;hdfs dfs -count -q&lt;/code&gt; 无法查看 JuiceFS 的配额。为了解决这个问题，我们对该功能进行了改进，现在可以通过相同的命令查看 JuiceFS 的配额信息。&lt;/p&gt;
&lt;h3&gt;&lt;a href="https://github.com/juicedata/juicefs/issues/6295"&gt;支持 Prometheus remote_write 协议&lt;/a&gt;（#6295）&lt;/h3&gt;
&lt;p&gt;使用 JuiceFS Hadoop SDK 时，可以将指标发送到 Pushgateway 和 Graphite。但 Pushgateway 需要定期清理指标，且 Graphite 格式独特，使用起来较为困难。&lt;/p&gt;
&lt;p&gt;许多系统支持 Prometheus &lt;code&gt;remote_write&lt;/code&gt; 协议。为了解决这个问题，我们在 JuiceFS 中增加了通过该协议发送指标的功能。通过 &lt;code&gt;juicefs.push-remote-write&lt;/code&gt; 和 &lt;code&gt;juicefs.push-remote-write-auth&lt;/code&gt; 设置，用户可以指定 VictoriaMetrics  &lt;code&gt;vmagent&lt;/code&gt; 或 Prometheus。这一功能不仅整合了跨平台数据，还能整合监控系统。&lt;/p&gt;
&lt;h2&gt;05 JuiceFS 的优势&lt;/h2&gt;
&lt;h3&gt;优势 1：通过并行处理和缓存克服对象存储的性能瓶颈&lt;/h3&gt;
&lt;p&gt;JuiceFS 需要通过网络与远程对象存储交换数据块，因此在性能上难以超越具有数据本地性优势的 HDFS。&lt;strong&gt;然而，通过将数据分块并行处理以及缓存已读取数据，可以克服这一性能瓶颈&lt;/strong&gt;。我们通过性能测试验证了 HDFS 和 JuiceFS 在不同场景下的表现。&lt;/p&gt;
&lt;h4&gt;DFSIO&lt;/h4&gt;
&lt;p&gt;使用 10 个 map task，针对 100GB 文件测量 HDFS 和 JuiceFS 的顺序数据写入和读取的吞吐量。数值越高性能越好。为适应顺序写入/读取，将 JuiceFS 的块大小设为 16MB。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;写入：JuiceFS 的吞吐量是 HDFS 的 1.7 倍。这是因为数据被分割成小块并行上传。  &lt;/li&gt;
&lt;li&gt;读取：JuiceFS 的吞吐量是 HDFS 的 0.75 倍。但如果数据已缓存，预期性能与 HDFS 相似。&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;n8&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;h4&gt;TPC-DS&lt;/h4&gt;
&lt;p&gt;使用 Spark SQL 测量对存储在 HDFS 和 JuiceFS 的 100GB 规模表的查询响应时间。数值越低性能越好。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JuiceFS 的响应时间是 HDFS 的 1.8 倍，这是由于数据本地性差异所致。  &lt;/li&gt;
&lt;li&gt;已缓存的 JuiceFS 表现出与 HDFS 相似的性能。&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;n9&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;h3&gt;优势 2：与 HDFS 完全兼容，无需修改现有 Hadoop 应用即可使用&lt;/h3&gt;
&lt;p&gt;NAVER 拥有稳定运营的公共 Hadoop 集群，运行着多种服务的 Hadoop 应用。如果仅将不常用的数据存储在对象存储中以降低存储成本，可能会出现问题。正如前所述，对象存储不是文件系统，无法保证现有 Hadoop 应用的性能和运行。为此，需要重写代码或检查数据处理引擎是否支持对象存储。此外，还需根据存储类型单独运行和管理 Hadoop 应用，增加了管理负担。&lt;/p&gt;
&lt;p&gt;与之相反，使用 JuiceFS 可以保持现有 Hadoop 应用不变。用户只需将输入输出路径指定为 &lt;code&gt;hdfs://&lt;/code&gt; 或 &lt;code&gt;jfs://&lt;/code&gt;，即可以相同方式运行应用。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;n10&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;HDFS 基于数据本地性保证高性能，而对象存储则在低成本和扩展性方面具有优势。两者各有所长，难以完全替代，需要根据需求选择。使用 JuiceFS 可以在不修改现有 Hadoop 应用的情况下，同时利用 HDFS 和对象存储的优势。&lt;/p&gt;
&lt;h3&gt;优势 3：支持多种接口，可作为跨平台集成存储&lt;/h3&gt;
&lt;p&gt;NAVER 使用多种平台进行服务开发和运营。例如，在开发/运营 AI 服务时，需要在数据处理平台中清洗数据，在 AI 平台中训练模型，并通过容器平台提供服务。&lt;/p&gt;
&lt;p&gt;在 NAVER，各个平台提供独立的存储，平台内部易于使用，但难以访问其他平台的存储。不同平台的存储隔离导致了数据孤岛现象，并容易造成数据重复和资源浪费。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;n11&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;JuiceFS 不仅支持 HDFS，还完美兼容 POSIX 和 Kubernetes CSI 驱动，适合作为跨平台的集成存储。通过在多个平台间顺畅使用 JuiceFS 共享数据，可大幅提升 AI 服务开发效率，实现数据统一管理。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;n12&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;h2&gt;06 结语&lt;/h2&gt;
&lt;p&gt;本文探讨了 JuiceFS 在 Hadoop 环境中的使用方法及其优势，而在部分业务场景下，直接采用 HDFS 或对象存储会是更适配的选择。例如，当业务需要依托数据本地性实现高效快速处理时，建议将数据存储于 HDFS 中；此外，针对访问频率较低的数据，或采用 Iceberg 等专为对象存储优化的数据格式时，直接使用对象存储则更为简便。&lt;/p&gt;
&lt;p&gt;而在以下场景中，JuiceFS 会是更优选择：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;需在 Kubernetes 与 Hadoop 环境之间实现数据共享时；  &lt;/li&gt;
&lt;li&gt;希望在不修改现有 Hadoop 应用代码的前提下，与 HDFS 并行部署使用时；  &lt;/li&gt;
&lt;li&gt;处理存在重复读取行为、可通过缓存显著提升效率的数据作业时；  &lt;/li&gt;
&lt;li&gt;业务所用 S3 API 无法被底层 S3 兼容存储良好支持时。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;本文介绍了在 NAVER 内部本地环境中的应用案例，但在 AWS、Google Cloud 等公有云环境中同样适用。希望对有类似困扰的读者有所帮助。  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;原文链接：https://d2.naver.com/helloworld/5215257&lt;/p&gt;
&lt;/blockquote&gt;&lt;/div&gt;</description><pubDate>Thu, 12 Feb 2026 02:40:00 +0000</pubDate><guid>https://www.juicefs.com/zh-cn/blog/user-stories/naver-juicefs-hadoop-kubernetes-storage</guid></item><item><title>海量小文件 + 多云协同：地瓜机器人 JuiceFS 存储优化之路</title><link>https://www.juicefs.com/zh-cn/blog/user-stories/horizon-robotics-juicefs-small-file-multi-cloud-optimization</link><description>&lt;div class="block-markdown"&gt;&lt;p&gt;地瓜科技成立于 2024 年，由地平线机器人事业部拆分组建，专注于消费级机器人底层计算平台的研发；此外，地瓜科技在 2025 年还发布了具身智能基座模型。&lt;/p&gt;
&lt;p&gt;在机器人数据管理和训练推理中，数据量庞大，使用对象存储时面临小文件、多云数据管理等挑战，在尝试了百度云 BOS、阿里云 CPFS 和将私有 MinIO 替换为 SSD 存储后，方案在应对上述挑战时仍然面临困难。地瓜机器人最终选择了 JuiceFS 作为核心存储解决方案。&lt;/p&gt;
&lt;p&gt;JuiceFS 对跨云业务的天然适配能力，能够高效支持多云环境中的数据共享需求。在训练场景中，JuiceFS 针对小文件数据设计的缓存机制，能够有效替代传统缓存方案，同时在成本和效率之间实现高性价比，完全满足存储性能的需求。目前，地瓜机器人的文件管理规模已达到千万级别。&lt;/p&gt;
&lt;p&gt;本文将详细介绍我们的业务背景、存储痛点、方案选型、落地实践与生产调优经验，希望对同行业的技术实践与方案选型提供参考与借鉴。&lt;/p&gt;
&lt;h2&gt;01 机器人行业的存储痛点&lt;/h2&gt;
&lt;p&gt;云平台作为地瓜机器人的技术核心中枢，承担仿真环境搭建、数据生成与模型训练、模型轻量化部署及可视化验证等关键业务职能。平台所涉及的数据类型多元，主要包括传感器图像数据、激光雷达点云数据、模型权重与配置数据、电机运行数据及地图构建数据等。&lt;/p&gt;
&lt;p&gt;对象存储虽能满足海量数据的基础存储需求，但在机器人业务高频出现的海量小文件处理场景中，性能短板尤为突出。地瓜机器人的存储系统面临四大核心挑战：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;海量小文件的元数据性能瓶颈&lt;/strong&gt;：机器人模型训练环节涉及千万至亿级规模的传感器图像、激光雷达数据与模型文件，传统对象存储（如标准 S3）在处理该规模数据时，元数据操作性能存在显著瓶颈，文件列表检索、属性获取等常规操作的固定 API 延迟通常为 10–30 ms，直接制约训练与推理环节的 QPS 表现，影响整体研发效率。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;多云协同与数据流通效率低下&lt;/strong&gt;：当前机器人企业普遍采用多云架构开展研发与生产业务，如何保障数据在不同云平台及地域间高效同步与共享，成为行业普遍面临的核心问题。传统存储方案跨云数据流通效率偏低，且大多与单一云服务商深度绑定，易形成技术依赖，难以实现灵活的跨云业务部署与数据协同。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;性能、成本与运维的 “不可能三角”&lt;/strong&gt;：高性能并行文件系统可提供高吞吐、低延迟的存储服务，但通常依赖全闪存阵列或专用硬件设备，前期硬件投入与后期运维成本高昂，且部署运维流程复杂。低成本对象存储虽具备良好的弹性扩展能力，却难以支撑 AI 训练场景下 GPU 集群所需的高吞吐 I/O 负载。行业常规方案是将 S3 数据同步至高速文件系统作为缓存使用，但额外的数据同步流程大幅降低业务易用性，无法实现存储与计算的高效协同。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;数据集版本管理困难&lt;/strong&gt;：机器人模型迭代速度快，需对多版本数据集进行高效、精细化管理。若采用物理拷贝的方式实现数据集版本控制，会直接导致底层存储容量成倍消耗，显著推高存储成本，同时多版本数据的检索、复用与维护难度也会大幅上升。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;1云平台&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;地瓜科技云平台架构图&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;h2&gt;02 存储选型：JuiceFS vs. MinIO/S3 vs. PFS&lt;/h2&gt;
&lt;p&gt;为解决上述存储痛点，地瓜机器人确立了明确的选型评估标准，围绕存储架构、协议兼容性、元数据性能、扩展性、多云适配能力、成本效率、运维复杂度七大核心维度，对行业主流存储方案开展全面对比测试。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;选型对比&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;基于上述对比结果，JuiceFS 在核心性能、扩展性、多云适配与成本效率等多个关键维度均展现出显著优势，成为地瓜机器人统一存储解决方案的首选。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;同时，JuiceFS 在智能驾驶领域已实现广泛落地，地平线等行业头部企业已通过 JuiceFS 完成千 PB 级别的数据承载，具备成熟的大规模场景应用经验&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;针对地瓜机器人业务场景，JuiceFS 的核心技术优势主要体现在以下四大方面：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;解耦架构&lt;/strong&gt;：JuiceFS 采用元数据与数据分离的架构设计，将数据持久化存储在低成本对象存储（如 S3、OSS），元数据则托管于 Redis 或 TiKV 等数据库组件。&lt;strong&gt;这种解耦架构实现了存储的弹性扩展，避免对单一云服务商的依赖&lt;/strong&gt;。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分块与缓存机制&lt;/strong&gt;：JuiceFS 使用 Chunk、Slice、Block 三级分块机制，有效提高了小文件读取效率，并提升了并发读写能力。此外，结合多级缓存（内存、本地 SSD、分布式缓存），可降低热数据访问延迟，满足高吞吐训练需求。&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;分快存储&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;云原生适配性&lt;/strong&gt;：通过提供 CSI 驱动，JuiceFS 在 Kubernetes 环境中提供与计算节点解耦的持久化存储，支持容器无状态化部署和跨云迁移。它支持数据共享，提升应用的高可用性和灵活性，并适配多种 Kubernetes 部署方式。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI 训练全链路支持&lt;/strong&gt;：JuiceFS 完整支持 POSIX、HDFS 和 S3 API，兼容主流 AI 框架（如 PyTorch、TensorFlow），无需修改代码即可接入，降低技术门槛。  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;支持多云&lt;/strong&gt;：其跨云能力和高性能元数据引擎确保数据流转高效，完美契合了我们“算力随需而动”的战略。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;从成本维度来看，JuiceFS 在初期小规模部署时成本优势不突出，但当数据规模突破 PB 级，尤其达到 10PB、100PB 级别并与全闪存方案对比时，其依托对象存储的低成本架构优势将全面凸显。此外，JuiceFS 的运维成本极低，地瓜机器人当前仅需一名工程师即可负责整个云平台与存储系统的运维工作，远低于传统方案所需的人员投入。&lt;/p&gt;
&lt;h2&gt;03 从社区版到企业版，应对更大规模场景需求&lt;/h2&gt;
&lt;p&gt;随着业务的不断扩展，我们在使用 Redis 作为元数据引擎时，发现物理内存容量限制了数据的扩展。当文件数量接近亿级时，元数据查询的延迟显著增加，进而影响了训练任务的并发效率。在使用 clone 功能后，元数据的量大幅增加，另外我们在跨云场景中对元数据同步和镜像文件系统的能力提出了更高要求。同时，我们还希望在目录级别进行更细粒度的容量限制和权限管理。&lt;/p&gt;
&lt;p&gt;考虑到这些需求，以及希望利用 GPU 机器本地 SSD 构建分布式缓存层来提升性能，我们决定并行部署 JuiceFS 企业版，将超大规模目录管理、多机协同训练等核心场景迁移至该版本。通过这种场景化拆分，我们有效提升了整体存储系统的适配性，并为未来的业务增长提供坚实的基础。以下是我们在实际场景中应用的企业版关键特性。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;特性 1- 高性能元数据引擎：解决超大规模目录检索瓶颈&lt;/strong&gt;&lt;br&gt;
针对亿级文件目录下的遍历、深分页查询等高频操作，我们曾遇到传统存储方案 “越查越慢” 的问题 —— &lt;strong&gt;单目录文件量突破千万后，分页查询偏移量超过 10 万条时，响应延迟会从百毫秒级飙升至秒级，严重影响数据筛选效率&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;切换至 JuiceFS 企业版后，其元数据的原生目录树形存储架构发挥了关键作用：不同于扁平化 KV 对文件元数据的无序存储，这种树形结构可直接定位目录层级，减少元数据扫描范围。我们实际测试中，单目录 1.2 亿文件的深分页查询（偏移量 50 万条），延迟从原来的 3.8 秒降至 210 毫秒，完全满足大规模数据集的检索需求；同时，该引擎支持单卷千亿级文件存储，目前我们已基于此支撑 3 个 PB 级训练数据集的稳定管理，匹配业务增长预期。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;特性 2- 企业级分布式缓存：提升多机多卡训练数据共享效率&lt;/strong&gt;&lt;br&gt;
在多机多卡训练场景中，我们曾面临 “缓存命中率低、跨节点带宽拥堵” 的问题 —— 开源版仅支持节点本地缓存，当多节点同时拉取同一数据集时，每个节点都需要访问对象存储，导致单节点带宽占用率超过 90%，训练任务启动延迟平均达 20 分钟。借助 JuiceFS 企业版的分布式缓存功能，我们通过 3 行命令在 12 台训练节点组成的局域网内搭建了分布式缓存，数据集只需要从对象存储拉取一次，并缓存在节点本地 SSD 组成的缓存池中。&lt;strong&gt;多机协同训练的缓存命中率从原来的 45% 提升至 92%，跨节点带宽占用率降至 15% 以下，训练任务启动时间缩短至 3 分钟内，大幅提升了算力利用率&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;特性 3- 增强型跨云协同：构建低运维成本的跨云数据底座&lt;/strong&gt;&lt;br&gt;
由于我们的研发环境分布在阿里云、百度云两个平台，此前存在 “跨云数据同步慢、运维成本高” 的痛点 —— 通过传统同步工具实现两地数据一致，需配置 8 个定时任务，同步延迟平均达 4 小时，且需专人每周排查同步失败问题。基于 JuiceFS sync 工具，结合内部 AI 运维工具实现了同步策略自动化配置：系统可根据数据热度自动调整同步优先级，跨云数据延迟控制在 10 分钟内；&lt;strong&gt;同时，同步任务的失败重试、日志告警等均实现自动化，无需专人值守，运维投入减少 70%，目前已稳定支撑两个云平台多个训练项目共享同一套数据集。后续，将使用企业版的镜像文件系统功能来应对跨云数据协同&lt;/strong&gt;。&lt;/p&gt;
&lt;h2&gt;04 JuiceFS 调优攻略&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;客户端缓存与写入性能调优实践&lt;/strong&gt;&lt;br&gt;
需重点关注缓存策略与 Kubernetes 资源限额之间的兼容性问题。如使用内存作为本地缓存路径，配置不合理可能引发 Mount Pod 内存异常增长，或因资源配额预留不足，导致长周期训练任务出现检查点丢失、文件句柄写入异常等情况。&lt;/p&gt;
&lt;p&gt;在写入性能调优方面，开启 writeback 模式可在一定程度上提升小文件写入吞吐，但结合生产环境对数据一致性的要求，我们仍采用 write-through 同步写入模式，以降低极端宕机场景下的数据风险。建议仅在对数据可靠性要求较低的临时计算、离线数据清洗等场景中，根据实际需求谨慎启用 writeback 模式以提升写入效率。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;部署与网络拓扑优化&lt;/strong&gt;&lt;br&gt;
为获得更稳定的性能表现，在部署时强烈建议将元数据引擎与计算节点规划在同一 region 区域内。实际运行中观察到，跨 region 部署会使元数据操作延迟出现数倍至十倍的上升，对数据解压等 I/O 密集型操作的效率影响较为明显。将元数据服务与 GPU 计算资源部署在同一 region 内，有助于在保障性能的同时控制网络传输成本，提升整体资源利用效率。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;数据预热与缓存优化策略&lt;/strong&gt;&lt;br&gt;
在万兆网络环境下，可充分利用 JuiceFS 的数据预热机制，结合业务场景合理调整数据块大小，以更好地发挥网络带宽能力，提升读吞吐量。配合分布式缓存架构，可有效改善多机并发场景下的数据共享效率，提升高并发读取时的缓存命中率，从而优化大规模 AI 训练任务的整体运行表现。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;资源配额与高可用保障策略&lt;/strong&gt;&lt;br&gt;
企业级多角色运维、存储职责分离场景下，为规避配置不一致的运行风险，建议精细化管控 K8s 环境中 JuiceFS CSI 驱动的资源配额。通过合理设置 Mount Pod 的 CPU 与内存 Request/Limit，可减少因资源抢占导致的 Pod 重启或节点异常，实际使用中可根据集群负载动态调整资源预留比例。&lt;/p&gt;
&lt;p&gt;同时，对业务连续性要求较高的场景，可开启 Mount Pod 的挂载点自动恢复功能，实现存储服务的自动化故障恢复，进一步保证底层存储的稳定性。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;多租户实践&lt;/strong&gt;&lt;br&gt;
我们为大型企业客户提供独立文件系统和存储桶，并通过子目录级别的目录隔离和权限管控实现中小型企业客户与终端用户的隔离。大型企业客户可以灵活扩展吞吐量和容量，避免共享存储桶带来的性能瓶颈。对于中小型企业和终端用户，我们通过子目录隔离和权限管控确保数据安全与独立性，同时实现精确计量与计费。这一架构在保障租户隔离的同时，也能灵活调配资源，提高系统管理效率。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;版本管理&lt;/strong&gt;&lt;br&gt;
通过 &lt;code&gt;juicefs clone&lt;/code&gt; 命令，可以快速创建原始数据集的副本，并独立修改，而不影响原数据。克隆操作仅复制文件的元数据，数据则只额外存储变更部分，节省底层存储空间。此功能支持管理多个版本，便于回滚和恢复，确保数据的安全性和版本控制。&lt;/p&gt;
&lt;h2&gt;05 小结与展望&lt;/h2&gt;
&lt;p&gt;JuiceFS 在元数据性能、扩展能力、跨云适配性与综合成本效率等方面的特性，支撑其成为我们构建统一存储层的选择。目前地瓜科技采用 JuiceFS 社区版与企业版并行部署的模式，适配不同业务场景下的差异化存储诉求。&lt;/p&gt;
&lt;p&gt;未来，我们计划将 JuiceFS 进一步落地至具身智能领域，针对性解决该场景下的专属存储需求，包括时序数据高吞吐处理、多模态数据精准对齐、边缘与云端协同存储及仿真与真实场景数据的融合管理等。后续积累更多实践经验后，我们将持续分享具身机器人场景下的存储实践心得。关于 AI 场景的存储实践与技术探索，欢迎评论区一起交流探讨。&lt;/p&gt;&lt;/div&gt;</description><pubDate>Fri, 06 Feb 2026 06:41:58 +0000</pubDate><guid>https://www.juicefs.com/zh-cn/blog/user-stories/horizon-robotics-juicefs-small-file-multi-cloud-optimization</guid></item><item><title>JuiceFS 企业版 5.3 特性详解：单文件系统支持超 5,000 亿文件，首次引入 RDMA</title><link>https://www.juicefs.com/zh-cn/blog/release-notes/juicefs-enterprise-5-3-500b-files-rdma-support</link><description>&lt;div class="block-markdown"&gt;&lt;p&gt;JuiceFS 企业版 5.3 近日发布，单文件系统支持超 5,000 亿文件，实现里程碑式突破。此次升级针对元数据多分区架构进行了多项关键优化，并首次引入 RDMA 技术，以提升分布式缓存效率；此外，5.3 版本还增强了可写镜像，为跨桶导入的对象提供数据缓存等多项功能，旨在支持高性能要求及多云应用场景。&lt;/p&gt;
&lt;p&gt;JuiceFS 企业版专为高性能场景设计。自 2019 年起开始应用于机器学习领域，现已成为 AI 行业核心基础设施之一。商业客户涵盖大模型公司：MiniMax、智谱 AI、阶跃星辰；AI 基础设施及应用如 Fal.ai、HeyGen 等；自动驾驶领域的 Momenta、地平线等，以及众多应用 AI 技术的各行业领先科技企业。&lt;/p&gt;
&lt;h2&gt;01 单文件系统支持超 5,000 亿文件&lt;/h2&gt;
&lt;p&gt;多分区架构是 JuiceFS 应对千亿文件规模的关键技术之一，保证了系统的高扩展性和高并发处理能力。&lt;strong&gt;为了继续满足如自动驾驶场景业务增长的需求，5.3 版本对多分区架构进行了深入优化，将分区数量限制提高到 1,024 个，单文件系统能够存储和访问至少 5,000 亿个文件&lt;/strong&gt;。（每个分区可存储 5 亿个文件，最大支持 20 亿）。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;企业版架构&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 企业版架构图，左下角为单个分区示意图&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;这一突破对系统性能、数据一致性、稳定性要求提出了几何级的难度，背后是一系列繁杂的底层优化与研发工作。&lt;/p&gt;
&lt;h3&gt;关键优化 1 - 分区间热点均衡：自动监测和热点迁移；提供手动运维工具&lt;/h3&gt;
&lt;p&gt;在分布式系统中，热点问题是常见的挑战，特别是当数据被分布到多个分区时，某些分区的负载可能比其他分区更高，这种不均衡会引发热点问题，影响系统的性能。&lt;/p&gt;
&lt;p&gt;当分区数量达到数百时，热点问题变得更加普遍。尤其是在数据集较小、涉及的文件数量较多的情况下，读写热点问题会加剧，进一步增加延迟波动。&lt;/p&gt;
&lt;p&gt;我们引入了自动化的热点迁移机制，将访问频繁的文件迁移到其他分区，从而分担负载并降低特定分区的压力。然而在实际环境中，我们发现仅依赖自动迁移并不能完全解决所有问题。特别是在某些特殊场景或极端情况下，自动迁移工具可能无法及时应对。&lt;strong&gt;因此，我们在自动监测和迁移的基础上，增加了手动运维工具，允许运维人员在遇到复杂场景时介入，进行人工分析并实施优化方案&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;关键优化 2 - 大规模迁移：提升迁移速度，少量多次并发迁移&lt;/h3&gt;
&lt;p&gt;面对热点过高的分区，早期的迁移操作比较简单，但随着系统规模扩大，迁移效率逐渐降低。为此，&lt;strong&gt;我们引入了“少量多次并发迁移”的策略，将高访问量的目录分解成多个小块，并行迁移到多个负载较低的分区&lt;/strong&gt;，从而迅速分散热点，恢复业务的正常访问体验。&lt;/p&gt;
&lt;h3&gt;关键优化 3 - 强化可靠性自检：自动修复与清理迁移中间态文件&lt;/h3&gt;
&lt;p&gt;在大规模集群中，分布式事务的失败概率显著上升，特别是在大量迁移过程中。为应对这一问题，&lt;strong&gt;我们增强了可靠性检测机制，增加了后台周期性的检查功能，定期扫描跨分区文件的状态，特别关注中间状态问题，并自动进行修复和清理&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;此前，系统曾遇到过中间状态数据残留的问题，虽然短期内未影响系统运行，但随着时间推移，这些残留数据可能导致错误。通过增强的自检机制，我们确保了后台能够定期扫描并及时处理中间状态问题，从而提升了系统的稳定性和可靠性。&lt;/p&gt;
&lt;p&gt;除了上述三项关键优化外，我们还在控制台进行了多项改进，以更好地适应更多分区的管理需求。我们优化了并发处理、运维操作和查询展示，提升了整体性能和用户体验。特别是，在 UI 设计方面，我们做了优化，以便更好地展示大规模分区环境下的系统状态。&lt;/p&gt;
&lt;h3&gt;千亿文件性能压测：稳定性与资源利用良好&lt;/h3&gt;
&lt;p&gt;我们在谷歌云上使用自定义的 mdtest 测试工具进行了大规模测试，部署了 60 个节点，每个节点的内存超过 1 TB。在软件配置方面，我们将分区数增加至 1,024 个。部署方式与之前类似，为了降低内存消耗，我们选择仅部署一个服务进程，另两个作为冷备。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;压测&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 企业版 5.3 测试&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;ul&gt;
&lt;li&gt;测试持续时间：大约 20 小时  &lt;/li&gt;
&lt;li&gt;写入的文件总数：约 4,000 亿个文件  &lt;/li&gt;
&lt;li&gt;每秒写入速度：500 万个文件  &lt;/li&gt;
&lt;li&gt;内存占用：约 35% 到 40%  &lt;/li&gt;
&lt;li&gt;硬盘使用： 40% 到 50%，主要用于元数据的持久化，使用情况良好&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;根据我们的经验，如果采用一个服务进程、一个热备进程和一个冷备进程的配置，内存占用会增加 20% 到 30%。&lt;/p&gt;
&lt;p&gt;由于云端资源有限，本次测试只写到 4,000 亿文件。在压测过程中，系统表现稳定，且硬件资源尚有富余。后续，我们会继续尝试更大规模的测试。&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;02 首次支持 RDMA：带宽上限提升，CPU 占用降低&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;在此次新版本中首次支持了 RDMA（Remote Direct Memory Access）技术，它的基本原理架构如下图所示。RDMA 通过允许直接访问远程节点的内存，绕过操作系统的网络协议栈，显著提高了数据传输效率。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;rdma&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;RDMA 原理架构图&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;RDMA 的主要优点包括：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;低延迟：通过直接从内存到内存的传输，绕过操作系统的网络协议层，减少 CPU 的中断和上下文切换，从而降低延迟。  &lt;/li&gt;
&lt;li&gt;高吞吐量：RDMA 通过硬件直接传输数据，能够更好地发挥网卡（NIC）的带宽。  &lt;/li&gt;
&lt;li&gt;减少 CPU 占用：在 RDMA 中，数据的拷贝几乎全部由网卡完成，CPU 仅用于处理控制消息。这样，网卡负责硬件传输，释放了 CPU 的资源。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在 JuiceFS 中，客户端与元数据服务之间的网络请求消息都较小，现有的 TCP 配置已能满足需求。而在分布式缓存中，客户端与缓存节点之间传输的是文件数据，使用 RDMA 可以有效提升传输效率，降低 CPU 消耗。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;网络对比&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;CPU 占用对比：TCP vs RDMA&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;我们使用了 160 Gbps 网卡进行 1MB 随机读测试，比较了 5.1、 5.2（使用 TCP 网络） 和 5.3 版本（RDMA），并观察了 CPU 占用情况。测试表明，RDMA 有效降低了 CPU 占用。在 5.2 版本中，CPU 占用了近 50%；&lt;strong&gt;而在 5.3 版本中，通过 RDMA 优化，CPU 占用降至约 1/3。客户端和缓存节点的 CPU 占用分别降至 8 核和 5 核，带宽达到了 20 GiB/s&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;在以往的测试中，我们发现 TCP 在 200G 网卡下虽然稳定运行，但要完全拉满带宽仍有困难，通常只能达到 85-90% 的带宽利用率。&lt;strong&gt;对于需要更高带宽（如 400G 网卡）的客户，TCP 无法满足需求，而 RDMA 能够更容易地发挥硬件带宽上限，提供更优的传输效率&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;如果用户的硬件支持 RDMA 且存在高带宽需求（如网卡大于 100G），同时希望降低 CPU 占用，那么 RDMA 是值得尝试的技术。目前，我们的 RDMA 功能处于公测阶段，尚未在生产环境中广泛部署。&lt;/p&gt;
&lt;h2&gt;03 可写镜像增强&lt;/h2&gt;
&lt;p&gt;最初，镜像集群主要用于企业产品中的只读镜像。随着用户提出在镜像中写入临时文件（如训练数据）等需求，我们为此提供了可写镜像功能。&lt;/p&gt;&lt;/div&gt;
&lt;div class="block-ImageWithCaption"&gt;&lt;dl&gt;
    &lt;dt&gt;image&lt;/dt&gt;
    &lt;dd&gt;企业版镜像系统&lt;/dd&gt;
    &lt;dt&gt;caption&lt;/dt&gt;
    &lt;dd&gt;JuiceFS 企业版镜像文件系统架构&lt;/dd&gt;
&lt;/dl&gt;&lt;/div&gt;
&lt;div class="block-markdown"&gt;&lt;p&gt;镜像客户端在实现时采用了读写分离机制。客户端在读取数据时优先从镜像集群获取，以降低延迟；而写入数据时，仍然需要写入源集群，以确保数据一致性。通过元数据版本号的记录与对比，我们确保了镜像客户端和源集群客户端看到的数据保持强一致性。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;为了提升可用性，我们在 5.3 版本引入了回退机制，即当镜像不可用时，客户端的读请求能自动回退到源集群&lt;/strong&gt;，从而保证业务连续性，避免镜像集群故障导致的业务中断。我们还优化了多镜像环境的部署。原先，镜像端需要部署两个热备节点以确保高可用性。现在，通过改进的回退功能，部署一个镜像节点也能实现类似的效果，确保业务连续性并降低成本，尤其适用于需要多个镜像的用户。&lt;/p&gt;
&lt;p&gt;通过这一改进，我们不仅降低了硬件成本，还在高可用性和低成本之间找到了平衡。对于那些在多个地点部署镜像的用户，减少元数据副本的同时进一步降低了总体成本。&lt;/p&gt;
&lt;h2&gt;04 简化运维管理，提升灵活性：为导入对象提供跨桶数据缓存&lt;/h2&gt;
&lt;p&gt;在 JuiceFS 中，用户可以使用 import 命令将对象存储中的现有文件导入并统一管理。这对于已经存储大量数据（如几十 PB）的用户来说十分便捷。但在之前版本中，这一功能仅支持为同一数据桶中的对象提供缓存，意味着导入的对象必须与现有文件系统数据处于同一个桶内。这一限制在实际使用中带来了一定局限性。&lt;/p&gt;
&lt;p&gt;在 5.3 版本中，我们对该功能进行了改进。现在，&lt;strong&gt;用户可以为任何导入的对象提供缓存能力，无论这些对象是否来自同一数据桶&lt;/strong&gt;。这样，用户可以更加灵活地管理不同数据桶中的对象，避免了对数据桶的严格限制，从而提升了数据管理的自由度。&lt;/p&gt;
&lt;p&gt;此外，以前如果用户将数据分布在多个桶中，想要为这些桶中的数据提供缓存能力，需要为每个桶新建一个文件系统。而在 5.3 版本中，用户只需创建一个文件系统（volume），便可统一管理多个桶的数据，并为所有桶提供缓存能力。&lt;/p&gt;
&lt;h2&gt;05 其他重要优化&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Trace 功能&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我们新增了 trace 功能，这是 Go 语言本身提供的一个特性。通过这个功能，资深用户可以进行追踪和性能分析，获得更多信息，帮助我们快速定位问题。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;回收站恢复&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在之前的版本中，特别是在多分区的情况下，有时回收站记录的路径不完整，导致恢复时出现异常，未能恢复到预期位置。为了解决这个问题，在 5.3 版本中，在删除文件时，我们会记录文件的原始路径，确保恢复时能够提供更可靠的恢复能力。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Python SDK 改进&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在前几个版本中，我们发布了 Python SDK，它提供了基础的读写功能，方便 Python 用户与我们的系统对接。在 5.3 版本中，我们不仅加强了基础读写功能，还增加了对运维子命令的支持。例如，用户可以直接通过 SDK 调用 juicefs info 或 warmup 等命令，而不需要依赖外部系统命令。这不仅简化了编码工作，并且避免了频繁调用外部命令时可能产生的性能瓶颈。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Windows 客户端&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我们在之前版本中推出了 Windows 客户端 Beta 版本，并已获得不少用户反馈。经过改进，当前版本在挂载的可靠性、性能以及与 Linux 系统的兼容性上都有了显著提升。未来，我们计划进一步完善 Windows 客户端，为依赖 Windows 的用户提供更接近 Linux 的体验。&lt;/p&gt;
&lt;h2&gt;06 小结&lt;/h2&gt;
&lt;p&gt;相较于昂贵的专用硬件，JuiceFS 通过灵活地利用云上或客户现有的存储资源，帮助用户在应对数据增长时平衡性能与成本。在 5.3 版本中，通过优化元数据分区架构，单文件系统可支持超过 5,000 亿个文件。首次引入的 RDMA 技术显著提升了分布式缓存带宽和数据访问效率，减少了 CPU 占用，进一步优化了系统性能。此外，我们还优化了可写镜像、缓存等多项功能，提升了大规模集群的性能和运维效率，优化用户体验。&lt;/p&gt;
&lt;p&gt;云服务用户现已可以直接在线体验 JuiceFS 企业版 5.3，私有部署用户可通过官方渠道获得升级支持。我们将继续专注于高性能存储解决方案，和企业一起应对数据量的持续增长所带来的挑战。&lt;/p&gt;
&lt;p&gt;如果你在存储架构设计、成本控制或性能优化中遇到过问题，或有相关实践心得，欢迎在评论区留言。&lt;/p&gt;&lt;/div&gt;</description><pubDate>Thu, 29 Jan 2026 10:25:33 +0000</pubDate><guid>https://www.juicefs.com/zh-cn/blog/release-notes/juicefs-enterprise-5-3-500b-files-rdma-support</guid></item></channel></rss>