首页 > 技术文章 > 【Redis】Redis BGSAVE内存不足异常

wsx2019 2021-12-14 18:00 原文

【Redis】Redis BGSAVE内存不足异常

测试系统不能正常登陆,检查日志发现是Redis异常。

Handling error: RedisPipelineException, Pipeline contained one or more invalid commands; nested exception is io.lettuce.core.RedisCommandExecutionException: MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error

日志显示是Redis将快照保存到硬盘上报错。

将错误在浏览器上检索,找到一种比较快速解决方法(治标不治本),先保障能够正常访问。

[root@HH]# redis-cli 
127.0.0.1:6379>config set stop-writes-on-bgsave-error no 

查看 Redis日志,显示异常信息如下

WARNING overcommit_memory is set to 0! Background save may fail
under low memory condition. To fix this issue add ‘vm.overcommit_memory = 1’ to > > > /etc/sysctl.conf and then reboot or run the command ‘sysctl vm.overcommit_memory=1’ > for this to take effect.

结合上面项目中的日志。报错的根本原因:

Redis在fork子进程,把数据持久化到硬盘上时,系统分配不到足够的内存给子进程。所有报错。而使用stop-writes-on-bgsave-error no忽略此错误,让Redis出来正常的请求。

设置vm.overcommit_memory意义

这时候就是内存不足,到了这里,操作系统要怎么办,就要祭出我们的主角“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大小,如果这么多资源已经用光,那么后面任何尝试申请内存的行为都会返回错误,这通常意味着此时没法运行任何新程序。
————————————————
版权声明:本文为CSDN博主「朱清震」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zqz_zqz/article/details/53384854

vim /etc/sysctl.conf
vm.overcommit_memory=1
sysctl -p

推荐阅读