msync的性能是否与指定的同步区间大小有关?
Linux 内核
msync 性能问题解答 核心结论
现代Linux内核(所有2.6及以上稳定版本)中,对大文件全区间执行msync不会产生和文件总大小成正比的性能损耗,100GB文件仅修改10MB的场景下全量同步也不会有额外开销。
内核实现逻辑
- Linux 页缓存(page cache)会为每个文件维护独立的脏页管理结构,不会遍历
msync指定区间的所有内存页:- 每个文件对应的
address_space结构中,既通过基数树标记了所有页的脏状态,也维护了专属的脏页LRU链表,执行msync时只会扫描该文件的脏页集合,干净页完全不会被触碰。 - 即使你指定
msync的区间为整个文件大小,内核也只会筛选出落在同步区间内的脏页处理,10MB修改对应仅2560个4KB标准页,遍历的CPU开销可以忽略不计。
- 每个文件对应的
注意事项
如果你使用
MS_SYNC标志执行同步阻塞的msync,产生的性能开销仅和实际修改的数据量正相关,来自于脏页写入磁盘的IO耗时,和文件总大小无关。如果使用MS_ASYNC异步标志,仅会提交脏页IO请求,不会阻塞等待写入完成,开销更低。
使用建议
- 如果没有其他进程同时修改该mmap映射的文件,直接对全文件执行
msync是完全可行的,不需要额外追踪每次小范围写入的地址区间,不会有性能问题。 - 如果追求极致性能,也可以在业务侧累计一批写入的脏区间,批量调用
msync仅同步这些脏区间,和全量调用的差异仅为内核过滤脏页所属区间的极小CPU开销,绝大多数场景下感知不到差异。
内容的提问来源于stack exchange,提问作者Quo Si Than
相关产品推荐
相关产品推荐

