Nginx非阻塞I/O与Linux页缓存协同提升小文件服务性能:依赖page cache实现零磁盘读取复用,sendfile实现零拷贝直通,open_file_cache减少元数据开销,禁用directio保障缓存有效性。
Nginx 的非阻塞 I/O 不是孤立运行的,它和 Linux 内核的页缓存(page cache)协同工作,形成一套高效、低开销的小文件服务机制。关键不在于“绕开”内核,而是在非阻塞前提下,最大化复用已缓存的数据,避免重复读盘和多余拷贝。
当 Nginx 处理静态小文件请求(如 JS、CSS、图标)时,它默认走的是标准缓存 I/O 路径:内核先检查 page cache 中是否已有该文件内容;有则直接返回,无则从磁盘加载进 page cache,再提供给 Nginx。这个过程对 Nginx 是透明的,但至关重要——非阻塞 I/O 只负责“什么时候去读”,而 page cache 决定了“读什么、从哪读”。
这是非阻塞 I/O 与内核缓存协作最典型的体现。启用 sendfile on 后,Nginx 不再调用 read() + write(),而是让内核直接把 page cache 中的数据复制到 socket 发送队列:
非阻塞 I/O 的效率会被频繁的 stat()、open() 拖累——这些调用虽不读文件内容,但每次都要查 inode、权限、是否存在,也走内核路径。open_file_cache 就是为缓解这个问题而设:
directio 指令会让读操作绕过 page cache,直接读磁盘(O_DIRECT)。这对大文件流式传输有意义,但对小文件是负优化:
不复杂但容易忽略:非阻塞只是调度方式,真正提升吞吐的是让内核缓存“一直有用”。配置上做减法(关日志、禁正则匹配)、做缓存(open_file_cache、sendfile)、不做干扰(不用 directio),就能让两者稳稳配合。