levels参数不加快单次查找,但通过1:2两级哈希分层(共4096目录)均匀分散百万级缓存文件,避免单目录I/O瓶颈;需配合keys_zone≥10m、inactive≥30m、use_temp_path=off及稳定cache_key设计才能发挥最佳效果。

直接说结论:levels 参数本身不加快单次文件查找速度,但能有效缓解高并发下因单目录文件过多引发的 I/O 瓶颈。关键在于把海量缓存文件均匀打散到多级子目录中,避免一个目录塞进几万甚至几十万个文件。
为什么 levels=0(即不设分层)会拖慢整体性能
所有缓存文件都堆在同一个目录里。当缓存条目超过 10 万,ext4 或 xfs 文件系统在执行 stat、open 等操作时,就会暴露性能短板:
- ext4 默认用线性扫描方式查目录项,文件越多,平均查找耗时越长
- xfs 的 dir2 结构在单目录超数万文件后,目录块分裂频繁,哈希桶冲突上升
- Nginx 每次缓存命中都要读取文件元数据,高频小文件 I/O 下,瓶颈立刻显现
推荐配置:levels=1:2 是当前最实用的分层方案
它基于 cache_key 的 MD5 值生成两级子目录路径:
- 第一级:取 MD5 值最后 1 位(0–f),共 16 个目录
- 第二级:再取前 2 位(00–ff),共 256 个子目录
- 最终形成最多 4096 个叶子目录,百万级缓存也能保持每个目录仅几百个文件
- 路径示例:/var/cache/nginx/mycache/a/1b/a1b2c3...
固定哈希映射还带来局部性优势:相同请求总落在同一目录,利于 page cache 复用和磁盘预读。
只设 levels 不够,必须配合其他关键参数
单独调 levels 效果有限,需同步优化内存索引、生命周期与文件系统行为:
- keys_zone 至少配 10m:1MB 内存约存 8000 个 key,10m 可支撑约 8 万个活跃缓存项,避免 key 冲突淘汰
- inactive 别设太短:如仅 60s,会导致频繁清理重建,加剧 I/O;建议按业务热度设为 30m–2h
- use_temp_path=off:让临时文件直接写入缓存目录,避免跨文件系统拷贝,减少一次磁盘写
- 挂载选项优化:SSD 上推荐 noatime,nobarrier(xfs)或 noatime,commit=60(ext4),降低元数据更新开销
缓存 key 设计影响分层效果是否均衡
路径由 cache_key 经 MD5 后取前几位生成。如果 key 中含时间戳、随机串或用户 ID,哈希结果会严重倾斜——有些目录爆满,有些长期空置,仍会造成局部 I/O 压力集中。
推荐构造稳定 key:
- 保留 $scheme$host$request_uri 这类低熵字段
- 避免使用 $request_time、$cookie_sessionid、$arg_t 等高动态参数
- 可通过日志统计各子目录文件数,验证分布是否均匀











