Redis报错Can't save in background: fork: Cannot allocate memory及类似问题的处理方法
问题的发现及解决过程:
1.Redis主从复制(一主一从)环境在客户端用命令查看主从状态
在slave上输入命令显示如下:

在master上输入命令显示如下:

从显示可以看出主从关系出现问题,然后查看slave的redis.log有如下报错:

以为是IP及端口问题,经检查后发现非此问题。于是在网上查看一些别人的解决方法,但试过后都无效。于是查看master的redis.log有如下报错:

说明内存不足,无法为fork子进程分配内存,这就是主从出现问题的原因。
解决方法:
在master上的操作:
vim /etc/sysctl.conf
vm.overcommit_memory = 1 #在文件里添加该行后然后执行sysctl -p命令,该行的解释请看参考链接 https://blog.csdn.net/zqz_zqz/article/details/53384854 或下面的知识点扩展
此时再查看主从关系:
slave显示:

master显示:

说明主从关系已经恢复正常,再查看redis.log发现已经不再报错。
知识点扩展:
1.vm.overcommit_memory 参数说明如下:
Linux对大部分申请内存的请求都回复"yes",以便能跑更多更大的程序。因为申请内存后,并不会马上使用内存,将这些不会使用的空闲内存分配给其它程序使用,以提高内存利用率,这种技术叫做Overcommit。一般情况下,当所有程序都不会用到自己申请的所有内存时,系统不会出问题,但是如果程序随着运行,需要的内存越来越大,在自己申请的大小范围内,不断占用更多内存,直到超出物理内存,当linux发现内存不足时,会发生OOM killer(OOM=out-of-memory)。它会选择杀死一些进程(用户态进程,不是内核线程,哪些占用内存越多,运行时间越短的进程越有可能被杀掉),以便释放内存。当oom-killer发生时,linux会选择杀死哪些进程?选择进程的函数是oom_badness函数(在mm/oom_kill.c中),该函数会计算每个进程的点数(0~1000)。点数越高,这个进程越有可能被杀死。每个进程的点数跟(/proc/<pid>/oom_adj)oom_score_adj有关,而且oom_score_adj可以被设置(-1000最低,1000最高)。当发生oom killer时,会将记录在系统日志/var/log/messages中。
这时候就是内存不足,到了这里,操作系统要怎么办,就要祭出我们的主角“overcommit_memory”参数了(/proc/sys/vm/overcommit_memory);
vm.overcommit_memory = 0 启发策略
比较 此次请求分配的虚拟内存大小和系统当前空闲的物理内存加上swap,决定是否放行。系统在为应用进程分配虚拟地址空间时,会判断当前申请的虚拟地址空间大小是否超过剩余内存大小,如果超过,则虚拟地址空间分配失败。因此,也就是如果进程本身占用的虚拟地址空间比较大或者剩余内存比较小时,fork、malloc等调用可能会失败。
vm.overcommit_memory = 1 允许overcommit
直接放行,系统在为应用进程分配虚拟地址空间时,完全不进行限制,这种情况下,避免了fork可能产生的失败,但由于malloc是先分配虚拟地址空间,而后通过异常陷入内核分配真正的物理内存,在内存不足的情况下,这相当于完全屏蔽了应用进程对系统内存状态的感知,即malloc总是能成功,一旦内存不足,会引起系统OOM杀进程,应用程序对于这种后果是无法预测的。
vm.overcommit_memory = 2 禁止overcommit
根据系统内存状态确定了虚拟地址空间的上限,由于很多情况下,进程的虚拟地址空间占用远大于其实际占用的物理内存,这样一旦内存使用量上去以后,对于一些动态产生的进程(需要复制父进程地址空间)则很容易创建失败,如果业务过程没有过多的这种动态申请内存或者创建子进程,则影响不大,否则会产生比较大的影响 。这种情况下系统所能分配的内存不会超过上面提到的CommitLimit大小,如果这么多资源已经用光,那么后面任何尝试申请内存的行为都会返回错误,这通常意味着此时没法运行任何新程序。
2./etc/sysctl.conf添加vm.overcommit_memory=1一行相当与修改了/proc/sys/vm/overcommit_memory(默认是0)文件(参考链接 http://blog.51cto.com/yjw1983/1914916),所以我认为你可以不在/etc/sysctl.conf添加vm.overcommit_memory一行,直接修改/proc/sys/vm/overcommit_memory文件亦可
3.该问题解决两天后在slave发现如下报错:

亦是内存不足导致,采用如上方法即可解决
4.此参数是redis优化的一个关键参数,如果主从硬件配置相同,建议主从都修改此参数。
5.redis建议根据业务选择大于redis.conf中auto-aof-rewrite-min-size两倍的内存,例如该值为20G,建议内存为64G。auto-aof-rewrite-min-size的大小建议根据持久化文件的大小来进行优化。
Redis报错Can't save in background: fork: Cannot allocate memory及类似问题的处理方法的更多相关文章
- redis 写磁盘出错 Can’t save in background: fork: Cannot allocate memory (转)
查看 Redis 日志 发现系统在频繁报错: [26641] 18 Dec 04:02:14 * 1 changes in 900 seconds. Saving… [26641] 18 Dec 04 ...
- redis : Can't save in background: fork: Cannot allocate memory
redis : Can't save in background: fork: Cannot allocate memory JAVA程序报错信息: MISCONF Redis is configur ...
- mysql报错mmap(137428992 bytes) failed; errno 12,Cannot allocate memory for the buffer pool
mysql以`systemctl start mysqld.service`的方式启动一段时间后发现突然无法启动,尝试重新启动也不能解决问题,排查问题时,先后通过`systemctl status m ...
- redis报错
网站登录异常,redis数据不能写!解决方法汇总! redis---flushdb ###提示如下错误 ###flushall 清空说有数据,所有库 (error) ...
- Redis报错 : (error) NOAUTH Authentication required.
原文:Redis报错 : (error) NOAUTH Authentication required. 这个错误是因为没有用密码登陆认证 , 先输入密码试试 . 127.0.0.1:6379> ...
- mac brew install redis 报错
mac brew install redis 报错 /usr/local/opt/php55/bin/phpize /usr/local/opt/php55/bin/phpize: line 61: ...
- redis报错Windows error 0x70(a large memory)
redis报错Windows error 0x70 redis 嫌弃你内存不够了,就给你不开第二个实例. The Windows version of Redis allocates a large ...
- filebeat output redis 报错 i/o timeout
filebeat output redis 报错 i/o timeout 先把报错内容贴出来. ERROR redis/client. go: Failed to RPUSH to redis li ...
- window下安装redis报错: creating server tcp listening socket 127.0.0.1:6379: bind No error
window下安装redis报错: creating server tcp listening socket 127.0.0.1:6379: bind No error 解决: 如果没有配置环境,在安 ...
随机推荐
- StartDT AI Lab | 智能运筹助力企业提升决策效率、优化决策质量
在人工智能和大数据时代,越来越多的云上数据和越来越智能的模型开始辅助人们做出各种最优决策,从运营效率.成本节约.最优配置等方方面面,实现降本增效,进一步提升商业效率.京东.美团.滴滴.顺丰等众多知名厂 ...
- idea高效插件
RestfulToolkit:url定位controller,快捷键:ctrl+\Maven Helper:依赖分析JRebel:热部署Rainbow Brackets:个性化花括号aiXcode:a ...
- linux c 调用 so 库
/***********编译时要链接 -l dl 库************/ #include<stdlib.h> #include<stdio.h> #include< ...
- 吴裕雄--天生自然python学习笔记:python 用firebase实现英汉词典进阶版
用 post 方法创建的数据会自动产生一个 id (Key ),但有时也常常为了取得这个 id 而让程序难以处理 . 以英汉词典标准版来说,它的数据结构如下: 如果将每条数据都改为{eword:cwo ...
- python语法基础-异常操作-长期维护
############### python-异常的操作 ############### # 异常:python解释器遇到一个错误,会停止程序的执行,并且提示错误信息,这就是异常, # 抛出异 ...
- 传输层TCP和UDP
TCP协议 传输控制协议 TCP是面向连接.可靠的进程到进程通信的协议 TCP提供全双工工服务,即数据可在同一时间双向传输 三次握手: ...
- 浅谈Java中的泛型
泛型是Java自JDK5开始支持的新特性,主要用来保证类型安全.另外泛型也让代码含义更加明确清晰,增加了代码的可读性. 泛型的声明和使用 在类声明时在类名后面声明泛型,比如MyList<T> ...
- 非线程安全的HashMap 和 线程安全的ConcurrentHashMap
在平时开发中,我们经常采用HashMap来作为本地缓存的一种实现方式,将一些如系统变量等数据量比较少的参数保存在HashMap中,并将其作为单例类的一个属性.在系统运行中,使用到这些缓存数据,都可以直 ...
- redis安装zmalloc.h:50:31: 致命错误:jemalloc/jemalloc.h:没有那个文件或目录
问题: zmalloc.h:50:31: 致命错误:jemalloc/jemalloc.h:没有那个文件或目录 解决方案:执行命令:make MALLOC=libc make MALLOC=libc
- Spring Boot: Jdbc javax.net.ssl.SSLException: closing inbound before receiving peer's close_notify
jdbc:mysql://127.0.0.1:3306/xxx?useSSL=false 在后面添加?useSSL=false即可 参考网站