Linux I/O 路线之争:mmap vs Direct I/O 在 io_uring 时代的架构演变

2024 年 7 月,Hacker News 上一篇标题为《Beyond io_uring: Why mmap is the Future of Linux I/O》的文章引发了一场足以载入 Linux I/O 多重核心开发者激烈辩论的风暴。本文将追溯 Linux I/O 两条核心路径——内存映射文件与直接 I/O 的技术演进史,解读 io_uring 如何重塑游戏规则,并以内核源码级视角讲解当前生产环境中该作何选择。

1. 两条技术路线的哲学分歧

在 Linux 中,用户进程读取文件存在两种根本思路:

/* 路线 A: mmap —让内核帮你搬运 */void *p = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);// 直接解引用 p 指针,缺页异常由内核处理/* 路线 B: read/write —你自己搬运 */char *buf = malloc(len);pread(fd, buf, len, offset);     // copy_to_user// 内核把 page cache 内容拷贝到用户空间

mmap 的核心优势是零拷贝(zero-copy)——文件页在内核 page cache 中驻留一次后,用户态通过页表映射直接访问,无需 copy_to_user。操作系统负责预读、驱逐,为用户提供了极其简洁的指针语义。

Direct I/O(O_DIRECT)则走另一条路:完全绕过 page cache,通过 DMA 在磁盘和用户缓冲区之间直传数据。它抛弃了内核的页缓存中间层,把缓存策略的自主权完全交给了应用层。

这种哲学上的分野,直接决定了两种方案在数据库、搜索引擎、流媒体、AI 推理等诸多领域的竞争力演化轨迹。

2. mmap 帝国的根基与暗礁

2.1 mmap 的生产力优势

mmap 看起来几乎是"免费"的:对于只读或顺序扫描负载,它天然避开了用户态缓冲区的分配,简化了代码路径。对于 RocksDB、LMDB、ClickHouse MergeTree 这类需要随机读的系统,mmap 让它们可以直接使用 B-Tree 指针语义,无需自行维护页偏移与缓冲池之间的映射表。

/* LMDB 的核心读路径 —没有任何用户态 buffer pool */MDB_val key, data;mdb_cursor_get(cursor,                        
                    
点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部