redis Can’t save in background: fork: Cannot allocate memory 解决及原理
来源:互联网 发布:share软件下载 编辑:程序博客网 时间:2024/06/08 19:51
java日志中报错
redis.clients.jedis.exceptions.JedisDataException: MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error. at redis.clients.jedis.Protocol.processError(Protocol.java:66) ~[jedis-2.2.1.jar:na] at redis.clients.jedis.Protocol.process(Protocol.java:73) ~[jedis-2.2.1.jar:na] at redis.clients.jedis.Protocol.read(Protocol.java:138) ~[jedis-2.2.1.jar:na] at redis.clients.jedis.Connection.getIntegerReply(Connection.java:191) ~[jedis-2.2.1.jar:na] at redis.clients.jedis.Jedis.incr(Jedis.java:560) ~[jedis-2.2.1.jar:na]
redis日志中报错1
Can't save in background: fork: Resource temporaily unavailable
redis日志中报错2
Can’t save in background: fork: Cannot allocate memory
这个是因为,redis有个默认的选项:
stop-writes-on-bgsave-error yes
这个选项默认情况下,如果在RDB snapshots持久化过程中出现问题,设置该参数后,Redis是不允许用户进行任何更新操作。
不彻底的解决方式是,将这个选项改为false
不彻底的解决方式是,将这个选项改为false
stop-writes-on-bgsave-error false但是这样只是当redis写硬盘快照出错时,可以让用户继续做更新操作,但是写硬盘仍然是失败的;
彻底的解决方式
编辑文件 /etc/sysctl.conf 添加:
vm.overcommit_memory=1执行sysctl -p使其生效;
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
Out of memory: Kill process 9682 (mysqld) score 9 or sacrifice child
Killed process 9682, UID 27, (mysqld) total-vm:47388kB, anon-rss:3744kB, file-rss:80kB
httpd invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
Killed process 9682, UID 27, (mysqld) total-vm:47388kB, anon-rss:3744kB, file-rss:80kB
httpd invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
在什么条件下,linux会发现内存不足呢?
在Linux下有个CommitLimit 用于限制系统应用使用的内存资源:
[root@iZuf6c2qeenlv7dqgioq2eZ bin]# grep -i commit /proc/meminfo
CommitLimit: 961120 kB
Committed_AS: 1514856 kB
其中:
CommitLimit是一个内存分配上限,
Committed_AS是已经分配的内存大小。
虚拟内存算法:
CommitLimit = 物理内存 * overcommit_ratio(/proc/sys/vm/overcmmit_ratio,默认50,即50%) + swap大小
它是由内核参数overcommit_ratio的控制的,当我们的应用申请内存的时候,当出现以下情况:
应用程序要申请的内存 + 系统已经分配的内存(也就是Committed_AS)> CommitLimit
这时候就是内存不足,到了这里,操作系统要怎么办,就要祭出我们的主角“overcommit_memory”参数了(/proc/sys/vm/overcommit_memory);
- vm.overcommit_memory = 0 启发策略
- vm.overcommit_memory = 1 允许overcommit
- vm.overcommit_memory = 2 禁止overcommit
前面讲了一大堆参数,那么这些参数又是怎么影响redis的呢?
Redis的数据回写机制分同步和异步两种,
- 同步回写即SAVE命令,主进程直接向磁盘回写数据。在数据大的情况下会导致系统假死很长时间,所以一般不是推荐的。
- 异步回写即BGSAVE命令,主进程fork后,复制自身并通过这个新的进程回写磁盘,回写结束后新进程自行关闭。由于这样做不需要主进程阻塞,系统不会假死,一般默认会采用这个方法。
设置一个合理的写磁盘策略,否则写频繁的应用,也会导致频繁的fork操作,对于占用了大内存的redis来说,fork消耗资源的代价是很大的;
0 0
- redis Can’t save in background: fork: Cannot allocate memory 解决及原理
- redis Can’t save in background: fork: Cannot allocate memory
- redis Can’t save in background: fork: Cannot allocate memory
- 解决redis Can't save in background: fork: Cannot allocate memory
- Can’t save in background: fork: Cannot allocate memory
- 从Redis fork主进程 Can’t save in background: fork: Cannot allocate memory && vm.overcommit_memory
- redis 写磁盘出错 Can’t save in background: fork: Cannot allocate memory (转)
- redis日志出现Can't save in background fork Cannot allocate memory
- [bigdata-045] redis故障处理 "Can't save in background: fork: Cannot allocate memory"
- redis 故障处理 "Can't save in background: fork: Cannot allocate memory"
- [Redis] 解决Redis运行时Cannot save in background问题
- pid max导致fork: Cannot allocate memory 的分析及解决办法
- pid max导致fork: Cannot allocate memory 的分析及解决办法
- -bash: fork: Cannot allocate memory 问题的处理
- -bash: fork: Cannot allocate memory 问题的处理
- -bash: fork: Cannot allocate memory 问题的处理
- -bash: fork: Cannot allocate memory 问题的处理
- 7za 出现 Can't allocate required memory
- Connection-采用properties配置文件建立Connecton连接
- 模板模式
- Java JNI 入门篇——HelloWorld
- 谈谈malloc ()和free()
- 这些nginx文章不错,需要多研究
- redis Can’t save in background: fork: Cannot allocate memory 解决及原理
- Android-Context原理与用法详解
- SEO巧妙运用方法分享
- 从数据类型和运算符再出发
- poj 2186 Popular Cows (有向图的联通分量问题)
- codeforces 735C/382.2.C Tennis Championship
- 分配内存的函数C和C++
- linux命令之diff命令详解(比较文件内容)
- android开发 -- 时间控件的使用