美文网首页
Redis 写磁盘出错 Cannot allocate memo

Redis 写磁盘出错 Cannot allocate memo

作者: 现阶段是高科技的时代 | 来源:发表于2016-03-27 21:53 被阅读0次

    故障简介

    早上查看Redis日志的时候发现Redis一直在报错

    [1524] 24 Mar 10:00:56.037 * 1 changes in 900 seconds. Saving...
    [1524] 24 Mar 10:00:56.037 # Can't save in background: fork: Cannot allocate memory
    

    Redis数据回写机制

    数据回写分同步和异步两种方式

    • 同步回写(SAVE), 主进程直接向磁盘回写数据. 在数据量大的情况下会导致系统假死很长时间
    • 异步回写(BGSAVE), 主进程fork后, 复制自身并通过这个新的进程回写磁盘, 回写结束后新进程自行关闭.

    由于 BGSAVE 不需要主进程阻塞, 系统也不会假死, 一般会采用 BGSAVE 来实现数据回写.

    故障分析

    在小内存的进程上做fork, 不需要太多资源. 但当这个进程的内存空间以G为单位时, fork就成为一件很恐怖的操作.
    在16G内存的足迹上fork 14G的进程, 系统肯定Cannot allocate memory.
    主机的Redis 改动的越频繁 fork进程也越频繁, 所以一直在Cannot allocate memory

    解决方案

    直接修改内核参数 vm.overcommit_memory = 1, Linux内核会根据参数vm.overcommit_memory参数的设置决定是否放行。

    vm.overcommit_memory = 1,直接放行
    vm.overcommit_memory = 0:则比较 此次请求分配的虚拟内存大小和系统当前空闲的物理内存加上swap,决定是否放行。
    vm.overcommit_memory = 2:则会比较进程所有已分配的虚拟内存加上此次请求分配的虚拟内存和系统当前的空闲物理内存加上swap,决定是否放行。

    源码如下:

    /* 在/etc/sysctl.conf文件里面加入或者直接删除也可以,因为它缺省值就是 */
    sudo echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf
    sudo sysctl -p
    

    相关文章

      网友评论

          本文标题:Redis 写磁盘出错 Cannot allocate memo

          本文链接:https://www.haomeiwen.com/subject/jdljlttx.html