news 2026/10/15 2:12:28

goofys 在 Azure Blob Storage 上的基准测试:环境、方法、结果与实现解读

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
goofys 在 Azure Blob Storage 上的基准测试:环境、方法、结果与实现解读
  • 存储

【免费下载链接】goofys

a high-performance, POSIX-ish Amazon S3 file system written in Go

项目地址:https://gitcode.com/gh_mirrors/go/goofys
点击查看免费下载

本文基于 goofys 仓库中的 Azure 基准测试文档 与配套的 原始测试数据,完整还原 goofys 挂载 Azure Blob Storage 时的性能评估全过程:测试跑在什么硬件与地域、如何用一条 Docker 命令复现、benchmark 覆盖哪些文件系统操作、goofys 与 blobfuse 的实测耗时对比,以及这些测试指标背后的脚本实现和 goofys 的 Azure 后端源码。读完本文,你将能独立复跑该基准测试,并理解每一条测试指标的真实含义。

测试环境与前提

文档明确给出了本次 Azure 基准测试的硬件与网络前提,这是理解所有数据的先决条件:

  • 计算实例:Standard DS4 v2(Azure 通用型虚拟机,8 vCPU / 28 GiB 内存级别);
  • 部署地域:West US,被测 bucket 同样位于West US,即客户端与服务端同地域,网络延迟处于较低水平;
  • 计时单位:秒(units are seconds);
  • 对照组:blobfuse(Azure 官方 FUSE 客户端),文档特别注明blobfuse 的缓存目录会被清空,用于模拟冷读场景,确保双方读取路径尽量对等。

也就是说,该基准测试比较的是“同一地域、同规格机器”下 goofys 与 blobfuse 作为用户态 FUSE 文件系统访问同一 Azure 容器的端到端耗时,而非底层 API 的纯带宽测试。

一键复现:运行 Azure 基准测试

文档给出了完整的复现命令。基准测试以 Docker 镜像形式分发(镜像构建过程见 bench/Dockerfile.azure,入口脚本为 bench/run_bench.sh):

$ export AZURE_STORAGE_ACCOUNT=myaccount $ export AZURE_STORAGE_KEY=STORAGE-ACCESS-KEY $ sudo docker run -e BUCKET=$TESTBUCKET -e AZURE_STORAGE_ACCOUNT=$AZURE_STORAGE_ACCOUNT -e AZURE_STORAGE_KEY=$AZURE_STORAGE_KEY --rm --privileged --net=host -v /mnt/cache:/tmp/cache kahing/goofys-bench:azure-latest # result will be written to $TESTBUCKET

各参数含义与作用如下:

参数含义
AZURE_STORAGE_ACCOUNTAzure 存储账户名,goofys 通过它定位账户并解析出 Blob 服务端点(见 conf_azure.go 的AzureBlobConfig逻辑)
AZURE_STORAGE_KEY存储账户的访问密钥(Storage Access Key),用于 SharedKey 签名
BUCKET被测容器(container)名,运行结束后结果文件会被回写到该容器
--privileged授予容器挂载 FUSE 所需的权限(如访问/dev/fuse、执行fusermount)
--net=host复用宿主机网络,避免容器 NAT 带来的网络性能偏差
-v /mnt/cache:/tmp/cache将宿主机/mnt/cache映射为容器内/tmp/cache,该目录被用作 blobfuse 的临时缓存路径与 goofys/catfs 的数据缓存目录
--rm测试结束后自动清理容器

容器内 run_bench.sh 会依次完成:启动挂载进程 → 运行各轮测试 → 收集bench.goofys、bench.blobfuse、bench.data、bench.png等结果文件 → 通过 goofys 自身把结果写回$TESTBUCKET容器。

从 run_bench.sh 的源码可以看出,脚本支持以下可调环境变量,便于控制测试范围与深度:

变量默认值作用
BUCKETgoofys-bench被测容器名
FASTfalse设为true时每个测试只迭代 1 次,且 1GB 大文件降为 100MB,用于快速验证
CACHEfalse设为true时启用磁盘缓存(goofys 使用--cache /tmp/cache),可额外生成缓存模式下的图表
ENDPOINThttp://s3-us-west-2.amazonaws.com/S3 模式下的端点;Azure 模式下会被置空并由 goofys 自动探测

基准测试指标设计

所有指标都由 bench/bench.sh 定义。该脚本接受<mount cmd> <dir> [test name]三个参数,test name决定运行哪一组操作。核心指标及其底层实现如下:

指标实现方式(对应 bench.sh 函数)测量内容
create_filesecho $i > file$i循环 100 次顺序创建 100 个文件的端到端耗时
create_files_parallel100 个(echo ... &)后台并行创建并行创建 100 个文件的耗时
rm_files/rm_files_parallelrm file$i顺序 / 并行删除删除 100 个文件的耗时
write_md5openssl enc -aes-256-ctr生成随机流,经tee同时写largefile(默认 1GB)并计算 md5写入 1GB 数据的耗时,同时保留 md5 供后续校验
read_md5md5sum largefile并比对写入时记录的MD5读取 1GB 数据并校验完整性的耗时
read_first_bytedd if=largefile of=/dev/null bs=1 count=1 iflag=nocache冷启动场景下读到第一个字节的延迟(反映对象存储流式读的响应速度)
ls_filesls -1 --color=always \| wc -l,先并行创建 2000 个文件含 1000+ 文件的目录ls耗时
find_filesfind \| wc -l,先并行创建 9×9×9 的目录树(共 820 个文件/目录)递归遍历目录树的耗时

脚本还保证了测量环境的“公平性”:

  • 每轮测试前执行drop_cache,即echo 3 > /proc/sys/vm/drop_caches,清空操作系统页面缓存(bench.sh 第 124-128 行);
  • CACHE=false时每次测试前清空/tmp/cache;
  • 对 blobfuse 采取更严格的隔离:每轮测试前卸载并重新挂载 blobfuse,彻底清空其缓存(第 141-152 行),这正是文档中“cache directory is cleared to simulate cold read”的来源;
  • 默认iter=10,即每个指标重复 10 轮取统计量;TRAVIS或FAST模式下降为 1 轮。

read_md5会校验读取数据的 md5 与写入时一致,不一致则报错退出,因此读测试结果同时验证了数据完整性,并非单纯计时。

结果数据:goofys vs blobfuse

文档引用 bench/azure/bench.data 中的汇总数据(由 10 轮原始记录经异常值过滤后统计得到)。以下是该文件完整数据的整理(单位:秒):

操作goofys 均值(min/max)blobfuse 均值(min/max)
Create 100 files2.67(2.52 / 2.80)4.40(4.31 / 4.52)
Create 100 files (parallel)0.54(0.51 / 0.63)2.12(2.05 / 2.17)
Unlink 100 files1.33(1.24 / 1.42)2.47(2.38 / 2.57)
Unlink 100 files (parallel)1.29(1.15 / 1.46)2.36(2.19 / 2.56)
ls with 1000 files0.53(0.50 / 0.57)0.39(0.26 / 1.25)
findwith 1000 dirs/files2.06(1.81 / 2.41)3.31(2.87 / 4.17)
Write 1GB3.84(3.72 / 3.95)6.58(6.36 / 6.72)
Read 1GB4.86(4.71 / 4.97)5.46(5.15 / 5.97)
Time to 1st byte0.13(0.10 / 0.16)3.15(2.92 / 3.94)

(表中数据均来自 bench/azure/bench.data,10 轮样本的均值与 min/max 范围;原始逐轮记录见 bench/azure/bench.goofys 与 bench/azure/bench.blobfuse。)

从本次测试结果可以客观观察到几组关键差异:

  1. 元数据操作(create/unlink):goofys 在顺序与并行场景下均快于 blobfuse,其中并行创建 100 个文件差距最明显(0.54s vs 2.12s)。这与 goofys “尽可能少的 API 调用、重读时补齐属性”的设计取向一致。
  2. 大文件读写(Write/Read 1GB):goofys 写入 1GB 约 3.84s,blobfuse 约 6.58s;读取约 4.86s vs 5.46s,差距小于写入。
  3. 首字节延迟(Time to 1st byte):goofys 平均 0.13s,blobfuse 平均 3.15s,是本次测试中差距最大的单项。这反映了冷读场景下从发起读取到数据到达用户态缓冲的响应速度。
  4. ls单项例外:1000 文件的目录列举中 blobfuse 均值(0.39s)略快于 goofys(0.53s),但其 min/max 波动极大(0.26s~1.25s),而 goofys 稳定在 0.50s~0.57s 区间。单项均值不构成整体结论,且该数据仅代表本次单机单地域测试,不应外推为普适性能结论。

基准测试结果图

下图即为 Azure 基准测试文档 中引用的官方结果图(由 bench_graph.gnuplot 渲染,三个分段面板分别展示不同耗时量级的操作):

该图由 bench_format.py 输出的汇总数据驱动:脚本对 10 轮原始记录计算均值与标准差,剔除偏离均值超过 2 倍标准差的异常点后重新求均值与 min/max,再交由 gnuplot 以带误差条的直方图形式呈现(bench_graph.gnuplot 第 12-13 行)。

数据流水线:从原始日志到成图

仓库完整保留了“原始记录 → 汇总 → 成图 → 回写”的流水线,这也是该基准测试可复现、可信的原因:

  1. 原始记录:run_bench.sh 对$PROG(此处为 blobfuse)和 goofys 分别调用bench.sh,把每次计时追加写入bench.goofys/bench.blobfuse,每行形如create_files 2.778(操作名 + 秒);
  2. 汇总:paste合并两组日志后交给 bench_format.py,输出 bench.data 的#operation,time表格(每行依次为操作名、goofys 均值/min/max、blobfuse 均值/min/max),同时完成操作名到中文可读标签的映射(如write_md5→Write 1GB);
  3. 成图:gnuplot -c bench_graph.gnuplot生成横向柱状图,convert -rotate 90旋转为最终可读方向(run_bench.sh 第 165-172 行);
  4. 回写:测试结束前,脚本通过临时挂载 goofys 把所有结果文件cp进被测容器bench-mnt/,这就是文档中“result will be written to $TESTBUCKET”的实现(第 77-93 行)。

源码视角:goofys 的 Azure Blob 后端如何工作

基准测试只是表象,goofys 能在 Azure 上运行,依赖其原生 Azure Blob 后端实现:

  • 后端选择:goofys.go 的NewBackend根据FlagStorage.Backend类型分派,其中*AZBlobConfig对应NewAZBlob(实现在 backend_azblob.go,基于 Azure 官方azure-storage-blob-goSDK)。
  • bucket 规格解析:ParseBucketSpec 支持wasb://container、wasb://container:prefix以及wasb://container@storage-end-point三种形态——文档中“prefix separator is:”的约定正源于此:非完整 URI 时以冒号分隔前缀,完整 URI 时则以路径形式表达前缀。
  • 凭证与端点解析:conf_azure.go 的AzureBlobConfig按优先级依次读取:URL 中内嵌的存储端点(@之后部分)→AZURE_STORAGE_ACCOUNT/AZURE_STORAGE_KEY环境变量 →~/.azure/config的[storage]段;三者均缺失时,还会回退到 Azure CLI 登录令牌(az login)并尝试通过管理 API 自动发现账户端点与密钥(第 286-415 行)。这正是 README 中AZURE_STORAGE_ACCOUNT/AZURE_STORAGE_KEY两个环境变量能直接驱动基准测试的原因。
  • 兼容性细节:backend_azblob.go 中有一个值得注意的实现细节:Go 的net/http会把请求头规范化为驼峰形式,而 Azure Blob 服务对头名大小写敏感,因此代码包装了 pipeline,把x-ms-meta-前缀的头统一转为小写再发送,避免元数据(如目录标记hdi_isfolder)丢失。

需要说明的是:本文基准数据仅覆盖 goofys 与 blobfuse 两个对象,测试环境为文档指定的单地域同机房场景。若需在 S3、GCS 等其他后端下对比,仓库还提供了对应的 bench/Dockerfile、bench/Dockerfile.gcs 与 run_bench.sh 的通用入口,可参照同一套指标自行复跑。

复现注意事项与限制

最后,根据仓库中的脚本逻辑,列出复现或扩展测试时需要留意的边界:

  1. 必须是具备 FUSE 权限的 Linux 环境:挂载、fusermount -u、/proc/sys/vm/drop_caches都需要 root / privileged 权限,这也是 Docker 命令带--privileged的原因;
  2. 清缓存是结果可信的前提:比较冷读场景时,务必保证CACHE=false且缓存目录被清空(blobfuse 依赖重新挂载实现),否则读指标会被本地缓存“污染”;
  3. Azure 凭证优先级:AZURE_STORAGE_ACCOUNT/AZURE_STORAGE_KEY可覆盖~/.azure/config配置;goofys 尚不支持connection_string或sas_token(见 README-azure.md);
  4. 结果是相对参考而非绝对基准:数值随实例规格、地域、容器内数据规模、网络状况变化,文中所有数据仅代表本次Standard DS4 v2(West US)测试的观测值,引用时需注明前提。

如需深入阅读,可继续查看:Azure 配置使用文档、Azure 后端实现、凭证与端点解析 以及 基准测试主脚本。

  • 存储

【免费下载链接】goofys

a high-performance, POSIX-ish Amazon S3 file system written in Go

项目地址:https://gitcode.com/gh_mirrors/go/goofys
点击查看免费下载

相关推荐

上一篇:ngx-loading-bar源码解析:从拦截器到进度状态管理的实现原理
下一篇:X-SwiftFormat完全指南:让Xcode代码格式化效率提升10倍的终极工具

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

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

Natron ClipTest 节点使用指南:用斑马纹精准检出画面颜色越界

音视频视频处理图形学桌面应用 【免费下载链接】Natron Open-source video compositing software. Node-graph based. Similar in functionalities to Adobe After Effects and Nuke by The Foundry. 项目地址&#xff1a; https://gitcode.com/gh_mirrors/na/Natron 点击查看 …

作者头像 李华