news 2026/9/14 12:38:14

JuiceFS 性能基准测试实战:bench 命令、fio 吞吐测试与 mdtest 元数据 IOPS 评估

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JuiceFS 性能基准测试实战:bench 命令、fio 吞吐测试与 mdtest 元数据 IOPS 评估

JuiceFS 性能基准测试实战:bench 命令、fio 吞吐测试与 mdtest 元数据 IOPS 评估

【免费下载链接】juicefsJuiceFS is a distributed POSIX file system built on top of Redis and S3.项目地址: https://gitcode.com/GitHub_Trending/ju/juicefs

本文以 JuiceFS 官方性能基准文档为主线,讲解如何评估一套分布式文件系统环境的真实性能:先使用内置的juicefs bench子命令快速体检环境,再用 fio 压测顺序读写吞吐,用 mdtest 压测元数据 IOPS,并结合juicefs statsjuicefs profile做性能分析。读完后你应能独立完成一轮 JuiceFS 端到端基准测试,读懂测试工具输出,并依据源码理解每项指标的统计口径。

一、为什么要做基准测试,以及基准测试前的注意事项

JuiceFS 是构建在元数据引擎(如 Redis)与对象存储(如 S3)之上的 POSIX 分布式文件系统。由于最终性能取决于元数据引擎、对象存储、网络带宽、客户端配置等多方因素,官方文档(Performance Benchmark)给出的结论是:在 Redis 作为元数据引擎的条件下进行基准测试,可以定量回答“我的环境配置是否正常”“瓶颈在元数据还是对象存储”这两个问题。

在开始压测前,官方文档特别提示了一个容易踩的坑:

JuiceFS v1.0+ 默认启用回收站(Trash)。基准测试过程中会在文件系统中创建并删除大量临时文件,这些文件最终会落入.trash目录并占用存储空间。为避免该问题,可以在压测前执行juicefs config META-URL --trash-days 0关闭回收站。

这一点在 fio 测试文档 与 mdtest 测试文档 开头均有相同提示。另外,cmd/bench.go中的单元测试(cmd/bench_test.go)也印证了这一点——TestBench在挂载临时测试文件系统时显式传入了--trash-days=0

二、juicefs bench:一条命令完成基础性能体检

bench是 JuiceFS 内置的子命令,用于在目标路径上运行一组基础基准测试,快速验证文件系统在当前环境是否工作正常。其命令定义位于 cmd/bench.go,源码中的命令说明为:

Run basic benchmarks on the target PATH to test if it works as expected. Results are colored with green/yellow/red to indicate whether they are in a normal range. If you see any red value, please double check relevant configuration before further test.

2.1 参数说明

cmd/bench.gocmdBench()函数可以看到完整的参数列表与默认值:

参数默认值说明
PATH必填测试目录(挂载点内的任意目录),实际测试会在其下创建__juicefs_benchmark_<时间戳>__临时目录
--block-size1M每个 IO 块大小(MiB)
--big-file-size1G每个大文件大小(MiB),设为0可跳过大文件测试
--small-file-size128K每个小文件大小(KiB)
--small-file-count100每线程的小文件数量
--threads/-p1并发线程数,官方建议设置为服务器 CPU 核数

基本用法示例(与源码 Description 及 性能评估指南 一致):

# 使用 4 个并发线程运行基准测试 juicefs bench /mnt/jfs -p 4 # 只测试小文件(跳过大文件测试) juicefs bench /mnt/jfs --big-file-size 0

2.2 测试流程(源码级拆解)

从 cmd/bench.go 的bench()函数实现看,整个流程为:

  1. 预检查:解析block-size、文件大小参数,在目标路径下创建带纳秒时间戳的临时目录__juicefs_benchmark_%d__,通过findMountpoint定位所属挂载点;
  2. 清理内核缓存:Linux 下执行echo 3 > /proc/sys/vm/drop_caches,macOS 下执行purge,且非 root 用户会自动加sudo前缀;每一轮大文件写、大文件读、小文件写、小文件读、stat 之间都会再次清理缓存,保证读测试真实命中对象存储/缓存层而不是页缓存;设置环境变量SKIP_DROP_CACHES=true可跳过该操作(单测即以此方式运行);
  3. 运行基准(N 为--threads的并发数):
    • N 并发写:每线程一个 1 GiB 大文件,IO 尺寸 1 MiB(writeFiles,按block-size分块随机数据utils.RandRead填充后循环fp.Write);
    • N 并发读:读回刚写的大文件(readFiles);
    • N 并发写:每线程 100 个 128 KiB 小文件;
    • N 并发读:读回 100 个小文件;
    • N 并发 stat:对 100 个小文件逐个os.Stat
  4. 清理与报告rm -rf删除临时目录(Windows 用rd /s /q),打印结果表格,并输出测试期间的耗时、CPU 占用、内存用量。

并发通过sync.WaitGroup+ goroutine 实现(见benchCase.run()),每线程写入的文件命名为{bigfile|smallfile}.{线程号}.{序号},天然避免线程间文件竞争。

2.3 如何解读结果:红黄绿三色机制

bench的输出为三列表格:ITEM(测试项)、VALUE(吞吐/每秒文件数/每秒操作数)、COST(每文件或每操作耗时)。源码 cmd/bench.go 中预置了resultRange阈值表,每项指标对应[min, max, cost_min, cost_max]四个界:

var resultRange = map[string][4]float64{ "bigwr": {100, 200, 10, 50}, // 大文件写吞吐 MiB/s "bigrd": {100, 200, 10, 50}, // 大文件读吞吐 MiB/s "smallwr": {12.5, 20, 50, 80}, // 小文件写 files/s "smallrd": {50, 100, 10, 20}, // 小文件读 files/s "stat": {20, 1000, 1, 5}, // stat files/s "fuse": {0, 0, 0.5, 2}, // FUSE 操作 ms/op "meta": {0, 0, 2, 5}, // 元数据事务 ms/op "put": {0, 0, 100, 200}, // 对象 PUT ms/op "get": {0, 0, 100, 200}, // 对象 GET ms/op "delete": {0, 0, 30, 100}, // 对象 DELETE ms/op "cachewr": {0, 0, 10, 20}, // 写缓存 ms/op "cacherd": {0, 0, 1, 5}, // 读缓存 ms/op }

判色逻辑(colorize()):吞吐量高于max为绿色、介于minmax之间为黄色、低于min为红色;延迟低于cost_min为绿色、高于cost_max为红色。对smallwr/smallrd/stat三项,吞吐量阈值会乘以线程数bm.threads,即并发越多,期望吞吐按比例放大。出现红色指标时应先检查相关配置(网络、元数据引擎距离、对象存储带宽、max-uploads等),再决定是否继续后续测试。

2.4 深入项:从 Prometheus 指标拆解 FUSE/元数据/对象存储延迟

当目标路径是 JuiceFS 挂载点时,bench会在测试前后两次调用readStats(mp)抓取 Prometheus 指标,用差值计算以下七项延迟(对应源码中show()的调用):

报告项底层指标
FUSE operationfuse_ops_durations_histogram_seconds
Update metatransaction_durations_histogram_seconds
Put / Get / Delete objectobject_request_durations_histogram_seconds_PUT/_GET/_DELETE
Write into cache / Read from cacheblockcache_write_hist_seconds/blockcache_read_hist_seconds

这使得一次bench不仅能给出端到端吞吐,还能定位慢在哪一层:FUSE 层(内核交互与客户端开销)、元数据事务、对象存储请求,还是本地块缓存。此外,元数据引擎基准文档 展示了同一张表在 Redis、MySQL、PostgreSQL、TiKV、etcd、FoundationDB 六种元数据引擎下的实测对比——例如大文件写吞吐各家均在 730~746 MiB/s 区间(对象存储成为瓶颈),而Stat file在 Redis 下约 12000 files/s,MySQL 下约 3583 files/s,直观体现了元数据引擎对元数据密集负载的影响。

三、fio 顺序读写吞吐测试

官方基准使用 fio(版本 3.1)在 JuiceFS、Amazon EFS 与 S3FS 三者之间做顺序读写吞吐对比。完整的测试方案、命令与环境见 docs/en/benchmark/fio.md,此处完整保留其测试命令:

顺序读(单任务)

fio --name=sequential-read --directory=/s3fs --rw=read --refill_buffers --bs=4M --size=4G fio --name=sequential-read --directory=/efs --rw=read --refill_buffers --bs=4M --size=4G fio --name=sequential-read --directory=/jfs --rw=read --refill_buffers --bs=4M --size=4G

顺序写(单任务,测试结束 fsync)

fio --name=sequential-write --directory=/s3fs --rw=write --refill_buffers --bs=4M --size=4G --end_fsync=1 fio --name=sequential-write --directory=/efs --rw=write --refill_buffers --bs=4M --size=4G --end_fsync=1 fio --name=sequential-write --directory=/jfs --rw=write --refill_buffers --bs=4M --size=4G --end_fsync=1

16 任务并发顺序读/写:在上述命令基础上追加--numjobs=16(写测试保留--end_fsync=1),用于考察多客户端/多线程并发下的聚合吞吐。

3.1 测试环境

三组测试均在 EC2 c5d.18xlarge 实例(72 vCPU,144 GiB 内存)+ Ubuntu 18.04 LTS(Kernel 5.4.0)上执行:

  • JuiceFS 使用本地 Redis 4.0.9 存储元数据,挂载命令为:
./juicefs format --storage=s3 --bucket=https://<BUCKET>.s3.<REGION>.amazonaws.com localhost benchmark ./juicefs mount --max-uploads=150 --io-retries=20 localhost /jfs

其中--max-uploads--io-retries是 JuiceFS 挂载级参数(定义见 cmd/flags.go,在 cmd/mount.go 中分别映射到conf.MaxUploadconf.Retries):前者控制并发的上传任务数上限,直接影响大块写入对象存储的并发带宽;后者控制 IO 失败重试次数,影响弱网下的稳定性。

  • EFS 使用 NFS v4.1 挂载(rsize/wsize=1048576,hard,timeo=600,retrans=2,noresvport);
  • S3FS 使用 1.82 版本,通过passwd_file提供凭证。

3.2 测试结果

官方结论:在该环境(Redis 元数据 + S3 对象存储 + 大规格 EC2 客户端)下,JuiceFS 的顺序读写吞吐约为 EFS 与 S3FS 的 10 倍:

需要说明该结论的适用前提:测试客户端是 72 vCPU / 144 GiB 的大规格实例且对象存储带宽充足,小规格实例或带宽受限环境下三者差距会缩小。性能评估指南 同时提示:大文件顺序吞吐是 JuiceFS 的优势项,但小文件写入性能相对一般,因为每个文件都要持久化到对象存储,而对象存储 API 调用通常有 10~30ms 的固定开销。该指南还给出了更贴近日常使用的 fio 参数说明(--ioengine=libaio--direct=1关闭系统缓冲使结果更稳定等)以及随机读写示例,可直接复用:

# 顺序写(libaio + O_DIRECT) fio --name=jfs-test --directory=/mnt/jfs --ioengine=libaio --rw=write --bs=1m --size=1g --numjobs=4 --direct=1 --group_reporting # 随机读 fio --name=jfs-test --directory=/mnt/jfs --ioengine=libaio --rw=randread --bs=1m --size=1g --numjobs=4 --direct=1 --group_reporting

四、mdtest 元数据 IOPS 测试

元数据操作(create / stat / unlink 等)是分布式文件系统与本地文件系统差异最大的部分。官方基准使用 HPC 社区的 mdtest(3.4 版本)在 JuiceFS、EFS、S3FS 之间对比元数据 IOPS,完整方案见 docs/en/benchmark/mdtest.md。为控制在 5 分钟内跑完,参数做了相应调整:

./mdtest -d /s3fs/mdtest -b 6 -I 8 -z 2 ./mdtest -d /efs/mdtest -b 6 -I 8 -z 4 ./mdtest -d /jfs/mdtest -b 6 -I 8 -z 4

测试环境为 EC2 c5.large(2 vCPU,4 GiB),Redis 4.0.9 运行在同可用区的 c5.large 实例上。JuiceFS 侧仅两条命令:

./juicefs format --storage=s3 --bucket=https://<BUCKET>.s3.<REGION>.amazonaws.com localhost benchmark nohup ./juicefs mount localhost /jfs &

官方结论:JuiceFS 的元数据 IOPS 显著高于 EFS 与 S3FS:

4.1 官方原始输出摘录

mdtest 文档 保留了三者的完整 SUMMARY rate(ops/sec,均值,单任务)。关键对比行:

操作S3FSEFSJuiceFS
Directory creation5.977192.3011416.582
Directory stat435.8981311.1663810.083
File creation5.696179.2931410.288
File stat68.692915.2305023.227
File read(open/close)33.931371.0123487.947
File removal23.658217.4981163.371

从数字量级看,该次测试中 JuiceFS 元数据速率约为 EFS 的 7~8 倍、S3FS 的 20~70 倍(不同操作倍数不一)。注意 S3FS 的-z 2与其余两者的-z 4不同,即 S3FS 测试的目录树更浅、文件数更少(344 个 vs 12440 个),对比时以相对量级而非绝对值为准。

4.2 仓库内置的元数据压测命令juicefs mdtest

除外部 mdtest 工具外,JuiceFS 源码中还内置了一个直接压测元数据引擎的子命令(cmd/mdtest.go,标记为Hidden,不进入主帮助列表),其用法为:

juicefs mdtest redis://localhost /test1

参数包括--threads(默认 1)、--dirs(默认 3,子目录数)、--depth(默认 2,目录树层级)、--files(默认 10,文件数)、--write(写入字节数,默认 0 即只测纯元数据)。从runTest()的实现看,它会先构建目录树并统计 dirs/s,再以多线程createFile递归创建文件并统计 files/s;当--write大于 0 时,还会通过meta.NewSlice+m.Write真实写入 chunk 数据。这意味着可以直接对元数据引擎做脱离客户端 FUSE 层的裸压测,适合在多节点环境下评估元数据引擎的扩展能力——元数据引擎基准文档 中的并行 mdtest 测试正是用mpirun -np 12在 3 个客户端节点上执行:

# 纯元数据 mpirun --use-hwthread-cpus --allow-run-as-root -np 12 --hostfile myhost --map-by slot /root/mdtest -b 3 -z 1 -I 100 -u -d /mnt/jfs # 12000 个 100KiB 小文件 mpirun --use-hwthread-cpus --allow-run-as-root -np 12 --hostfile myhost --map-by slot /root/mdtest -F -w 102400 -I 1000 -z 0 -u -d /mnt/jfs

五、性能分析:stats 与 profile 工具

当基准测试暴露出性能问题时,官方基准文档指向实时性能监控章节。性能评估指南 给出了两个配套工具的标准用法:

5.1juicefs stats:实时指标观测

类似 Linux 的dstat,在juicefs bench运行期间另开一个会话执行:

juicefs stats /mnt/jfs --verbosity 1

即可实时看到客户端吞吐、缓存命中、元数据延迟等指标变化,与 bench 的测试流程(大文件写 → 大文件读 → 小文件读写 → stat)对照着看,能直接判断当前处于哪一阶段、瓶颈在哪一层。

5.2juicefs profile:访问日志回放统计

.accesslog是 JuiceFS 挂载点内的一个虚拟文件,只有被读取(如cat)时才会产生日志:

cat /mnt/jfs/.accesslog > juicefs.accesslog # Ctrl+C 停止后: juicefs profile juicefs.accesslog --interval 0

--interval 0表示快速回放整个日志文件生成统计。官方指南中给出了一个非常有助于理解调用链的推算:默认参数下 bench 共创建(1 + 100) × 4 = 404个文件,每个文件经历 Create → Write → Close → Open → Read → Close → Delete 全流程,因此应有 404 次 create/open/unlink、808 次 flush(close 自动触发)、以及 33168 次 write/read 请求——因为 FUSE 层单次请求默认最大 128 KiB,1 GiB 大文件按 1 MiB 应用层 IO 拆成 8 个 FUSE 请求,(1024 × 8 + 100) × 4 = 33168。这与 profile 统计完全吻合。指南还指出write平均延迟极低(约 45 μs)的原因:JuiceFS 默认先把写入放进内存缓冲,close 时再经 flush 上传对象存储。

六、测试后端对象存储:juicefs objbench

文件系统级测试只能看到“组合性能”,要评估对象存储本身是否配得上 JuiceFS(带宽是否够、功能是否齐全),可用内置的 objbench 子命令单独压测对象存储端:

juicefs objbench \ --storage s3 \ --access-key myAccessKey \ --secret-key mySecretKey \ https://mybucket.s3.us-east-2.amazonaws.com

从源码看,objbench先执行 15 项功能测试(建桶、上传/下载对象、Range 读、HEAD、DELETE、List、分片上传、chown、chmod、修改 mtime 等,不支持的功能标记为not support),再执行 10 项性能测试(上传/下载小对象并校验内容、分片上传大对象、并发 List、并发取元信息/改 mtime/改权限/删除等)。可调参数包括--threads/-p(默认 4)、--block-size(默认 4M)、--big-object-size(默认 1G)、--small-object-size(默认 128K)、--small-objects(默认 100)、--shards(按 key 哈希分桶)以及--skip-functional-tests。测试结果中任何一项failed都提示该对象存储与 JuiceFS 的兼容性存在问题。

七、把基准测试组织成可复现的评估流程

综合以上文档,一个可落地的完整流程是:

  1. 明确场景(参照 性能评估指南):应用类型(Spark / PyTorch / 自研程序)、所需 CPU/内存/网络规格、数据规模(文件数与总容量)、文件粒度与访问模式(大/小文件,顺序/随机)、量化指标(吞吐、QPS、延迟);
  2. 关闭回收站juicefs config META-URL --trash-days 0
  3. 快速体检juicefs bench /mnt/jfs -p <CPU核数>,红黄绿三色定位异常项;
  4. 定位分层瓶颈juicefs stats实时观测 +juicefs profile回放.accesslog
  5. 专项压测
    • 吞吐 → fio(顺序/随机,--direct=1,多numjobs);
    • 元数据 → 外部 mdtest(含 mpirun 多节点)或内置juicefs mdtest META-URL PATH
    • 对象存储后端 →juicefs objbench
    • 元数据引擎选型 → 参照 元数据引擎基准 的同环境对比方法(Golang Benchmark、bench、mdtest、fio 四件套)。
  6. 记录结论:测试场景、参数、环境(客户端/元数据/对象存储规格)、结果与异常,形成可回溯的评估报告。

官方各篇文档中的绝对数值(如“10 倍于 EFS/S3FS”、各引擎对比倍数)均基于特定测试环境(实例规格、网络、Redis 版本、对象存储区域),复现时请以自身环境实测为准,上述数值可用作量级参考与回归对比的基线。

【免费下载链接】juicefsJuiceFS is a distributed POSIX file system built on top of Redis and S3.项目地址: https://gitcode.com/GitHub_Trending/ju/juicefs

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 12:35:04

WeChatMsg:微信聊天记录导出|免费完整使用指南

WeChatMsg&#xff1a;微信聊天记录导出&#xff5c;免费完整使用指南 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/W…

作者头像 李华
网站建设 2026/9/14 12:34:50

Unity跨平台开发踩坑实录:数字孪生项目从PC到VR的完整复盘

做 Unity 软件开发这两年&#xff0c;踩过的坑比我之前做 Web 前端三年加起来都多。尤其这次这个项目&#xff0c;从 UI 交互、渲染阴影、WebGL 打包到串口通信、XR 设备适配全过了一遍&#xff0c;很多东西回过头看特别想记下来。这篇文章就是一个完整的项目记录&#xff0c;把…

作者头像 李华
网站建设 2026/9/14 12:34:37

SpringBoot 3 + Vue 3 校园社团管理系统实战

简介&#xff1a;这是一套面向Java与前端初学者的全栈实践项目&#xff0c;聚焦校园社团管理场景&#xff0c;帮助开发者掌握SpringBoot后端开发与Vue前端框架的协同应用。资源包含133个文件&#xff0c;主体为55个Java源码&#xff08;涵盖TeamsService、NoticesController等核…

作者头像 李华
网站建设 2026/9/14 12:31:58

Canvas+SVG协同实现水泡分裂动画:双图层分工与状态机设计

简介&#xff1a;一份基于HTML5 Canvas与SVG的彩色水泡分裂动画特效源码&#xff0c;代码量虽小却完整实现了从绘制到交互的动画链路&#xff0c;非常适合前端学习者、动画爱好者及Web交互视觉工程师用来研究两种图形技术的配合方式。压缩包本身只有3KB&#xff0c;没有多余文件…

作者头像 李华
网站建设 2026/9/14 12:30:57

STM32CubeIDE驱动ST7735S:从SPI初始化到DMA刷屏完整指南

简介&#xff1a;这是基于STM32CubeIDE非常详细地从零开始驱动ST7735S液晶屏的完整资料包&#xff0c;面向嵌入式初学者及需要快速点亮LCD显示界面的开发者。屏幕采用的驱动芯片为ST7735S&#xff0c;属于1.8英寸TFT全彩屏&#xff0c;通过SPI接口通信&#xff0c;分辨率128乘以…

作者头像 李华