MISCONF Redis配置为保存RDB快照


366

在写入Redis(SET foo bar)期间,出现以下错误:

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

基本上,我知道问题是redis无法将数据保存在磁盘上,但是不知道如何解决该问题。

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


您是否能够解决此问题。如果是,请您协助进行操作。因为我将rdb文件放在其他位置无法解决它。我想我在这里错过了一些东西
ankur 17-4-11

4
由于在Redis没有权限的目录中启动Redis服务器而发生此错误。我建议在解决问题后恢复为默认设置:有关解决此问题的信息,请参阅答案
Govind Rai


@GovindRai我已经通过将组和所有者都更改为来授予redis权限redis,但无济于事!
wdetac '18

Answers:


184

万一遇到错误,并且一些重要数据无法在正在运行的Redis实例上被丢弃(rdb文件或文件目录权限不正确或磁盘空间不足的问题),则始终可以重定向rdb文件以将其写入其他位置。

使用redis-cli,您可以执行以下操作:

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

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


7
持续性下的rdb_bgsave_in_progress:0
thanikkal,2014年

由于某些原因,当我尝试任何config set命令时,它就像永远加载一样。
巴沙尔·阿卜杜拉

5
对于那些现在在Windows上不幸的人,以及我正在使用MSOpenTech版本的Windows,您必须以以下样式设置目录路径:dir C:/Temp/。做一个bgsave,以验证它的工作原理..
约翰·P

@John P,这就是需要做的事情。谢谢!
山姆

2
127.0.0.1:6379> CONFIG SET dir / root / tool(错误)ERR更改目录:权限被拒绝
Gank

316

使用redis-cli,您可以停止尝试保存快照:

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

这是一个快速的解决方法,但是如果您关心要使用它的数据,则应检查以确保bgsave首先失败的原因。


21
这是一个快速的解决方法,但是您应该检查一下以确保bgsave失败的原因
Mandeep Singh

7
如果将redis主要用于缓存和会话,则必须这样做。
2015年

1
这不危险吗?例如,NodeBB使用Redis作为数据存储。
codecowboy

2
@LoveToCode配置设置为stop-writes-on-bgsave-error是
Phil

4
每当我重新启动服务器时,我都会再次遇到相同的问题。然后,我必须再次设置它。我如何使其永久化?
Zia Qamar

63

由于内存不足,在bgsave过程中可能会出错。试试看(从Redis后台保存常见问题解答)

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

5
LInk:redis.io/topics/faq搜索此:“ 即使在我有很多可用RAM的情况下,在Linux下,后台保存也会因fork()错误而失败!
Bruno Peres

49

发生此错误是由于BGSAVE失败。在BGSAVE期间,Redis派生一个子进程以将数据保存在磁盘上。尽管可以从日志中检查BGSAVE失败的确切原因(通常在/var/log/redis/redis-server.logLinux计算机上),但是很多时候BGAVE失败是因为fork无法分配内存。很多时候,由于OS的优化冲突,fork未能分配内存(尽管计算机有足够的可用RAM)。

可以从Redis FAQ中读取:

Redis后台保存架构依赖于现代操作系统中fork的写时复制语义:Redis forks(创建子进程)是父级的精确副本。子进程将数据库转储到磁盘上,最后退出。从理论上讲,子级应该使用与父级一样多的内存,但是实际上,由于大多数现代操作系统实现了写时复制语义,因此父级和子级进程将共享公共内存页。仅当页面在子代或父代中更改时,页面才会被复制。从理论上讲,由于在保存子进程时所有页面都可能会更改,因此Linux无法提前告知子进程将占用多少内存,因此,如果将overcommit_memory设置设置为零fork将会失败,除非有足够的可用RAM作为内存。真正复制所有父内存页面所需的内容,

将overcommit_memory设置为1表示Linux可以放松并以更乐观的分配方式执行派生,而这确实是Redis想要的。

Redis不需要像操作系统认为的那么多的内存来写入磁盘,因此可能会抢先失败。

要解决此问题,您可以:

修改/etc/sysctl.conf并添加:

vm.overcommit_memory=1

然后使用以下命令重新启动sysctl:

在FreeBSD上:

sudo /etc/rc.d/sysctl reload

在Linux上:

sudo sysctl -p /etc/sysctl.conf

输出systemctl status redis显示有警告,提示您正好更改overcommit_memory=0设置。改变的确为我解决了问题。
抽象算法

这可以正确解决问题,应该是可以接受的答案
DSynergy

所以tldr是默认设置,如果redis使用的是10 gb的ram,那么您需要有10gb的可用ram才能执行此子进程吗?
丹·黑斯廷斯

@DanHastings-是的。并将overcommit_memory设置为1可放宽此要求。
Bhindi

26

重新启动您的Redis服务器。

  • MACOS(BREW) :brew services restart redis
  • Linux: sudo service redis restart /sudo systemctl restart redis
  • Windows: Windows + R->类型services.mscEnter->搜索,Redis然后单击restart

使用Brew(brew upgrade)升级Redis后,我个人遇到了此问题。重新启动笔记本电脑后,它立即可以工作。


如果有人正在阅读此书,那么我也遇到了Homebrew的问题,但与升级无关:我只需要使用sudo:启动服务即可brew services stop redis; sudo brew services start redis
bfontaine

24

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

可以通过以下方式获取数据库及其路径:

redis-cli

配置获取目录

配置获取dbfilename

并在命令行中ls -l。目录的权限应为755,文件的权限应为644。另外,通常redis-server是作为user执行的redis,因此redis通过执行以下操作也可以为用户提供文件夹的所有权sudo chown -R redis:redis /path/to/rdb/folder。这已经在这里的答案中得到了阐述。


他们应该是什么权限?
斯蒂芬,

这对我有用。谢谢!
Lordwhizy

19

谢谢大家检查问题,显然错误是在 bgsave

对我来说,键入config set stop-writes-on-bgsave-error noshell并重新启动Redis解决了该问题。


82
那没有“解决问题”,它只是忽略了它。
布法罗

在Services.msc中重新启动RedisServer对我有用。
ViPuL5

每当我重新启动服务器时,我都会再次遇到相同的问题。然后,我必须再次设置它。我如何使其永久化?
Zia Qamar '18

@ZiaQamar,您可以在redis.conf中永久设置该属性,该文件很可能位于/etc/redis/redis.conf中,设置“ stop-writes-on-bgsave-error no”
Gaurav Tyagi

IMO绝对不是解决方案。您只是在告诉Redis不要记录这些错误。但是错误仍然存​​在……
Erowlin

17

在具有Redis写入权限的目录中启动Redis Server

上面的答案肯定会解决您的问题,但实际上是这样:

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

似乎您已开始在Redis没有创建dump.rdb文件的正确权限的目录中运行Redis服务器。

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

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

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

(现在,如果您需要将dump.rdb文件保存在启动服务器的目录中,那么您将需要更改该目录的权限,以便Redis可以写入该目录。您可以搜索stackoverflow以了解如何执行该操作)。

现在,您应该能够关闭Redis服务器。请注意,我们对路径进行了硬编码。硬编码很少是一个好习惯,我强烈建议从您的项目目录启动redis服务器并更改dir key back to。/`。

CONFIG SET dir "./"
BGSAVE

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


确保您为转储文件将存储在的目录授予非root用户权限。就我而言,我有一个用户可以redis这样做: sudo chown redis:redis /var/lib/redis
RoundOutTooSoon

13

如果您正在运行MacOS,并且最近已升级到Catalina,则可能需要brew services restart redis按照本期建议运行。


12

曾遇到此错误,并且能够从日志中找出该错误是由于磁盘空间不足所致。在我的情况下,不再需要插入的所有数据。所以我试着去冲洗。由于redis-rdb-bgsave进程正在运行,因此也不允许刷新数据。我按照以下步骤操作,可以继续。

  1. 登录到Redis客户端
  2. 执行配置设置bgsave-stops-writes-on错误
  3. 执行FLUSHALL(不需要存储数据)
  4. 执行配置设置bgsave-stop-writes-on-bgsave-error是

完成上述步骤后,进程redis-rdb-bgsave不再运行。


7

我遇到了类似的问题,其背后的主要原因是redis占用的内存(RAM)。我的EC2机器有8GB RAM(可使用arounf 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 MACHINE

仅供参考:您可能需要安装htop才能完成此工作:sudo apt-get install htop

解决此问题的另一种方法是在系统上运行其他一些占用大量RAM的服务,检查服务器/机器/实例上是否正在运行其他服务,并在不需要时停止该服务。要检查计算机上运行的所有服务,请使用service --status-all

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

-更新-

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

maxmemory 6gb
maxmemory-policy allkeys-lru

您可以为这两个参数设置许多其他值,您可以从此处阅读有关此内容:https : //redis.io/topics/lru-cache


6

一个更永久的解决方法可能是在/etc/redis/redis.conf的第200-250行附近找到rdb功能的设置,这在2.x天内还不是redis的一部分。

明显地

dir ./

可以更改为

dir /home/someuser/redislogfiledirectory

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

另外,不要忘记

service redis-server stop
service redis-server start

6

所有这些答案都不能解释为什么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内核:[28152358.208108]杀死了进程28416(redis-server)total-vm:7660204kB,anon-rss:2285492kB,文件-rss:0kB

这就对了!此过程(redis save rdb)被OOM杀手杀死

指:

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

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


3

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


您如何确定内存溢出是问题所在?我可能遇到同样的问题。
DarthSpeedious

@DarthSpeedious我不记得了。如果我不得不猜测,我可能会说日志中的某些内容在抱怨无法分配内存。抱歉,我帮不上忙。
Ryan Angilly '16

首先,我认为结合使用swap和redis也是一个很好的解决方案,然后我进行了一些研究,找到了本文antirez.com/news/52,该文章声称使用redis是错误的方式,无论如何我不是100%同意,您对在交换中使用redis的性能满意吗?
talsibony

1
@DarthSpeedious在您的Redis日志中,您会看到“ 无法分配内存 ”错误。看到这里就怎么看日志文件:stackoverflow.com/questions/16337107/...
布鲁诺·佩雷斯

3

我也面临着同样的问题。答案(最受支持的答案和被接受的答案)都只是针对此问题的临时解决方案。

此外,这config set stop-writes-on-bgsave-error no是一种忽略此错误的可怕方法,因为此选项的作用是阻止Redis通知写入已停止并且继续运行而无需将数据写入快照。这只是忽略了此错误。 推荐这个

至于设置dirconfig在Redis的CLI,一旦你重新启动Redis的服务,这应太清除,同样的错误将再次弹出。的默认值dirredis.conf./,如果你开始Redis的作为root用户,然后.//不授予写权限的对象,因此会出现错误。

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


3

如今,Redis的写访问问题使此错误消息再次出现在客户端中 redis Docker容器中。

来自官方redis映像的 Redis 尝试将.rdb文件写入容器/data文件夹,这很不幸,因为它是root拥有的文件夹,并且它也是一个非永久位置(如果您的container / pod,写入那里的数据将消失崩溃)。

因此,在一个小时的不活动之后,如果您redis以非root用户身份运行容器(例如,docker run -u 1007而不是default docker run -u 0),则服务器日志中将出现非常详细的错误msg (请参阅参考资料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文件夹映射到外部位置(非root用户,在这里:1007,具有写访问权限,例如/tmp在主机上),例如:

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

因此,这是产生此“定时炸弹” 的官方docker映像(应写为/tmpnot /data)的错误配置,您很可能只会在生产中遇到……在某个特别安静的假期周末过夜:/


1
只是想在这里添加评论,因为这最终有助于解决我在Docker中遇到的redis问题。我们的UAT和Dev Docker服务器是Windows。Windows Defender会将RDB文件识别为潜在病毒。因此,挂载/ data目录将暂时解决父问题。直到Windows Defender隔离文件,从而导致另一个文件。确保将安装的数据目录添加为Windows Defender中的一个例外,以解决此问题。
TrevorB

1
提醒我:Windows Defender警报可能不一定是假阳性-即使在没有root用户且所有功能都掉落的情况下运行,cryptominer仍可能感染官方Redis映像-足以将其端口暴露于网络
mirekphd

谢谢,这是一个好点。只是好奇,但是RDB文件如何在主机上执行,尤其是Windows?我想它可能在容器本身内执行。但这不是特定于此特定容器的。
TrevorB

1
是的,有效负载可能无法在Windows上执行,除非完全用Lua编写,因此像Redis一样跨平台... eval命令是魔鬼的发明,与语言无关
mirekphd

这是一个启发性的经历。非常感谢。显然,我们的UAT / DEV撰写文件暴露了Docker网络外部的端口。我不知道这是怎么可能的,但是那些实例确实正在接收管理命令。正在推出一个加密矿工。我已禁用了这些端口,关闭了本地RDB挂载,并重新设置了Windows Defender异常(尽管,挂载关闭无关紧要)。我需要调查这些命令如何通过防火墙,但是我正在密切监视
TrevorB

3

为了我

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

我重新加载了Mac,它可以正常工作


1

在具有AFS磁盘空间的服务器上工作时,我遇到了此问题,因为我的身份验证令牌已过期,这Permission Denied在redis服务器尝试保存时产生了响应。我通过刷新令牌解决了这个问题:

kinit USERNAME_HERE -l 30d && aklog


1

如果您使用的是docker / 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

myou可以在此处查看更多用于删除持久数据的解决方案


1

就我而言,这是因为我只是redis使用快速方法进行安装。因此,redis不是以root身份运行。按照Installing Redis more properly他们的《快速入门指南》部分中的说明,我能够解决此问题。这样做之后,问题已解决,redis并且现在以root用户身份运行。一探究竟。


1

终于让我烦恼了这么多SO问题之后-对我来说@Axel Advento的答案行得通,但没有几个额外的步骤-我仍然遇到权限问题。
我必须将用户切换到redis,在其主目录中创建一个新目录,然后将其设置为redis的目录。

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


0

如果您在Windows计算机上本地运行Redis,请尝试“以管理员身份运行”,然后查看其是否有效。对于我来说,问题在于Redis位于“ Program Files”文件夹中,默认情况下会限制权限。正如它应该。

但是,不要以管理员身份自动运行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文件夹移到您知道具有正确权限的文件夹中。


0

对我来说,这只是永久性redis数据文件夹上的权限问题。我给它一个:

chmod 777 -Rf data/

而且有效!也许现在就说解决问题还为时过早。因为我也怀疑redis不是以root身份执行,所以我需要检查dockerFile找出更多信息。


0

在执行任何操作之前,请检查您的Redis日志。该线程中的某些解决方案可能会擦除您的Redis数据,因此请注意您在做什么。

就我而言,机器的RAM即将用完。当主机上没有更多可用磁盘空间时,也会发生这种情况。


0

请注意,服务器受到攻击时会出现此错误。刚刚发现redis无法写入“ /etc/cron.d/web”,在更正权限之后,添加了包含挖掘算法和一些隐藏选项的新文件。


0
# 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

正如@Chris指出的那样,问题很可能是内存不足。当我们为MySQL(innodb_buffer_pool_size)分配了过多的RAM时,我们就开始体验它。

为了确保有足够的RAM用于Redis和其他服务,我们innodb_buffer_pool_size在MySQL上进行了缩减。


-1

就我而言,原因是磁盘上的可用空间非常低(只有35 Mb)。我做了以下-

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

    sudo rm /var/lib/redis/*

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

    sudo redis-cli flushall

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

1
您必须在开发实例上完成此操作。在处理以数据为中心的应用程序时,不合适的解决方案。
Nikesh Devaki

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.