现网问题
关于mmap的基本操作自行google去吧, 一抓一大把,99%基本上夸mmap是有多好多快,mmap快是因为建立了页到用户进程的虚拟空间映射,以读取文件为例,避免了页从内核态拷贝到用户态, 少了一次拷贝,而且在内存中操作,从这个层面看,mmap是屌屌的。但是在现网使用, mmap带来很多问题。
图一: 内存吃紧,swap也是关闭, 该进程使用内存状况
图二: 该进程 mmap 的索引 放在sda盘
带宽也就跑了3G左右 IO快到80了 SSD盘没有过期,上去观察的现象: 内存全部被该进程吃掉, 没有一点buffer/cache, swap也是关掉的。 iostat观察io次数特别多,排除写日志带来的io次数多
网上解决方案:
调研网上mmap相关资料,也出现过类似情况
使用mmap映射时指定MAP_LOCKED参数:指定此参数后mmap()函数会调用mlock()将内存区域锁定,防止被换出到磁盘,但是如果不是root账号只能锁定RLIMIT_MEMLOCK大小的内存(x86_64下默认为64K),需要调大此参数或修改为ulimited
但是现网验证,并没有效果, 调研网上资料mmap MAP_LOCKED参数, 实际上调用的是mlock这个系统调用。看linux代码, mlocked的页面也不是真正的锁住,最后还是会采用LRU算法,内存吃紧的情况下,这也就是废了。
网上mmap文章
认真分析mmap:是什么 为什么 怎么用
结论
- mmap文件更新操作多, mmap避免两态拷贝的优势就被摊还, 最后还是落在大量的脏页回写及其引发的随机io上。大量io又引发了util飙升。
- 内核功能,通常都运行得不太理想。 最大的问题是缺乏监控机制。 不好干预内部运行
- 有事没事直接翻内核代码比看网文章更靠谱点