☰
SeaweedFS FUSE 挂载承载数据库工作负载:SQLite / MySQL 持久性与性能基准测试全解析
2026/9/30 1:57:14 网站建设 项目流程
  • 分布式文件系统
  • 对象存储
  • 存储

【免费下载链接】seaweedfs

SeaweedFS is a distributed storage system for object storage (S3), file systems, and Iceberg tables, designed to handle billions of files with O(1) disk access and effortless horizontal scaling.

项目地址:https://gitcode.com/GitHub_Trending/se/seaweedfs
点击查看免费下载

导读

本文基于 test/benchmark/fuse_db 目录下的基准测试套件,完整介绍在 SeaweedFS 的 FUSE 挂载文件系统上运行MySQL(InnoDB)与 SQLite数据库时的两项核心指标:持久性(正常关闭、kill -9意外终止、写入过程中崩溃后,已提交数据是否丢失)与性能(相比本机磁盘的损耗比例)。读完本文,你将掌握这套可复现的基准测试的运行方法、验证机制与源码级实现细节,并理解为什么「小事务 fsync 提交」是 FUSE 文件系统上数据库性能的关键瓶颈。


一、为什么需要这套基准测试

SeaweedFS 的 FUSE 挂载(weed mount)可以把分布式存储以本地文件系统的形态暴露给应用,数据库(如 SQLite、MySQL)可以直接把数据文件放在挂载点上。但用户最关心两个问题:

  1. 持久性(Durability):数据库通过 fsync 提交的数据,在正常关闭、意外kill -9、甚至写入过程中崩溃后,是否真的还在?
  2. 性能(Performance):同样的工作负载(批量导入、OLTP 小事务提交、全表扫描、裸 fsync),跑在 FUSE 挂载上比跑在本机磁盘上慢多少?

这套基准套件用约 1 GB 数据集分别跑 SQLite 和 MySQL,并给出单节点(loopback)环境下可复现的答案。

二、测试设计与数据验证机制

2.1 数据载荷:确定性且不可压缩

为了避免存储层压缩「作弊」(比如全零页被 gzip 后不占实际空间),每条数据行携带:

  • id:自增主键;
  • payload:4 KB 确定性但不可压缩的随机字节(由 id 作为随机种子生成);
  • chk:该 payload 的 CRC32 校验值。

1 GB 数据集 = 262,144 行 × 4,096 字节 payload,这些数据会真实地写入 volume 服务器,而不是被压缩掉。从 sqlite_gen.py 可以看到,载荷由random.Random(i).randbytes(4096)生成——同样算法在验证脚本里可以重新计算并与存储的 CRC 比对。

2.2 验证维度:四重检查

每次崩溃恢复后,验证器(sqlite_verify.py / MySQL 侧的mysql_verify)执行四重检查:

检查项说明
integrity_check/CHECK TABLE数据库结构(B-tree / 页面)是否完好
精确行数与期望值比对(exact 模式)
连续 id 前缀0..count-1 必须连续(atleast 模式)
逐行 CRC 重算每个 payload 重新计算 CRC32 并与存储值比对,检测字节级损坏

2.3 崩溃场景与「可靠下界」设计

持久性套件包含三个场景:

场景做法验证方式
A 正常关闭优雅停 DB → 卸载挂载 → 停集群 → 重启 → 验证exact(一行不能多、不能少)
B 意外终止kill -9同时杀掉 DB、mount、cluster → 重启恢复 → 验证exact
C 写入中崩溃后台持续写入,进度过半时kill -9全部进程 → 重启 → 验证atleast(已提交行必须保留且成连续前缀)

场景 C 的关键是「可靠下界(lower bound)」:加载器每提交一批事务,就把已提交行数原子写入本机磁盘上的进度文件(写临时文件 + fsync + rename,见 sqlite_gen.py 的write_progress),这样崩溃时就知道至少有多少行已经持久提交,重启后验证器要求实际行数 ≥ 该下界且 id 连续——正在写入但未提交的事务可以回滚,但任何已提交的行都不允许丢失。

三、测试环境与基线说明

原文结果基于以下环境(2026-06-15 采集):

  • 单节点;
  • macOS arm64 + macFUSE;
  • weed 4.34;
  • 本机 NVMe 磁盘。

集群以单进程形态运行(weed server同时包含 master + volume + filer),FUSE 挂载通过 loopback 访问 filer。注意:这是单节点 loopback 数字,真实多节点集群(远端 volume、复制)会在每次提交上额外叠加网络 RTT 与副本 fsync。

四、持久性结果:6/6 全部通过

场景说明SQLiteMySQL
A 正常关闭优雅停库、卸载、停集群、重启、验证PASSPASS
B 意外终止(kill -9)kill -9 杀掉 db + mount + cluster,重启恢复验证PASSPASS
C 写入中崩溃加载中途 kill -9,重启恢复,验证已提交前缀PASSPASS

场景 C 验证了正确的恢复行为:正在进行的事务被回滚,所有 fsync 已提交的行以连续前缀的形式完整存活(InnoDB redo 恢复约耗时 9 秒)。

五、性能结果:FUSE vs 本机磁盘

5.1 裸文件系统

指标本机FUSEFUSE 慢多少
顺序写 + fsync2336 MB/s369 MB/s6.3x
顺序读(热缓存)3435 MB/s1422 MB/s2.4x
fsync 延迟0.13 ms1.18 ms9x

对应 fsbench.py 的三项微基准:512 MB 顺序写、500 次「4 KB 随机偏移 pwrite + fsync」、热缓存顺序读。

5.2 SQLite(1 GB,journal=DELETE,synchronous=FULL)

指标本机FUSEFUSE 慢多少
批量导入5.8 s(177 MB/s)11.6 s(88 MB/s)2.0x
OLTP 单行事务1987 tx/s171 tx/s11.6x
全表扫描(热缓存)316 MB/s427 MB/s基本持平(受 Python 瓶颈限制)

5.3 MySQL / InnoDB(1 GB,trx_commit=1,flush_method=fsync)

指标本机FUSEFUSE 慢多少
批量导入24.4 s(42 MB/s)32.9 s(31 MB/s)1.35x
OLTP 单行提交10542 tx/s1144 tx/s9.2x
全表扫描2419 MB/s430 MB/s5.6x

5.4 结论要点

成本主要由 fsync / 提交延迟决定(0.13 ms → 1.18 ms,约 9 倍):每次持久提交都要把 chunk 上传到 volume,并在 loopback 上持久化 filer 的 chunk-manifest。具体表现为:

  • 小 fsync 事务:慢约 9–12 倍;
  • 批量导入(提交被摊薄):慢 1.3–2 倍;
  • 热缓存顺序读:接近本机水平。

六、持久性边界:这套测试测的是什么

需要特别强调的是测试的范围界定:kill -9终止的是进程,而操作系统仍在运行,因此所有已进入 OS page cache 的数据(即所有已 fsync 的数据)都会存活。这忠实地模拟了进程/守护进程崩溃,也正是 6/6 全部通过的原因;但它并不能模拟真正的断电(page cache 随电源一起丢失)。

源码层面的佐证在 weedfs_write.go:FUSE 挂载上传 chunk 时构造的operation.UploadOption不携带 fsync 语义(对照 upload_content.go 中的UploadOption结构体,字段包含Filename、Cipher、IsInputCompressed、WantMd5等,但不存在任何要求 volume 端对.dat做 fsync 的选项)。因此:

  • volume 端不会对每次上传的.dat单独 fsync;
  • filer 端的 leveldb 大概率也不会逐次写同步。

在真实断电场景下,那些只到达 page cache 的「刚提交」数据可能丢失。README 明确指出,在真实硬件上做 VM 硬复位 / 断电测试,是补上这一缺口的后续计划。

七、运行环境要求

  • weed位于$PATH(或通过WEED=/path/to/weed指定);
  • macOS 需要 macFUSE,Linux 需要 libfuse;
  • python3、sqlite3;
  • MySQL/MariaDB 安装,并设置MYSQL_BASE为其安装前缀(macOS Homebrew 默认/opt/homebrew/opt/mysql,目录下需包含bin/mysqld、bin/mysql、bin/mysqladmin;Linux 上如/usr)。对非默认安装路径运行mysql_bench.py时,还需设置MYSQL_BIN=/path/to/mysql。

八、运行方法

运行时的所有产物(集群、挂载、日志)统一放在$SEAWEED_BENCH_WORK目录(默认/tmp/seaweedfs_fuse_db_bench),不会污染仓库:

cd test/benchmark/fuse_db bash bin/run_sqlite.sh > results/sqlite.log 2>&1 # SQLite 持久性套件 bash bin/run_mysql.sh > results/mysql.log 2>&1 # MySQL 持久性套件 bash bin/compare.sh > results/compare.log 2>&1 # FUSE vs 本机性能对比

8.1 隔离与安全设计

测试脚手架通过 lib.sh 只管理自己启动的进程:

  • 使用 pidfile 追踪进程,只在非默认端口运行(master 9555 / volume 9560 / filer 9565、filer gRPC 19565、mysqld 3308);
  • 从不执行pkill weed,机器上运行的其他 SeaweedFS 实例完全不受影响;
  • 提供clean_state彻底清理本次测试状态(只清自己的目录与端口,绝不触碰用户数据)。

8.2 集群与挂载的关键参数

从 lib.sh 可以看到被测集群的启动方式:单进程weed server,-volume.max=50 -master.volumeSizeLimitMB=1024,挂载使用weed mount -dirAutoCreate -cacheDir=...。MySQL 侧固定使用严格持久化配置:innodb_flush_log_at_trx_commit=1、innodb_flush_method=fsync、innodb_doublewrite=ON,确保每次提交都通过 FUSE 层 fsync redo log,从而测出 FUSE 栈对提交路径的真实影响。

九、脚本文件速览

脚本职责
bin/lib.sh集群 / 挂载 / mysqld 生命周期助手(启动、停止、kill、状态清理)
bin/run_sqlite.shSQLite 1 GB 加载 + A/B/C 崩溃场景
bin/run_mysql.shMySQL 1 GB 加载 + A/B/C 崩溃场景
bin/compare.shFUSE vs 本机性能对比驱动(同一磁盘、同样的持久化设置)
bin/sqlite_gen.py确定性不可压缩 SQLite 加载器(带进度 / 参考文件)
bin/sqlite_verify.pySQLite 完整性 + 行数 + 前缀 + 逐行 CRC 验证器
bin/sqlite_bench.pySQLite 加载 / OLTP / 扫描计时探针
bin/mysql_bench.pyMySQL 加载 / OLTP / 扫描计时探针(经 mysql CLI 驱动)
bin/fsbench.py裸顺序写 / fsync 延迟 / 顺序读微基准

9.1 两个值得注意的实现细节

  • SQLite 加载器(sqlite_gen.py)在把synchronous/journal_mode拼进 PRAGMA 前会做白名单校验,拼错参数会直接报错退出,避免在不知情的情况下悄悄削弱持久化设置而让崩溃测试结论失真。
  • MySQL 载荷(run_mysql.sh)用AES_ENCRYPT(REPEAT('a',4080), SHA2(id,256))生成确定性且不可压缩的 4 KB 密文,同一表达式同时生成 payload 与 chk,保证验证端重算的 CRC32 必然等于存储值。

十、复现与基线参考

README 中给出的数据是参考基线:运行输出写入results/*.log,该目录已被仓库级*.loggitignore 规则忽略、不纳入版本控制。重新运行上述脚本即可在本机复现,并对照你自己的硬件(本机磁盘、FUSE 版本、weed 版本)观察损耗比例。

结语

这套基准测试给出了一个清晰、可复现的答案:SeaweedFS FUSE 挂载能安全地承载 SQLite / MySQL 这类数据库(6/6 持久性场景通过,含写入中崩溃恢复),性能损耗集中在 fsync 提交路径上——小事务场景慢约 9–12 倍,批量导入慢 1.3–2 倍,顺序读基本持平。如果你计划把数据库放进 FUSE 挂载,请务必理解这里的断电边界(挂载上传不做 volume 端 fsync),并结合真实集群的网络延迟与副本 fsync 开销做整体评估。

  • 分布式文件系统
  • 对象存储
  • 存储

【免费下载链接】seaweedfs

SeaweedFS is a distributed storage system for object storage (S3), file systems, and Iceberg tables, designed to handle billions of files with O(1) disk access and effortless horizontal scaling.

项目地址:https://gitcode.com/GitHub_Trending/se/seaweedfs
点击查看免费下载
上一篇:Magika代码覆盖率分析:确保测试覆盖所有核心功能
下一篇:DLSS Swapper指南:如何升级或回滚游戏内DLSS/FSR/XeSS

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询