JuiceFS 元数据引擎性能测试:Redis、MySQL、TiKV、etcd 等六种引擎的基准对比与实战方法

发布时间:2026/9/14 21:42:24
JuiceFS 元数据引擎性能测试:Redis、MySQL、TiKV、etcd 等六种引擎的基准对比与实战方法 JuiceFS 元数据引擎性能测试Redis、MySQL、TiKV、etcd 等六种引擎的基准对比与实战方法【免费下载链接】juicefsJuiceFS is a distributed POSIX file system built on top of Redis and S3.项目地址: https://gitcode.com/GitHub_Trending/ju/juicefsJuiceFS 采用数据与元数据分离的存储架构元数据可以存放在 Redis、MySQL、PostgreSQL、TiKV、etcd、FoundationDB 等多种数据库引擎中不同引擎在纯元数据操作、小文件读写与大文件流式读写场景下的性能差异显著。本文基于 JuiceFS 官方在亚马逊云真实环境中对六种元数据引擎含 Redis 的两种持久化配置所做的系统性基准测试完整呈现测试环境、测试工具与全部测试数据并结合仓库源码pkg/meta/benchmarks_test.go、cmd/bench.go说明每类指标的含义与复现方法。读完本文你将掌握如何根据业务负载特点选择元数据引擎以及如何使用 Go 基准测试、juicefs bench、mdtest、fio 等工具评估元数据层的性能。结论先行不同引擎的定位差异先给出本次测试的核心结论便于快速把握选型方向纯元数据操作如 mkdir、create、rename、getattr 等MySQL 的耗时约为 Redis 的 24 倍TiKV 性能与 MySQL 接近在大部分场景下略优于 MySQLetcd 的耗时约为 TiKV 的 1.5 倍。小 IO约 100 KiB压力小文件创建/读写/删除使用 MySQL 引擎的操作总耗时大约是使用 Redis 引擎总耗时的 13 倍TiKV 和 etcd 的耗时与 MySQL 接近。大 IO约 4 MiB压力大文件顺序读写使用不同元数据引擎的总耗时未见明显差异——此时对象存储S3已成为瓶颈元数据引擎不再是性能短板。需要注意的两个前提条件Redis 可以通过将appendfsync配置项由always改为everysec牺牲少量可靠性来换取一定的性能提升该配置是 Redis 持久化策略的一部分always表示每个写命令都同步刷盘everysec表示每秒批量刷盘一次。测试中 Redis 和 MySQL 的数据均只在本地存储单副本而 TiKV 和 etcd 的数据会在三个节点间通过 Raft 协议存储三副本。也就是说TiKV/etcd 是在三倍写放大和跨节点同步的代价下达到接近甚至优于 MySQL 的表现这一点在横向对比时值得留意。以下测试均运行在相同的对象存储用来存放数据、相同的客户端和元数据节点上只有元数据引擎不同从而保证差异完全由元数据引擎引入。测试环境JuiceFS 版本本次测试使用的 JuiceFS 版本为1.1.0-beta12023-06-08.5ef17ba0。对象存储Amazon S3仅用于存放文件数据数据面元数据全部由被测引擎承载。客户端节点机型Amazon c5.xlarge4 vCPUs8 GiB 内存最高 10 Gigabit 网络操作系统Ubuntu 20.04.1 LTS元数据节点机型Amazon c5d.xlarge4 vCPUs8 GiB 内存最高 10 Gigabit 网络100 GB SSD为元数据引擎提供本地存储操作系统Ubuntu 20.04.1 LTSSSD 数据盘被格式化为 ext4 文件系统并挂载到/data目录所有引擎的数据都落在这块本地盘上保证 I/O 能力一致各元数据引擎的版本与配置引擎版本关键配置Redis7.0.9appendonly: yesappendfsync分别测试always和everysec两种取值dir: /data/redisMySQL8.0.25/var/lib/mysql目录被绑定挂载到/data/mysqlPostgreSQL15.3数据目录被更改到/data/pgdataTiKV6.5.3deploy_dir: /data/tikv-deploydata_dir: /data/tikv-dataetcd3.3.25data-dir: /data/etcdFoundationDB6.3.23data-dir: /data/fdb可以看出测试刻意把所有引擎的数据目录统一放置在/data本地 SSD下以消除底层磁盘差异对结果的影响。关于这些引擎在 JuiceFS 中的接入方式与 META-URL 格式可参考 docs/zh_cn/reference/how_to_set_up_metadata_engine.md。测试工具四类基准的定位与用法每种元数据引擎都会完整运行以下所有测试测试覆盖面从纯元数据接口到端到端文件读写。Golang Benchmark元数据接口级的微基准JuiceFS 源码中提供了简单的元数据基准测试pkg/meta/benchmarks_test.go。它直接以Meta接口为被测对象绕过 FUSE 和网络协议栈最能反映元数据引擎本身的原始性能。从源码结构看测试用例被组织为五个分组见 pkg/meta/benchmarks_test.go#L578-L631benchmarkDir目录操作包括mkdir、mvdir重命名目录、rmdir、resolve、readdir_10目录含 10 个条目、readdir_1k目录含 1000 个条目benchmarkFile文件操作包括mknod、create、rename、unlink、lookup、getattr、setattr、accessbenchmarkXattr扩展属性操作包括setxattr、getxattr、removexattr、listxattr_1、listxattr_10benchmarkLink链接操作包括link、symlinkbenchmarkData数据切片操作包括newchunk分配 slice、write、read_1、read_10读取包含 1 / 10 个 slice 的元数据。每个基准都遵循 Go testing 的标准模式先通过prepareParent准备父目录、ResetTimer清零计时然后在循环中反复执行单一元数据操作如 benchMkdir 中不断调用m.Mkdir创建d0、d1……。入口函数则通过NewClient见 pkg/meta/interface.go#L640-L669按协议头选择引擎例如BenchmarkRedis使用redis://127.0.0.1/1地址BenchmarkSQL使用sqlite3://BenchmarkTKV使用badger://。测试者只需替换元数据地址即可对任意已注册的引擎redis、mysql、postgres、tikv、etcd、fdb等执行同一套基准这保证了引擎间对比的公平性。JuiceFS Bench端到端的单机基准JuiceFS 提供了一个基础的性能测试命令juicefs bench /mnt/jfs -p 4该命令在挂载点/mnt/jfs上执行-p 4表示 4 个并发线程其完整实现见 cmd/bench.go。执行流程为各线程并发写/读 1 GiB 大文件IO 大小 1 MiB、写/读 128 KiB 小文件、对小文件执行 stat最后清理临时目录测试前后还会尝试清空内核页缓存Linux 下向/proc/sys/vm/drop_caches写入 3以避免缓存干扰结果。命令支持以下参数见 cmd/bench.go#L55-L83参数默认值说明--block-size1M每次 IO 块大小--big-file-size1G大文件大小设为 0 可跳过此项--small-file-size128K小文件大小设为 0 可跳过此项--small-file-count100每个线程创建的小文件数量--threads/-p1并发线程数结果以表格形式输出ITEM测试项、VALUE每秒处理能力与COST每个文件/操作耗时并会额外读取挂载点指标给出 FUSE 操作与元数据事务的平均耗时见 cmd/bench.go#L442-L481 中的FUSE operation、Update meta等统计项。juicefs bench更完整的背景说明与与其他存储的对比可参见 docs/zh_cn/benchmark/performance_evaluation_guide.md。mdtest多客户端并发元数据压力测试版本mdtest-3.3.0在 3 个客户端节点上并发执行测试主机文件如下$ cat myhost client1 slots4 client2 slots4 client3 slots4meta only纯元数据操作创建 12000 个空目录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/jfs12000 × 100 KiB 小文件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两轮测试分别考察「空文件的目录/文件创建、stat、删除、整树创建/删除」与「小文件写入后再 stat、读取、删除」两类场景并通过 3 节点 × 4 槽位共 12 个进程制造真实的多客户端并发压力。fio大块顺序写压力版本fio-3.28fio --namebig-write --directory/mnt/jfs --rwwrite --refill_buffers --bs4M --size4G --numjobs4 --end_fsync1 --group_reporting该任务以 4 MiB 块大小、4 个作业并发写入 4 GiB 数据并在结束时执行fsync用于衡量大 IO 场景下「元数据引擎 对象存储」全链路的表现。fio 的更多单机/多机测试配置可参考 docs/zh_cn/benchmark/performance_evaluation_guide.md。测试结果详解Golang Benchmark元数据接口原始耗时下表展示了各操作的单次耗时单位为微秒/op数值越小越好括号内数字是该指标对比 Redis-Always 的倍数always和everysec均是 Redis 配置项appendfsync的可选值。由于元数据缓存缘故目前Read接口测试数据均小于 1 微秒暂无对比意义。Redis-AlwaysRedis-EverysecMySQLPostgreSQLTiKVetcdFoundationDBmkdir558468 (0.8)2042 (3.7)1076 (1.9)1237 (2.2)1916 (3.4)1842 (3.3)mvdir693621 (0.9)2693 (3.9)1459 (2.1)1414 (2.0)2486 (3.6)1895 (2.7)rmdir717648 (0.9)3050 (4.3)1697 (2.4)1641 (2.3)2980 (4.2)2088 (2.9)readdir_10280288 (1.0)1350 (4.8)1098 (3.9)995 (3.6)1757 (6.3)1744 (6.2)readdir_1k14901547 (1.0)18779 (12.6)18414 (12.4)5834 (3.9)15809 (10.6)15276 (10.3)mknod562464 (0.8)1547 (2.8)849 (1.5)1211 (2.2)1838 (3.3)1763 (3.1)create570455 (0.8)1570 (2.8)844 (1.5)1209 (2.1)1849 (3.2)1761 (3.1)rename728627 (0.9)2735 (3.8)1478 (2.0)1419 (1.9)2445 (3.4)1911 (2.6)unlink658567 (0.9)2365 (3.6)1280 (1.9)1443 (2.2)2461 (3.7)1940 (2.9)lookup173178 (1.0)557 (3.2)375 (2.2)608 (3.5)1054 (6.1)1029 (5.9)getattr8786 (1.0)530 (6.1)350 (4.0)306 (3.5)536 (6.2)504 (5.8)setattr471345 (0.7)1029 (2.2)571 (1.2)1001 (2.1)1279 (2.7)1596 (3.4)access8789 (1.0)518 (6.0)356 (4.1)307 (3.5)534 (6.1)526 (6.0)setxattr393262 (0.7)992 (2.5)534 (1.4)800 (2.0)717 (1.8)1300 (3.3)getxattr8487 (1.0)494 (5.9)333 (4.0)303 (3.6)529 (6.3)511 (6.1)removexattr21596 (0.4)697 (3.2)385 (1.8)1007 (4.7)1336 (6.2)1597 (7.4)listxattr_18587 (1.0)516 (6.1)342 (4.0)303 (3.6)531 (6.2)515 (6.1)listxattr_108791 (1.0)561 (6.4)383 (4.4)322 (3.7)565 (6.5)529 (6.1)link680545 (0.8)2435 (3.6)1375 (2.0)1732 (2.5)3058 (4.5)2402 (3.5)symlink580448 (0.8)1785 (3.1)954 (1.6)1224 (2.1)1897 (3.3)1764 (3.0)newchunk00 (0.0)1 (0.0)1 (0.0)1 (0.0)1 (0.0)2 (0.0)write553369 (0.7)2352 (4.3)1183 (2.1)1573 (2.8)1788 (3.2)1747 (3.2)read_100 (0.0)0 (0.0)0 (0.0)0 (0.0)0 (0.0)0 (0.0)read_1000 (0.0)0 (0.0)0 (0.0)0 (0.0)0 (0.0)0 (0.0)解读要点Redis 依然是纯元数据操作的最快选择且把appendfsync从always改为everysec后绝大多数写类操作mkdir、create、write、removexattr 等都能获得约 20%60% 的提速代价仅是崩溃时可能丢失最近一秒的写命令。PostgreSQL 是关系型数据库中元数据接口性能最好的多数操作耗时约为 Redis 的 1.22.4 倍MySQL 次之约为 Redis 的 2.24.3 倍。readdir_1k单目录 1000 个条目是差异最大的操作MySQL 和 PostgreSQL 耗时达到 Redis 的 12 倍以上约 18.8 msTiKV 仅需约 3.9 倍5.8 ms。这意味着如果业务存在大量大目录列举关系型数据库需要承担显著更高的元数据延迟。TiKV 整体表现均衡绝大多数操作约为 Redis 的 23.9 倍且在三副本 Raft 同步的前提下仍优于多数单副本关系型引擎适合对可用性有要求的分布式部署。etcd 与 FoundationDB 的纯元数据耗时普遍位于 Redis 的 36 倍区间与 TiKV 相比也存在约 1.31.5 倍的差距。JuiceFS Bench端到端吞吐下表为挂载点层面的端到端测试结果写/读大文件与 stat 均为越高越好FUSE 操作与更新元数据为越低越好Redis-AlwaysRedis-EverysecMySQLPostgreSQLTiKVetcdFoundationDBWrite big file730.84 MiB/s731.93 MiB/s729.00 MiB/s744.47 MiB/s730.01 MiB/s746.07 MiB/s744.70 MiB/sRead big file923.98 MiB/s892.99 MiB/s905.93 MiB/s895.88 MiB/s918.19 MiB/s939.63 MiB/s948.81 MiB/sWrite small file95.20 files/s109.10 files/s82.30 files/s86.40 files/s101.20 files/s95.80 files/s94.60 files/sRead small file1242.80 files/s937.30 files/s752.40 files/s1857.90 files/s681.50 files/s1229.10 files/s1301.40 files/sStat file12313.80 files/s11989.50 files/s3583.10 files/s7845.80 files/s4211.20 files/s2836.60 files/s3400.00 files/sFUSE operation0.41 ms/op0.40 ms/op0.46 ms/op0.44 ms/op0.41 ms/op0.41 ms/op0.44 ms/opUpdate meta2.45 ms/op1.76 ms/op2.46 ms/op1.78 ms/op3.76 ms/op3.40 ms/op2.87 ms/op解读要点大文件读写1 GiB各引擎几乎打平写约 730 MiB/s、读约 900 MiB/s验证了「大 IO 下对象存储成为瓶颈、元数据引擎无关紧要」的结论此处带宽受限于 c5.xlarge 的 10 Gbps 网络与 S3 吞吐。Stat file 是元数据敏感度最高的指标Redis 可达约 1.2 万 files/sMySQL/etcd/FoundationDB 仅约 28003600 files/s相差约 34 倍。小文件写吞吐约 80110 files/s在所有引擎上都远低于 stat/读因为每个小文件都涉及一次对象存储 PUT 调用固定网络开销元数据引擎的差异被部分掩盖小文件读则波动较大PostgreSQL 出现 1857.90 files/s 的高值可能受缓存命中影响建议结合多次重复测试观察。Update meta元数据事务耗时项中 Redis-Everysec 与 PostgreSQL 最优约 1.8 ms/opTiKV/etcd 因三副本同步而偏高约 3.43.8 ms/op。mdtest多客户端并发元数据压力下表展示了操作速率每秒 OPS 数数值越大越好Redis-AlwaysRedis-EverysecMySQLPostgreSQLTiKVetcdFoundationDBEMPTY FILESDirectory creation4901.3429990.0291252.4214091.9344041.3041910.7683065.578Directory stat289992.466379692.5769359.27869384.09749465.2236500.17817746.670Directory removal5131.61410356.293902.0771254.8903210.5181450.8422460.604File creation5472.6289984.8241326.6134726.5824053.6101801.9562908.526File stat288951.216253218.5589135.571233148.25250432.6586276.78714939.411File read64560.14860861.3978445.95320013.02718411.2809094.62711087.931File removal6084.79112221.0831073.0633961.8553742.2691648.7342214.311Tree creation80.12183.54634.42061.93777.87556.29974.982Tree removal218.53595.59942.33044.696114.41476.00264.036SMALL FILESFile creation295.067312.182275.588289.627307.121275.578263.487File stat54069.82752800.1088760.70919841.72814076.2148214.31810009.670File read62341.56857998.3984639.57119244.67823376.7335477.7546533.787File removal5615.01811573.4151061.6003907.7403411.6631024.4211750.613Tree creation57.86057.08023.72352.62144.59019.99811.243Tree removal96.75665.27923.22719.51127.61617.86810.571解读要点空文件场景EMPTY FILES最能拉开引擎差距Redis-Everysec 的目录/文件创建速率高达约 1 万 OPS是 MySQL约 1300 OPS的 78 倍目录/文件 stat 更是达到约 25 万38 万 OPS依赖元数据缓存而 MySQL/etcd 仅约 60009000 OPS差距达数十倍。在空文件场景下Redis 的everysec配置全面优于always创建类操作速率几乎翻倍这与 Golang Benchmark 中写操作耗时的下降相互印证。小文件场景SMALL FILES中引擎差异被大幅压缩文件创建速率各引擎均在 260312 OPS 区间因为每个文件创建后都要写数据到 S3对象存储成为主要瓶颈但 stat 与 read 仍呈现明显分层Redis/PostgreSQL 领先MySQL/etcd 靠后。PostgreSQL 在空文件 stat23.3 万 OPS上表现突出仅次于 RedisTiKV 则在整个 mdtest 中保持稳定中上水平。fio大块顺序写Redis-AlwaysRedis-EverysecMySQLPostgreSQLTiKVetcdFoundationDBWrite bandwidth729 MiB/s737 MiB/s736 MiB/s768 MiB/s731 MiB/s738 MiB/s745 MiB/s4 MiB 块、4 并发、4 GiB 总量的顺序写测试中各引擎的写带宽落在 729768 MiB/s 的狭窄区间内再次印证「大 IO 场景下元数据引擎不构成瓶颈吞吐由对象存储决定」的结论。结果综合分析如何为你的场景选型将四类测试结果汇总可以得出以下选型参考追求极限元数据性能高 QPS、海量小文件、频繁目录操作优先选择 Redis。appendfsync建议按可靠性需求在everysec与always之间权衡。注意 Redis 是内存型引擎元数据需占内存可按约300 字节/文件估算用量键值数据库的粗略估算值详见 docs/zh_cn/reference/how_to_set_up_metadata_engine.md 中的元数据存储用量章节同时为保证元数据安全需要设置maxmemory-policy noeviction。希望使用事务型关系型数据库且已有 MySQL/PostgreSQL 运维体系PostgreSQL 在元数据接口延迟与 stat 吞吐上明显优于 MySQL是关系型引擎中的首选MySQL 则胜在生态成熟、云厂商托管服务普及。关系型数据库的单文件元数据开销可按约600 字节/文件估算。需要分布式高可用三副本且对元数据性能要求较高TiKV 在几乎所有指标上接近甚至略优于 MySQL且通过 Raft 提供多副本容错是从单机 Redis/MySQL 向分布式演进时值得重点评估的引擎。etcd、FoundationDB在本次测试环境下纯元数据性能偏弱etcd 约为 TiKV 的 1.5 倍耗时更适合对性能不敏感、但需要对应数据库生态能力如 Kubernetes 生态自带 etcd的场景FoundationDB 还需自行编译带 FDB 支持的 JuiceFS 客户端。此外无论选择哪种引擎都建议在正式压测前关闭回收站避免基准测试创建/删除的临时文件被转存到.trash占用空间即执行juicefs config META-URL --trash-days 0详见 docs/zh_cn/security/trash.md。复现测试的注意事项若要在自己的环境复现本文数据建议遵循以下原则保证结果可比较、可解释保持数据面一致所有引擎共用同一对象存储、同一挂载点和同一批客户端只更换 META-URL这是隔离元数据引擎差异的前提。消除存储介质差异将各引擎的数据目录放置在同一块本地 SSD 上如本文统一放在挂载于/data的 ext4 盘避免不同磁盘性能干扰结论。区分引擎的副本策略单副本引擎Redis、MySQL与三副本引擎TiKV、etcd的可靠性模型不同对比性能时应把副本数作为背景信息说明。分层解读数据用 Golang Benchmark 观察引擎的接口级原始性能用juicefs bench与 mdtest 观察端到端与多客户端并发表现用 fio 大块写确认对象存储瓶颈任何单一工具都无法完整刻画元数据引擎的优劣。注意缓存与持久化配置元数据缓存会显著压低读类操作耗时如本文中Read接口小于 1 微秒appendfsync等持久化选项也会直接改变写性能复现时应明确记录这些配置。元数据引擎的完整接入方式META-URL 格式、TLS 配置、各引擎的创建与挂载命令参见 docs/zh_cn/reference/how_to_set_up_metadata_engine.mdjuicefs bench的更多用法与 Fio、Vdbench 的多机测试配置参见 docs/zh_cn/benchmark/performance_evaluation_guide.md元数据基准测试的源码实现见 pkg/meta/benchmarks_test.go 与 cmd/bench.go。【免费下载链接】juicefsJuiceFS is a distributed POSIX file system built on top of Redis and S3.项目地址: https://gitcode.com/GitHub_Trending/ju/juicefs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考