MISCONF Redis用于保存RDB快照

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

MISCONF Redis被配置为保存RDB快照,但当前为 无法在磁盘上持久保存。可能修改数据集的命令是 禁用。

. Please check Redis logs for the details of error.

.

.

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

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

464531 次浏览

感谢大家检查这个问题,显然错误是在bgsave期间产生的。

对我来说,在shell中输入config set stop-writes-on-bgsave-error no并重新启动Redis解决了这个问题。

如果您遇到错误,一些重要的数据不能在运行中的redis实例上被丢弃(rdb文件或其目录的权限问题不正确,或磁盘空间不足),您总是可以将rdb文件重定向到其他地方。

使用redis-cli,你可以这样做:

CONFIG SET dir /tmp/some/directory/other/than/var
CONFIG SET dbfilename temp.rdb

在此之后,您可能希望执行BGSAVE命令,以确保将数据写入rdb文件。确保当你执行INFO persistence时,bgsave_in_progress已经是0rdb_last_bgsave_statusok。在此之后,您现在可以开始在安全的地方备份生成的rdb文件。

由于内存不足,bgsave过程中可能会出现错误。试试这个(从redis后台保存FAQ)

echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf
sysctl vm.overcommit_memory=1

使用redis-cli,你可以阻止它尝试保存快照:

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

这是一个快速的解决方法,但是如果你关心使用它的数据,你应该检查一下为什么bgsave首先失败了。

如果您在Linux机器上工作,还要重新检查数据库的文件和文件夹权限。

数据库和它的路径可以通过以下方式获得:

在# EYZ0:

CONFIG GET dir

配置dbfilename

和在命令行ls -l。目录的权限应为755,文件的权限应为644。此外,通常redis-server作为用户redis执行,因此通过执行sudo chown -R redis:redis /path/to/rdb/folder将文件夹的所有权授予redis用户也是很好的。这已经在答案在这里中详细说明了。

FWIW,我遇到了这个问题,解决方案是简单地向盒子添加一个交换文件。我使用这个方法:https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-ubuntu-14-04

一个更永久的修复方法可能是查看/etc/redis/redis.conf中200-250行左右的rdb特性的设置,这不是redis 2中的一部分。x天。

值得注意的是

dir ./

可更改为

dir /home/someuser/redislogfiledirectory

或者您可以注释掉所有保存行,而不用担心持久性。(见/etc/redis/redis.conf中的注释)

还有,别忘了

service redis-server stop
service redis-server start

所有这些答案都不能解释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 save rdb)被伯父杀手杀死

是指:

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

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

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

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

在Redis有写权限的目录下启动Redis服务器

上面的答案肯定能解决你的问题,但实际情况是这样的:

存储rdb.dump文件的默认位置是./(表示当前目录)。您可以在redis.conf文件中验证这一点。因此,启动redis服务器的目录将创建和更新dump.rdb文件。

似乎你已经开始运行redis服务器在一个目录,其中redis没有正确的权限来创建dump.rdb文件。

更糟糕的是,redis可能也不允许你关闭服务器,直到它能够创建rdb文件,以确保正确保存数据。

要解决这个问题,您必须使用redis-cli进入活动的redis客户端环境,并更新dir键,并将其值设置为您的项目文件夹或任何非root用户有权限保存的文件夹。然后运行BGSAVE调用dump.rdb文件的创建。

CONFIG SET dir "/hardcoded/path/to/your/project/folder"
BGSAVE

(现在,如果您需要保存转储。RDB文件在您启动服务器的目录中,然后您需要更改该目录的权限,以便redis可以写入它。您可以搜索stackoverflow如何做到这一点)。

你现在应该可以关闭redis服务器了。注意,我们对路径进行了硬编码。硬编码很少是一个好的做法,我强烈建议从你的项目目录启动redis服务器,并更改dir key back to./ '。

CONFIG SET dir "./"
BGSAVE

这样,当您需要redis为另一个项目时,转储文件将创建在当前项目的目录中,而不是在硬编码路径的项目目录中。

我在使用AFS磁盘空间的服务器上工作时遇到了这个问题,因为我的身份验证令牌已经过期,当redi -server试图保存时产生了Permission Denied响应。我通过刷新我的令牌来解决这个问题:

# EYZ0

在我的例子中,原因是磁盘的可用空间非常低(只有35 Mb)。我做了以下的事情

  1. 停止所有Redis相关进程
  2. 删除磁盘中的一些文件,以腾出足够的空间
  3. 删除redis转储文件(如果不需要现有数据)

    # EYZ0 < / p >

  4. 删除所有现有数据库的所有键

    # EYZ0 < / p >

  5. 重新启动所有芹菜任务,并检查相应的日志是否有任何问题

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

复述,常见问题解答可以读到:

Redis后台保存模式依赖于现代操作系统中fork的写时复制语义:Redis fork(创建一个子进程),它是父进程的精确副本。子进程将DB转储到磁盘上并最终退出。理论上,子进程使用的内存应该和父进程作为副本使用的内存一样多,但实际上,由于大多数现代操作系统实现了写时复制语义,父进程和子进程将共享公共内存页。只有在子节点或父节点中发生更改时,页面才会被复制。因为理论上所有的页面都可能在子进程保存的时候改变,Linux不能提前告诉子进程将占用多少内存,所以如果overcommit_memory设置为0,fork将失败,除非有足够多的空闲RAM来复制所有的父内存页面,结果是如果你有一个3gb的Redis数据集,只有2gb的空闲内存,它将失败。

将overcommit_memory设置为1表示Linux放松并以更乐观的分配方式执行fork,这确实是你想要的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

我也面临着同样的问题。两个答案(被点赞最多的和被接受的)都只是暂时的解决办法。

此外,config set stop-writes-on-bgsave-error no是一种可怕的忽略这个错误的方式,因为这个选项所做的是阻止redis通知写已经停止,并继续在快照中不写数据。这是简单地忽略这个错误。 # EYZ0 < / p >

至于在redis-cli的config中设置dir,当你重新启动redis服务时,这个错误也会被清除,并且会再次弹出相同的错误。redis.conf中的dir默认值为./,如果以root用户启动redis,则.//,不授予写权限,因此出现错误。

最好的方法是在redis.conf文件中设置dir参数,并对该目录设置适当的权限。大多数debian发行版都应该在/etc/redis/redis.conf中包含它

如果你在windows机器上本地运行Redis,试着“以管理员身份运行”,看看它是否有效。对我来说,问题是Redis位于“程序文件”文件夹中,默认情况下会限制权限。这是应该的。

但是,不以管理员身份自动运行Redis您不想授予它应该拥有的更多权限。你想按规矩办事。

因此,我们能够通过作为管理员运行它来快速识别问题,但这不是解决方法。一种可能的情况是,你把Redis放在一个没有写权限的文件夹中,结果DB文件被存储在同一个位置。

您可以通过打开redis.windows.conf并搜索以下配置来解决此问题:

    # The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir ./

dir ./更改为具有常规读/写权限的路径

你也可以将Redis文件夹整体移动到一个你知道拥有正确权限的文件夹。

遇到此错误,并且能够从日志中找出该错误是由于磁盘空间不足造成的。所有插入到我箱子里的数据都不再需要了。所以我试着冲洗马桶。由于redis-rdb-bgsave进程正在运行,因此也不允许FLUSH数据。我按照下面的步骤,并能够继续。

  1. 登录redis客户端
  2. 执行# EYZ0
  3. 执行FLUSHALL(不需要存储数据)
  4. 执行# EYZ0

进程redis-rdb-bgsave在执行以上步骤后不再运行。

我也遇到过类似的问题,这背后的主要原因是redis的内存(RAM)消耗。 我的EC2机器有8GB内存(大约7.4可用)

当我的程序运行时,RAM使用量上升到7.2 GB,只剩下大约100MB的RAM,这通常会触发MISCONF Redis error ...

您可以使用htop命令确定RAM消耗。运行htop命令后寻找Mem属性。如果它显示出较高的消耗(比如我的情况是7.2GB/7.4GB),那么最好将实例升级为更大的内存。 在这种情况下,使用config set stop-writes-on-bgsave-error no对服务器来说将是一场灾难,并可能导致中断服务器上运行的其他服务(如果有的话)。因此,最好避免使用config命令和升级你的redis机器.

供你参考:你可能需要安装htop来完成这个工作:sudo apt-get install htop

还有一个解决方案到这个可以是在你的系统上运行的一些其他内存大的服务,检查在你的服务器/机器/实例上运行的其他服务,如果没有必要就停止它。使用service --status-all检查机器上运行的所有服务

对于那些直接粘贴config命令的人,建议在使用这些命令之前,请做一些研究,至少警告用户。正如@Rodrigo在评论中提到的:“忽视错误看起来并不酷。”

——更新

你也可以配置maxmemorymaxmemory-policy来定义Redis在达到特定内存限制时的行为。 例如,如果我想保持6GB的内存限制,并从DB中删除最近最少使用的键,以确保redis mem的使用不超过6GB,那么我们可以设置这两个参数(在redis.conf或CONFIG set命令中):

maxmemory 6gb
maxmemory-policy allkeys-lru

你可以为这两个参数设置很多其他的值,你可以从这里阅读:https://redis.io/topics/lru-cache

如果你正在使用码头工人/ docker-compose并且想要阻止redis写入文件,你可以创建一个redis配置并挂载到容器中

docker.compose.override.yml

  redis:¬
volumes:¬
- ./redis.conf:/usr/local/etc/redis/redis.conf¬
ports:¬
- 6379:6379¬


您可以从在这里下载默认配置

在redis.conf文件中,确保注释掉这3行

save 900 1
save 300 10
save 60 10000

您可以查看更多的解决方案删除持久数据在这里

现在,Redis的写访问问题在官方的redis docker容器中再次出现,给客户端提供了这个错误消息。

来自官方的redis图片的Redis试图将.rdb文件写入容器/data文件夹中,这是相当不幸的,因为它是根目录拥有的文件夹,也是一个非持久化的位置(如果容器/pod崩溃,写入那里的数据将消失)。

所以在一个小时的不活动后,如果你以非根用户运行了你的redis容器(例如docker run -u 1007而不是默认的docker run -u 0),你会在你的服务器日志中得到一个非常详细的错误信息(见docker logs redis):

1:M 29 Jun 2019 21:11:22.014 * 1 changes in 3600 seconds. Saving...
1:M 29 Jun 2019 21:11:22.015 * Background saving started by pid 499
499:C 29 Jun 2019 21:11:22.015 # Failed opening the RDB file dump.rdb (in server root dir /data) for saving: Permission denied
1:M 29 Jun 2019 21:11:22.115 # Background saving error

所以你需要做的是将容器的/data文件夹映射到一个外部位置(非根用户,这里:1007,有写权限,比如主机上的/tmp),例如:

docker run --rm -d --name redis -p 6379:6379 -u 1007 -v /tmp:/data redis

所以这是官方docker镜像的错误配置(应该写入/tmp而不是/data),产生了这个“定时炸弹”,你很可能只会在生产中遇到……在某个特别安静的假日周末过夜:/

您必须chmod和chown新文件夹

chown -R redis And chmod…

在我的例子中,它与磁盘空闲空间有关。(你可以用df -h bash命令检查)当我释放一些空间时,这个错误消失了。

对我来说

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

我重新加载我的mac,它工作

如果你正在运行MacOS,并且最近升级到Catalina,你可能需要按照这个问题中的建议运行brew services restart redis

重新启动redis服务器。

  • # EYZ1: # EYZ0。
  • # eyz2 # eyz0 / # eyz1
  • 窗口: 窗户 + R ->键入services.msc输入 ->搜索Redis然后点击restart
我个人在用Brew (brew upgrade)升级redis后遇到了这个问题。 在重新启动笔记本电脑后,它立即工作了
在我的情况下,它发生了,因为我刚刚安装了redis使用快速的方式。所以redis不是以根用户身份运行。 我能够通过遵循他们的快速入门指南 Installing Redis more properly部分下的说明来解决这个问题。这样做之后,问题就解决了,redis现在以根用户身份运行。

在采取任何行动之前检查你的Redis日志。这个线程中的一些解决方案可能会删除你的Redis数据,所以要小心你在做什么。

在我的例子中,机器的RAM < em > < / em >快用完了。当主机上没有空闲磁盘空间 .时也会发生这种情况。

在我的脑袋撞了那么多so的问题之后,终于- 对我来说,@Axel Advento的回答奏效了,但没有额外的步骤- 我仍然面临着许可问题 我必须切换用户到redis,在它的home目录中创建一个新目录,然后将其设置为redis的dir.

sudo su - redis -s /bin/bash
mkdir redis_dir
redis-cli CONFIG SET dir $(realpath redis_dir)
exit # to logout from redis user (optional)

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

# on redis 6.0.4
# if show error 'MISCONF Redis is configured to save RDB snapshots'
# Because redis doesn't have permissions to create dump.rdb file
sudo redis/bin/redis-server
sudo redis/bin/redis-cli

我知道这个线程稍微老一些,但当我早些时候得到这个错误时,这里是为我工作的,因为我知道我没有接近内存限制-两个答案都在上面找到。

希望这能在将来帮助到需要的人。

  1. 检查CHMOD目录…发现符号符号不一样。CHMOD目录文件夹到755
  2. Dbfilename权限很好,不需要更改
  3. 重启redis-server
  4. 参考redis-server.log,发现该错误是访问被拒绝的结果。

再次-不确定DIR文件夹的权限是如何改变的,但我假设CHMOD回到755并重新启动redis-server,因为我之后能够ping到redis服务器。

另外,需要注意的是,redis确实拥有dbfilename和DIR文件夹的所有权。

redis.conf~235上,让我们尝试像这样更改配置

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

检查dir: var/lib/redis的权限,应该是redis:redis

redis-cli美元

设置stop-writes-on-bgsave-error no

根据Redis文档,只有当您没有启用RDB快照或您不关心快照中的数据持久性时,才建议这样做。

默认情况下,如果RDB快照启用(至少一个保存点)并且最近的后台保存失败,Redis将停止接受写入。这将使用户意识到(以一种艰难的方式)数据没有正确地保存在磁盘上,否则,强大的文本很可能没有人会注意到,并且会发生一些灾难。

你应该做的是:

# redis-cli
127.0.0.1:6379> CONFIG SET dir /data/tmp
OK
127.0.0.1:6379> CONFIG SET dbfilename temp.rdb
OK
127.0.0.1:6379> BGSAVE
Background saving started
127.0.0.1:6379>

请确保/data/tmp有足够的磁盘空间。

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

是的,这是因为当前用户没有修改“dump.rdb”的权限。

因此,除了创建一个新的RDB文件,您还可以对旧文件授予权限(更改其所有权)。

在redis-cli中输入:

# EYZ0

你会得到"/usr/local/var/db/redis"(这是redis写入数据的位置)

使用终端前往此位置

cd
cd /usr/local/var/db

输入以下命令(使用我们的用户名):

sudo chown -R [username] db

这将改变为所有者。

这对我很有用。

在我的情况下,这只是特权,我需要允许Redis接受传入的请求。

所以我通过Homebrew brew services stop redisbrew services start redis重新启动了Redis服务,并在本地运行Redis服务器redis-server。命令提示符要求我允许传入请求,然后它开始工作。