• Redis 写磁盘出错 Cannot allocate memory


    Redis 写磁盘出错 Cannot allocate memory

    故障简介

    早上查看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

    systecmtl restart redis
    

    转载文档

    https://www.jianshu.com/p/d03216c0150b
    
  • 相关阅读:
    【GoLang】转载:我为什么放弃Go语言,哈哈
    【GoLang】golang runtime 调度原理
    【GoLang】golang 微服务框架 介绍
    Redis缓存与springboot集成
    Redis分布式锁
    springboot配置文件的配置
    分布式事务之学习
    快速学习
    CAP定理为什么只能同时满足两个
    requestMapping之地址映射
  • 原文地址:https://www.cnblogs.com/evescn/p/12658226.html
Copyright © 2020-2023  润新知