Redis持久化失败,MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist o

时间:2019-02-25
本文章向大家介绍Redis持久化失败,MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist o,主要包括Redis持久化失败,MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist o使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Redis出现无法持久化的异常

具体报错信息如下:

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.

Redis日志如下:

21222:C 25 Feb 03:58:01.811 * RDB: 70 MB of memory used by copy-on-write
797:M 25 Feb 03:58:01.825 * Background saving terminated with success
797:M 25 Feb 04:03:02.100 * 10 changes in 300 seconds. Saving...
797:M 25 Feb 04:03:02.101 # Can't save in background: fork: Cannot allocate memory

Redis的持久化的工作方式:
当 Redis 需要保存 dump.rdb 文件时, 服务器执行以下操作:

  • Redis 调用forks. 同时拥有父进程和子进程。
  • 子进程将数据集写入到一个临时 RDB 文件中。
  • 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。

这种工作方式使得 Redis 可以从写时复制(copy-on-write)机制中获益。

解决方案
一、忽略持久化异常,继续写入

xxx> config set stop-writes-on-bgsave-error no

二、修改Linux内存分配策略

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

报错分析
Redis在dump数据的时候,会fork出一个子进程,理论上child进程所占用的内存和parent是一样的,比如parent占用的内存为8G,这个时候也要同样分配8G的内存给child,如果内存无法负担,往往会造成redis服务器的down机或者IO负载过高,效率下降。所以这里比较优化的内存分配策略应该设置为 1(表示内核允许分配所有的物理内存,而不管当前的内存状态如何)。

内存分配策略参数
overcommit_memory参数说明: 设置内存分配策略(可选,根据服务器的实际情况进行设置) ,可选值:0、1、2。

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

参考: