欢迎访问张朋的技术分享社区
当前位置: 首页 > 技术分享  > Redis

解决 Redis 只读不可写的问题

2018/4/18 11:01:12 人评论

在 Redis 终端上进行读写操作,发现只读不可写, GET 操作是正常的, SET 操作提示错误:(error)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.这一问题通报给…

在 Redis 终端上进行读写操作,发现只读不可写, GET 操作是正常的, SET 操作提示错误:(error)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.

这一问题通报给运维后得到解决,方法是修改配置为 vm.overcommit_memory=1.

原因:Redis 在保存数据到硬盘时为了避免主进程假死,需要 Fork 一份主进程,然后在 Fork 进程内完成数据保存到硬盘的操作,如果主进程使用了 4 GB 的内存,Fork 子进程的时候需要额外的 4 GB,此时内存就不够了,Fork 失败,进而数据保存硬盘也失败了。

通过关闭配置项stop-writes-on-bgsave-error解决该问题。

redis 127.0.0.1:6379> config set stop-writes-on-bgsave-error no

注意一下服务是否有大量的close_wait状态的网络连接。
一般情况下,redis的超时时间(timeout 60)需要大于你的客户端连接池的超时时间,
否则会产生大量close_wait导致服务上没有可用的文件描述符,进一步导致网络不可用,进一步导致无法写redis。

Linux 内核会根据参数 vm.overcommit_memory 参数的设置决定是否放行。

如果 vm.overcommit_memory = 1,直接放行。

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

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

Redis内核参数overcommit_memory

它是内存分配策略可选值:0、1、2。

0表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。

1表示内核允许分配所有的物理内存,而不管当前的内存状态如何。

2表示内核允许分配超过所有物理内存和交换空间总和的内存

这种办法不可取。 
redis 的持久化目前做的不是很好。 
如果用 rdb 持久化,那 8G 内存服务器,就只用 4G ,另外 4G 给备份的。要么就是做主从,备份在从库做,从库用点虚拟内存。 
aof 持久化稍微好一点,但是要调整到晚上空闲时间重新整理 aof 文件。如果不整理 aof 文件,重启恢复太慢。如果隔几分钟就整理 aof ,又太消耗磁盘,也会阻塞 redis 进程。

如果你要用 rdb 持久化,那就 redis 配置的最大内存,必须小于服务器物理内存的一半(毕竟系统还要占用几百兆内存的) 
要么就关掉 rdb 持久化,改用 aof 持久化。配置成每天晚上空闲时间重写 aof 文件。


附件下载

相关技术

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?