Redis说无法分配内存该怎么办?

近日我司生产环境的redis频繁异常不可访问,已经严重影响公司牛逼的产品起飞了,那么作为集设计、编码、测试、运维于一身的全栈吹牛皮工程师,必须给它搞上一搞。

生产环境出了问题后,其实就是登录失败时提示token无效。根据老衲多年写bug的经验,第一时间就想到redis出了问题。登录服务器,ps看了一眼redis的进程,没问题。又free看了一眼内存,我的个乖乖,64g内存还剩几百兆,这肯定不正常了啊。随即打开了redis的日志,看到满屏都是以下内容输出,有那么一瞬,就像一万只草泥马从心头奔过。

6663:M 10 Apr 03:42:42.077 * 1 changes in 900 seconds. Saving...
6663:M 10 Apr 03:42:42.077 # Can't save in background: fork: Cannot allocate memory
6663:M 10 Apr 03:42:48.086 * 1 changes in 900 seconds. Saving...
6663:M 10 Apr 03:42:48.086 # Can't save in background: fork: Cannot allocate memory
6663:M 10 Apr 03:42:54.097 * 1 changes in 900 seconds. Saving...
6663:M 10 Apr 03:42:54.097 # Can't save in background: fork: Cannot allocate memory
6663:M 10 Apr 03:43:00.006 * 1 changes in 900 seconds. Saving...
6663:M 10 Apr 03:43:00.006 # Can't save in background: fork: Cannot allocate memory

不过就这个日志来说,确实提示的也很清楚了,redis的fork进程没有办法分配到内存,这和我们查询到内存只有几百兆的情况也能吻合。天大地大,生产最大。不管三七二十八,先恢复环境访问。于是乎重启了rediis,系统能够正常的登录了。

你以为到这里就结束了吗?当然不可能,作为一个新时代的四有青年,我怎么可能仅仅满足恢复生产环境访问这么简单的地步呢?过两天万一又不可访问了,而恰巧那会儿我正在和霸飞忒烧烤大腰子,那岂不是显得我不尊重大腰子了。

还是看看redis的日志怎么说吧。打开刚刚启动的redis的日志,有一行warning瞬间引起了老衲的注意(得亏不是FBI WARNING)。

21515:M 10 Apr 16:31:10.232 # 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已经在启动的时候提前告诉使用者了,你最好给我把vm.overcommit_memory设置成1,要不然系统内存不够分配了,我可不能保证我能在后台给你把数据给你保存成功。这不是就和我们redis报错Cannot allocate memory不谋而合了嘛。来看看vm.overcommit_memory是个神马,它是linux内存分配策略的配置参数,有以下3个值:

0:表示操作系统内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
1:表示操作系统内核允许分配所有的物理内存,而不管当前的内存状态如何。
2: 表示操作系统内核允许分配超过所有物理内存和交换空间总和的内存。

而且redis很贴心的告诉了使用者,最好把vm.overcommit_memory设置成1,然后重启服务器,或者执行命令sysctl vm.overcommit_memory=1让其立即生效,但是重启后又还原。

既然redis都把饭喂到嘴边了,那你还不吃就不能怪谁了。话不多说,先来一波操作。在/etc/sysctl.conf中添加vm.overcommit_memory=1,生产环境暂时先不重启服务器。紧接着执行命令sysctl vm.overcommit_memory=1让其立即生效,这样来说即使某个月黑风高的夜晚,服务器重启了,这个配置也不会被还原。

当然这台服务器上不仅仅运行redis一个中间件服务,还有其他的服务,如果任由redis去无限制的申请内存,那么也会影响到其他中间件服务的运行。因此还需要在针对于redis自身进行最大内存的限制。

编辑/etc/redis.conf,找到maxmemory项,设置redis最大可以使用到的内存,单位为字节。重启redis服务使其生效。

这一波操作下来,redis运行一段时间没见出问题,通过日志查询,也未见Cannot allocate memory的错误了,我又可以和我们的小伙伴一起快乐地去玩耍了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值