File System (FS) 模块文档
本文档详细介绍了 veloq-runtime 的文件系统模块 (src/fs)。该模块旨在提供接近硬件极限的文件 I/O 性能,特别是在支持异步 I/O (io_uring / IOCP) 的现代操作系统上。
1. 概要 (Overview)
src/fs 模块提供了对底层文件描述符(或句柄)的异步封装。与标准库的 std::fs 不同,本模块的设计初衷是非阻塞 (Non-blocking) 和零拷贝 (Zero-Copy)。
核心组件包括:
File: 文件的异步句柄,实现了AsyncBufRead和AsyncBufWrite。OpenOptions: 高度可配置的文件打开构建器,支持跨平台的缓冲模式设置(如 Direct I/O)。
2. 理念和思路 (Concepts)
2.1 显式缓冲控制 (Explicit Buffering Control)
传统的缓冲 I/O (Buffered I/O) 依赖操作系统的 Page Cache。虽然简单,但在高吞吐场景下(如数据库 WAL、大文件传输)会导致双重拷贝和不可预测的延迟。
Veloq 通过 BufferingMode 提供了对 I/O 模式的精细控制:
Buffered: 标准模式,使用 Page Cache。Direct: 绕过 Page Cache (O_DIRECT / NO_BUFFERING),直接在用户态缓冲区和磁盘间传输数据。这要求缓冲区必须对齐(由BufPool保证)。DirectSync: Direct I/O 加上同步写入 (O_DSYNC / WRITE_THROUGH),确保数据落盘。
2.2 异步资源释放 (Async Drop)
在 Rust 中,Drop 是同步运行的。如果关闭文件描述符 (close/CloseHandle) 发生阻塞,会严重影响 Event Loop 的响应度。
File 实现了非阻塞 Drop 机制:在销毁时,它会尝试向 Runtime 提交一个后台关闭操作 (Close Op)。只有在 Runtime 无法访问(如已关闭)时,才会回退到同步关闭。
3. 模块内结构 (Internal Structure)
src/
├── fs.rs // 模块定义与导出
└── fs/
├── file.rs // 核心文件结构体
└── open_options.rs // 打开选项与标志位处理
fs.rs: 模块入口,负责导出子模块 (file,open_options) 和统一对外类型 (File,OpenOptions)。遵循 Rust 2018 模块标准,摒弃了mod.rs。file.rs: 封装了IoFd和对PlatformDriver的弱引用。提供了read_at,write_at,sync_range等高级操作。
4. 代码详细分析 (Detailed Analysis)
4.1 OpenOptions::open
这是文件打开的入口,采用了 Remote IO 架构以支持跨线程操作。
- Buffer 获取: 打开文件时,需要分配内存存储路径。这里使用了当前线程绑定的
BufPool。 - Op 构建: 调用
build_op,根据BufferingMode设置标志位。 - Remote Submission:
- 使用
RemoteSubmitter提交Open操作。 - 操作会被注入(Inject)到当前 Runtime 线程的 Driver 中执行。
- 关键点: 返回的
File对象会持有指向该 Driver 的Injector。这意味着该文件后续的所有 I/O 操作都会被“路由”回最初打开它的那个 Driver(线程)上执行。这保证了文件句柄(特别是 Windows Handle 或 io_uring 注册资源)的线程安全性。
- 使用
4.2 File 的异步读写与跨线程安全
File 结构体持有 RemoteSubmitter,因此它是 Send 的,可以在线程间传递。
- 路由机制: 当在一个新的线程上调用
file.read_at(...)时,操作并不是在当前线程执行,而是通过RemoteSubmitter发送回该文件绑定的源 Driver 执行。
4.3 File 接口
File 实现了原子偏移量的 I/O:
read_at/write_at: 这对实现数据库至关重要,允许并发地读写文件的不同部分而无需修改文件指针 (seek)。底层对应pread/pwrite。
4.4 SyncRangeBuilder
提供了细粒度的刷盘控制:
#![allow(unused)]
fn main() {
file.sync_range(0, 1024)
.wait_before(false)
.write(true)
.await
}
这段利用 Builder 模式的代码最终生成一个 SyncFileRange Op。
- Linux: 完美映射到
sync_file_range系统调用。 - Windows: 当前回退到
FlushFileBuffers(全文件 sync),因为 Win32 API 缺乏精确的范围同步机制。
5. 存在的问题和 TODO
- 文件元数据操作:
- 目前缺少
metadata(),set_permissions(),set_len()等标准操作。需要添加对应的异步 Op。
- 目前缺少
- 目录操作:
- 缺少
read_dir(I/O intensive) 的异步实现。
- 缺少
- Windows 范围同步:
- Windows 的范围同步回退到全量同步由于性能原因可能不可接受。TODO: 调研是否有未公开 API 或利用
LockFile等机制间接实现更细粒度的控制,或者明确文档警示。
- Windows 的范围同步回退到全量同步由于性能原因可能不可接受。TODO: 调研是否有未公开 API 或利用
- 路径处理:
- 目前路径处理涉及一次从
OsStr到BufPool缓冲区的拷贝。对于极高频打开操作,这可能存在微小开销。
- 目前路径处理涉及一次从
6. 未来的方向
- Registered Files (io_uring):
- 支持
io_uring的 “Fixed Files” 特性。允许用户注册文件描述符,减少内核层面的引用计数开销。这对高频 I/O 场景提效显著。
- 支持
- IO 优先级:
- 暴露 I/O 优先级设置(如
ioprio_set),允许关键任务抢占磁盘带宽。
- 暴露 I/O 优先级设置(如