在写入Redis (SET foo bar)期间,我得到以下错误:

MISCONF Redis被配置为保存RDB快照,但当前为 无法在磁盘上持久保存。可能修改数据集的命令是 禁用。有关错误的详细信息,请查看Redis日志。

基本上我理解的问题是,redis是不能在磁盘上保存数据,但不知道如何摆脱这个问题。

下面的问题也有同样的问题,它在很久以前就被抛弃了,没有答案,很可能没有尝试解决这个问题。


当前回答

请注意,当您的服务器受到攻击时,将出现此错误。刚刚发现redis无法写入'/etc/cron。D /web',在修改权限后,添加了包含挖掘算法和一些隐藏选项的新文件。

其他回答

所有这些答案都不能解释RDB保存失败的原因。


作为我的情况,我检查了redis日志,发现:

14975:M 18 Jun 13:23:07.354 #后台保存被信号9终止

在终端执行如下命令:

sudo egrep -i -r 'killed process' /var/log/

它显示:

/var/log/kern.log.1:Jun 18 13:23:07 10-10-88-16 kernel: [28152358.208108] Killed process 28416 (redis-server) total-vm:7660204kB, anon-rss:2285492kB, file-rss:0kB

就是这样!这个进程(redis保存rdb)被OOM杀手杀死

是指:

https://github.com/antirez/redis/issues/1886

查找哪个进程被Linux OOM杀手杀死

正如@Chris指出的,问题可能是低内存。当我们分配太多内存给MySQL (innodb_buffer_pool_size)时,我们就开始遇到这种情况。

为了确保有足够的内存用于Redis和其他服务,我们减少了MySQL上的innodb_buffer_pool_size。

在redis.conf第235行,让我们像这样修改配置

- stop-writes-on-bgsave-error yes
+ stop-writes-on-bgsave-error no

此错误是由于BGSAVE失败导致的。在BGSAVE期间,Redis会fork一个子进程来将数据保存到磁盘上。虽然BGSAVE失败的确切原因可以从日志中检查(通常在linux机器上的/var/log/redis/redis-server.log),但很多时候bgive失败是因为fork不能分配内存。很多时候,由于操作系统的优化冲突,fork无法分配内存(尽管机器有足够的可用RAM)。

可以从Redis常见问题中阅读:

Redis background saving schema relies on the copy-on-write semantic of fork in modern operating systems: Redis forks (creates a child process) that is an exact copy of the parent. The child process dumps the DB on disk and finally exits. In theory the child should use as much memory as the parent being a copy, but actually thanks to the copy-on-write semantic implemented by most modern operating systems the parent and child process will share the common memory pages. A page will be duplicated only when it changes in the child or in the parent. Since in theory all the pages may change while the child process is saving, Linux can't tell in advance how much memory the child will take, so if the overcommit_memory setting is set to zero fork will fail unless there is as much free RAM as required to really duplicate all the parent memory pages, with the result that if you have a Redis dataset of 3 GB and just 2 GB of free memory it will fail. Setting overcommit_memory to 1 says Linux to relax and perform the fork in a more optimistic allocation fashion, and this is indeed what you want for Redis.

Redis不需要像操作系统认为的那样多的内存来写入磁盘,所以可能会预先导致fork失败。

要解决这个问题,您可以:

修改/etc/sysctl.conf,增加:

vm.overcommit_memory=1

然后重新启动sysctl:

在FreeBSD上:

sudo /etc/rc.d/sysctl reload

在Linux上:

sudo sysctl -p /etc/sysctl.conf

在我的情况下,Ubuntu虚拟机的磁盘空间已满,这就是为什么我得到这个错误。从磁盘删除一些文件后,已解决问题。