零拷贝 + io_uring 打出 1580K IOPS:RustFS 性能超 4 倍是怎么做到的
零拷贝 io_uring 打出 1580K IOPSRustFS 性能超 4 倍是怎么做到的【免费下载链接】rustfsRustFS is an open-source, S3-compatible high-performance object storage system supporting migration and coexistence with other S3-compatible platforms such as MinIO and Ceph.项目地址: https://gitcode.com/GitHub_Trending/rus/rustfs「1580K IOPS」「零拷贝」「性能超 4 倍」——这几个关键词最近在存储圈反复出现伴随着 MinIO 许可风波后社区对替代方案的空前关注。但热度归热度真正值得读的是这些数字背后可被源码验证的工程事实RustFS 究竟把「零拷贝」落实到了哪几条代码路径上io_uring 在真实仓库里是默认开启还是灰度开关性能倍数到底从哪几层优化里来又在哪些场景下必然打折本文直接进入rustfs仓库沿读路径与写路径逐层拆解从UringBackend的运行时探测与 fd 缓存到mmap-copy的诚实取舍再到 PUT 侧 eager zero-copy 的准入规则最后把「4 倍」拆成可归因的优化层并给出明确的代价清单。1580K IOPS 是什么概念先把基线摆清楚讨论任何 IOPS 数字之前先看仓库自己公布的压测基线。项目根目录 README.md 中「RustFS vs MinIO Performance」一节给出了官方压力测试环境类型参数CPU2 核Intel Xeon Sapphire Rapids 8475B2.7/3.2 GHz内存4 GB网络15 Gbps硬盘40 GB × 4IOPS 3800 / 块这个环境很有代表性2 核 4 GB 的轻量配置4 块盘的设备层 IOPS 天花板合计约 1.5 万。而「1580K IOPS」是 15.8 万个量级——比设备层物理 IOPS 高出两个数量级。这说明它必然是应用层逻辑对象操作的口径当一次 GET/PUT 的对象落在页缓存或 mmap 区域里、当一次逻辑读不再对应一次物理盘寻址、当多个 shard 并行消化同一次请求时应用层 IOPS 完全可以、也应该远远甩开单块盘的设备指标。这一点不是 RustFS 独有而是所有「高并发、缓存命中密集」的存储服务共同的口径基础。更直接的实证在仓库自身的代码注释里。crates/ecstore/src/disk/local.rs 对 io_uring shard 化有一段带实测数据的说明16 核主机实测1 MiB 读从 4911 MB/s1 个 shard提升到 47361 MB/s8 个 shard64 KiB 读在并发 32 下从 124k 提升到 345k IOPS——同时保留 io_uring 的尾延迟优势。注意这两组数字约 2.8 倍的 IOPS 提升、约 9.6 倍的吞吐提升仅靠「把一个磁盘的 ring 从 1 个拆成 8 个」就拿到了。这为「性能超 4 倍」提供了仓库内可复核的量化证据倍数不是营销话术而是多层优化叠加后的保守结果。零拷贝链路拆解io_uring、内存映射各司其职社区热度文章常把「io_uring 内存映射 RDMA」并列为一个整体但仓库源码显示读侧零拷贝的真实构成是三层引擎的协作其中没有 RDMA 的实现证据仓库内未检索到相关代码可视为远期方向而非当前事实。真正的分工如下。第一层UringBackend——io_uring 读后端io_uring 读后端整体实现在 crates/ecstore/src/disk/local.rs 的UringBackend中约 4271 行起结构上是「除定位读外全部走StdBackend定位读走rustfs-uring的 cancel-safeUringDriver」的组合运行时探测默认灰度关闭RUSTFS_IO_URING_READ_ENABLE默认falseDEFAULT_RUSTFS_IO_URING_READ_ENABLE: bool false仅当环境变量置真且每盘探测成功时才启用。探测逻辑独立成模块 crates/ecstore/src/disk/uring_probe.rs并发探测上限 4探测失败会写入URING_UNSUPPORTED_DISKS负缓存避免每次磁盘重建都重复建 ring 开线程。每盘 fd 缓存FdCache命中时「没有 open、没有 spawn_blocking读路径全程不离开 runtime worker——这正是 io_uring 的意义所在backlog#1145」。fd 缓存有代际generation机制heal/delete 失效时会拒绝把陈旧描述符回填缓存同时用RLIMIT_NOFILE门控每盘 512 个 fd软限额过低时自动退回 open-per-read。shard 化 ringRUSTFS_IO_URING_SHARDS控制每盘独立 ring各自一个驱动线程的数量默认取可用并行度四分之一并夹在 1..4上限 16。设计动机在代码注释里写得很清楚缓冲读命中页缓存时io_uring_enter内联完成驱动线程要承担这次读的 memcpy——单 ring 会被单核内存带宽锁死shard 化近乎线性地抬升天花板。队列深度与背压URING_QUEUE_DEPTH 128且「背压把 in-flight 限制在每 shard 128低于该 ring CQ 容量2×所以 CQ overflow 结构性不可达」。单次读块长ReadChunkSize默认 128 MiBcrates/ecstore/src/disk/uring_read_chunks.rs逻辑长度不超过块长时走单操作快速路径代码注释直言「driver 的 Vec 直接成为结果无拷贝」The drivers Vec becomes the result with no copy超过块长则按块顺序拼装。运行时降级闸门ENOSYS/EPERM这类「子系统不可用」errno 会把整盘 latch 掉之后所有读直接走StdBackend且不再重试EINVAL/EOPNOTSUPP在已成功 O_DIRECT open 之后出现则只关闭原生 O_DIRECT 路径。每类降级都有独立事件日志与rustfs_io_uring_read_fallback_total计数器灰发期可以清楚地看到多少流量真在 io_uring 上、多少在 fallback。第二层mmap——「mmap-then-copy」不是严格零拷贝内存映射读的配置常量集中在 crates/config/src/constants/zero_copy.rs其文档注释罕见地诚实注意遗留的zero_copy环境变量只作为废弃兼容别名保留实际实现是 mmap-then-copy并非真正的零拷贝。关键事实RUSTFS_OBJECT_MMAP_READ_ENABLE默认开启DEFAULT_OBJECT_MMAP_READ_ENABLE: bool trueUnix 上先把文件映射进地址空间再拷入自有Bytes收益表述在源码里直接量化把内存拷贝从 3-4 次降到 1 次降低 CPU 占用与大对象读延迟——这正是「4 倍」叙事中最可归因的算术来源之一代价同样被明确标注数据仍要从 mmap 区域拷出一次且整段范围会在首字节发出前一次性物化于是有RUSTFS_OBJECT_MMAP_READ_MAX_LENGTH默认 32 MiB 的每 shard 读上限issue #5123 曾导致超大单部分对象整段物化、OOM 打死内存受限部署超限自动回落到有界流式读读取方式还有第二个开关RUSTFS_OBJECT_MMAP_READ_METHODmmap_copy与direct_read_copy二选一crates/ecstore/src/disk/local.rs 1051-1055 行。第三层io_uring × O_DIRECT——双特性叠加pread_uring_directcrates/ecstore/src/disk/local.rs 4856 行起是更激进的形态用O_DIRECT打开文件让 driver 读块对齐的超集范围进块对齐缓冲区再精确切回请求的逻辑区间——「同时保留 io_uring 的异步提交和 O_DIRECT 的页缓存旁路而不是二选一」。设备对齐通过statx每盘最多探测一次并缓存缓冲区用AlignedBuf分配1975 行。tmpfs、overlayfs、9p 等拒绝O_DIRECT的文件系统会 latch 关闭这条路径而非报错。写路径eager zero-copy 的准入规则读侧之外PUT 侧同样有零拷贝实现集中在 rustfs/src/app/object/put.rsshould_use_zero_copy(size, headers)404 行设了三道门槛对象必须大于 1 MiBZERO_COPY_MIN_SIZE请求了 SSE 加密含客户密钥与 KMS 头则排除content-type 命中text/plain、text/html、application/json等易压缩类型则排除因为下游会压缩先物化无意义read_zero_copy_put_body_exact701 行直接消费请求流的Bytes块压进ChunkedBytesReader每块只记账不拷贝record_zero_copy_buffer_operation(put_chunk, chunk.len())eager PUT 路径有独立准入状态机zero_copy_eager_put_path_statusextract、压缩、加密、无效大小、超上限、缺 AWS-chunked 解码长度都会落入对应ineligible分支默认体量上限RUSTFS_ZERO_COPY_EAGER_PUT_MAX_SIZE_BYTES 16 MiB超过则保持流式避免 1 MiB 请求也预留整请求大小的缓冲。全链路可观测性零拷贝不是黑盒。crates/io-metrics提供了完整指标面crates/io-metrics/src/metric_names.rs零拷贝写rustfs_zero_copy_buffer_operations_total、rustfs_zero_copy_buffer_bytes_total、rustfs_zero_copy_avg_copy_count、rustfs_zero_copy_throughput_mbps、rustfs_zero_copy_memory_saved_bytes_currentmmap 读rustfs_mmap_copy_reads_total、rustfs_mmap_copy_read_size_bytes、rustfs_mmap_copy_read_duration_ms、rustfs_mmap_copy_bytes_copied_total降级rustfs_zero_copy_fallback_total原因含mmap_unavailable、file_too_largeio_uring 侧还有rustfs_io_uring_read_fallback_total以及每盘导出的 in-flight、cq_overflow、cancel_already 三个 gauge。GET 完成路径在 rustfs/src/app/object/get.rs 2905 行按阶段指标开关记录record_zero_copy_read(size, duration_ms)运维可以对着「多少读走了零拷贝路径」做灰度判断。4 倍性能提升来自哪几层优化把「4 倍」拆开至少可以归因到五层每一层都有源码支撑1. 免系统调用与免上下文切换。fd 缓存命中后一次读不经过 open、不经过spawn_blocking提交与完成都发生在 ring 的 SQ/CQ 上驱动线程常驻poll(2)。相比传统「open → read → 内核缓冲 → 用户缓冲 → close」的往返每操作省掉的不仅是系统调用本身还有线程调度抖动。2. 拷贝次数从 3-4 次压到 0-1 次。mmap 路径把 3-4 次拷贝降为 1 次源码注释原话io_uring 快速路径下 driver 的Vec直接变成返回的Bytesno copy写侧 eager 路径复用请求流的既有Bytes块ChunkedBytesReader。这是「零拷贝」名号最实的部分。3. shard 并行打掉单核内存带宽天花板。单 ring 的缓存命中读受限于一个核心的 memcpy 带宽shard 化后近线性抬升1 MiB 读 4911→47361 MB/s约 9.6×64 KiB 读并发 32 下 124k→345k IOPS约 2.8×且保留 io_uring 的尾延迟优势。4. 预算与背压让并发不失控。队列深度 128/每 shard 使 CQ overflow 结构性不可达驱动线程预算RUSTFS_IO_URING_MAX_DRIVER_THREADS、共享读预算RUSTFS_IO_URING_READ_BUDGET_TOTAL_BYTES/_DRIVER_BYTES、结果预算RUSTFS_IO_URING_READ_RESULT_BUDGET_BYTES构成三级闸门——其中结果预算按返回Bytes的 clone 生命周期计费保留的 clone 不会在 future 完成时提前释放额度。并发被压在一个可控上界内CPU 预算没有被峰值请求池冲垮吞吐自然稳定在更高位。5. 写路径去中间缓冲 O_DIRECT 写减少脏页 flush。eager PUT 直收Bytes块省掉「流→整段缓冲→分片」的中间态O_DIRECT 写RUSTFS_OBJECT_DIRECT_IO_WRITE_ENABLE让 shard 字节直写设备提交点的sync_dir_filesfdatasync 不再冲刷约 2 MiB 脏页退化为廉价元数据/设备 FLUSH缓解 rename 临界区压力。代价与边界什么场景会打折扣性能叙事之外仓库代码把每条快路径的代价都写得明明白白这也是这篇最值得读的部分mmap 不是严格零拷贝。文档明言数据仍从映射区拷贝一次32 MiB 上限之外的大范围读自动回落有界流式读超大单部分对象的首字节延迟与内存占用是真实权衡issue #5123。io_uring 默认是关的且强依赖环境。RUSTFS_IO_URING_READ_ENABLE默认false需要 Linux 每盘探测通过容器/seccomp/LSM 环境里ENOSYS/EPERM会静默降级到StdBackend降级路径字节级等价但性能数字也随之回到普通基线。O_DIRECT 有对齐硬约束。块对齐缓冲、设备对齐探测statx都不可省tmpfs、overlayfs、9p 拒绝O_DIRECT时只保留 io_uring 的异步特性页缓存旁路失效。纠删码带来读放大与 CPU 成本。按 docs/architecture/erasure-coding.md 的规范说明RustFS 用 GF(2⁸) Reed-Solomon Vandermonde 矩阵、1 MiB erasure block读一个对象通常要并行读多个 shard且每个 1 MiB 块前置 32 字节 HighwayHash-256 校验verify-before-use校验不过绝不交数据。这意味着逻辑 IOPS 高但底层读请求数和校验计算量都成倍放大CPU 与设备预算必须同步到位——「2 核 4 GB 跑出 1580K」依赖的是缓存命中面不是盘本身的物理能力。driver 线程是显性成本。每盘shards个驱动线程默认保守取 1..4上限 16每个常驻poll(2)缓存不密集的工作负载里调高 shards 只是徒增线程。零拷贝 PUT 的排除面不小。SSE 加密、可压缩 content-type、≤1 MiB 的小对象、超 16 MiB eager 上限、AWS-chunked 缺失解码长度——任一命中即回退小对象高并发场景恰恰是普通路径。把这些边界放回「1580K IOPS / 4 倍」的语境里结论是清醒的RustFS 的倍数来自对缓存命中、拷贝次数、并发结构与设备对齐的系统性挤压每一条都经过了「探测→启用→latch 降级→可观测」的工程化包装。换个场景——冷数据、加密对象、无页缓存命中的裸盘随机读——性能会回到设备物理极限附近但这并不减损它在该赢的场景里确实赢下的事实。【免费下载链接】rustfsRustFS is an open-source, S3-compatible high-performance object storage system supporting migration and coexistence with other S3-compatible platforms such as MinIO and Ceph.项目地址: https://gitcode.com/GitHub_Trending/rus/rustfs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

在 Turborepo 与 Yarn Berry 中开发 Next.js 应用:with-berry 示例 Web 应用实战指南

在 Turborepo 与 Yarn Berry 中开发 Next.js 应用:with-berry 示例 Web 应用实战指南

构建工具开发工具CLI 【免费下载链接】turbo Build system optimized for JavaScript and TypeScript, written in Rust 项目地址: https://gitcode.com/gh_mirrors/tu/turbo 点击查看 免费下载 本篇指南以 Turborepo 仓库中 with-berry 示例的 apps/web 应用 READ…

2026/10/10 23:30:04 阅读更多 →
Serverless 冷启动 + Orleans 虚拟 Actor:Agent Substrate 的架构血统考

Serverless 冷启动 + Orleans 虚拟 Actor:Agent Substrate 的架构血统考

Serverless 冷启动 Orleans 虚拟 Actor:Agent Substrate 的架构血统考 【免费下载链接】substrate Agent Substrate: the core system 项目地址: https://gitcode.com/GitHub_Trending/substrate7/substrate 一个看似矛盾的事实正在改写云原生的资源模型&am…

2026/10/10 23:30:04 阅读更多 →
300 轮长会话实测:哪些内容会被 fast-jev-compaction 的「二元删除决策」误伤?

300 轮长会话实测:哪些内容会被 fast-jev-compaction 的「二元删除决策」误伤?

300 轮长会话实测:哪些内容会被 fast-jev-compaction 的「二元删除决策」误伤? 【免费下载链接】fast-jev-compaction Claude Code plugin that replaces the compaction summary with Jev decisions: every tool call and result is scored in one fast…

2026/10/10 23:30:04 阅读更多 →

最新新闻

物理与动画系统架构深度解析:从帧循环到Transform协同的引擎设计要点

物理与动画系统架构深度解析:从帧循环到Transform协同的引擎设计要点

做引擎这几年,最常被问到的一个问题就是:物理和动画这两个模块放在一起讲,是不是有点强行组CP?其实不是,这俩在帧循环里的位置紧挨着,数据耦合又深,渲染那边等着同一份Transform结果。你拆开看会…

2026/10/12 2:06:09 阅读更多 →
28岁没房没车别焦虑:转行前先搞懂副业与财富自由的底层逻辑

28岁没房没车别焦虑:转行前先搞懂副业与财富自由的底层逻辑

28岁,无车无房,收入一眼望到头,拿着几千块的工资,晚上躺床上刷手机,看到别人晒新房晒婚礼,再想想自己连恋爱都不敢谈,一种说不出的恐慌直接顶到嗓子眼儿。这种日子我太熟悉了,因为我…

2026/10/12 2:06:09 阅读更多 →
给Claude Code接入MCP搜索:告别过期答案,实时联网查资料

给Claude Code接入MCP搜索:告别过期答案,实时联网查资料

我印象最深的一次,是在某次项目重构里要用到一个库的最新接口。Claude Code 三两下就把代码写完了,看起来头头是道,结果一编译直接报错。后来我自己上官网翻文档才发现,这个库在两三周前刚改过一次函数签名,而 Claude …

2026/10/12 2:06:09 阅读更多 →
Ant Design Landing 设计资源页解析:Sketch 源文件、数据模型与前端实现

Ant Design Landing 设计资源页解析:Sketch 源文件、数据模型与前端实现

前端文档 【免费下载链接】ant-design-landing :mountain_bicyclist: Landing Pages of Ant Design System 项目地址: https://gitcode.com/gh_mirrors/antd/ant-design-landing 点击查看 免费下载 Ant Design Landing(ant-design-landing)是…

2026/10/12 2:06:09 阅读更多 →
Apache Beam Python 的 Mean 聚合变换:Globally 与 PerKey 用法及底层实现

Apache Beam Python 的 Mean 聚合变换:Globally 与 PerKey 用法及底层实现

【免费下载链接】beam Apache Beam is a unified programming model for Batch and Streaming data processing. 项目地址: https://gitcode.com/gh_mirrors/beam18/beam 点击查看 免费下载 本文围绕 Apache Beam Python SDK 中计算算术平均值的 Mean 聚合变换展开…

2026/10/12 2:06:09 阅读更多 →
Jenkins 2.346.1 内网离线安装插件:依赖解析与版本匹配实战

Jenkins 2.346.1 内网离线安装插件:依赖解析与版本匹配实战

简介:本资源面向在内网、隔离网等无外网环境中部署Jenkins的运维与DevOps工程师,针对Jenkins 2.346.1无法在线拉取插件的问题,提供一套完整的离线插件安装方案。压缩包共约2000个文件,整体314.4MB,涵盖90个jpi与30个hp…

2026/10/12 2:05:08 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →