MISCONF Redis配置为保存RDB快照

时间:2013-10-25 04:23:29

标签: redis

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

  

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

基本上我明白问题是redis无法在磁盘上保存数据,但不知道如何摆脱这个问题。

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

37 个答案:

答案 0 :(得分:243)

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

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

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

答案 1 :(得分:149)

如果您遇到错误并且某些重要数据无法在正在运行的redis实例上丢弃(rdb文件或其目录的权限问题不正确,或磁盘空间不足),您始终可以重定向要写在其他地方的rdb文件。

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

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

在此之后,您可能希望执行BGSAVE命令以确保将数据写入rdb文件。确保执行INFO时,bgsave_in_progress已经0(操作成功或遇到错误)。之后,您现在可以开始在安全的地方备份生成的rdb文件。

答案 2 :(得分:49)

由于内存不足,在bgsave过程中可能会出现错误。试试这个(从redis背景保存常见问题解答)

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

答案 3 :(得分:25)

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

Redis FAQ可以看到:

  

Redis后台保存模式依赖于现代操作系统中fork的copy-on-write语义:Redis forks(创建子进程),它是父进程的精确副本。子进程将数据库转储到磁盘上,最后退出。理论上,孩子应该使用尽可能多的内存作为副本,但实际上由于大多数现代操作系统实现的写时复制语义,父和子进程将共享公共内存页。仅当页面在子项或父项中发生更改时,页面才会重复。由于理论上所有页面都可能在子进程保存时发生变化,因此Linux无法预先知道子进程将占用多少内存,因此如果将overcommit_memory设置设置为零,则除非有尽可能多的自由,否则fork将失败RAM需要真正复制所有父内存页面,结果是如果你有一个3 GB的Redis数据集和2 GB的可用内存,它将会失败。

     

将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

答案 4 :(得分:22)

如果您正在使用Linux计算机,还要重新检查数据库的文件和文件夹权限。

db及其路径可以通过以下方式获得:

redis-cli中的

  

CONFIG GET dir

     

CONFIG GET dbfilename

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

答案 5 :(得分:17)

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

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

答案 6 :(得分:15)

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

上面的答案肯定会解决你的问题,但这是实际发生的事情:

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

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

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

要解决此问题,您必须使用redis-cli进入活动的redis客户端环境并更新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用于另一个项目时,转储文件将在你当前项目的目录中创建,而不是在硬编码路径的项目目录中。

答案 7 :(得分:6)

如果您正在运行MacOS,并且最近已升级到Catalina,则可能需要按照this issue中的建议运行LBLBuku.Text >= 5

答案 8 :(得分:5)

一个更永久的修复可能是在/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

答案 9 :(得分:5)

所有这些答案都没有解释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,file-rss:0kB

是的,就是这样!此过程(redis save rdb)被OOM killer

杀死

是指:

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

Finding which process was killed by Linux OOM killer

答案 10 :(得分:5)

$ redis-cli

<块引用>

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

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

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

你应该做的是:

redis-cli

127.0.0.1:6379> 配置设置目录 /data/tmp 行 127.0.0.1:6379> 配置集 dbfilename temp.rdb 行 127.0.0.1:6379> BGSAVE 后台保存开始 127.0.0.1:6379> 请确保 /data/tmp 有足够的磁盘空间。

答案 11 :(得分:5)

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

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

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

答案 12 :(得分:3)

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

答案 13 :(得分:3)

我知道这个线程稍旧一些,但是当我更早遇到此错误时,这就是对我有用的方法,因为我知道我距离内存限制还很遥远-上面都找到了两个答案。

希望这对将来某人有帮助。

  1. 检查dir文件夹上的CHMOD ...发现符号表示法有所不同。 CHMOD目录文件夹到755
  2. dbfilename权限很好,不需要更改
  3. 重新启动redis服务器
  4. (应该先这样做,但是很好)参考redis-server.log,发现错误是由于访问被拒绝引起的。

再次不确定DIR文件夹的权限是如何更改的,但是我假设CHMOD回到755,然后重新启动redis-server来解决这个问题,因为之后我就可以ping redis服务器了。

还要注意,redis确实拥有dbfilename和DIR文件夹的所有权。

答案 14 :(得分:2)

我也面临同样的问题。这两个答案(最受欢迎的答案和被接受的答案)只是给出了相同的临时解决方案。

此外,with open('test.txt', 'r') as f: # Do stuff with f # At this point, f will always be closed, even in case of exceptions 是查看此错误的一种可怕方式,因为此选项的作用是阻止redis通知写入已停止并继续前进而不在快照中写入数据。这只是忽略了这个错误。 Refer this

至于在redis-cli的config set stop-writes-on-bgsave-error no中设置dir,一旦你重新启动redis服务,它也会被清除,同样的错误会再次弹出。 configdir的默认值为redis.conf,如果您以root用户身份启动redis,则././,写权限不是{39}} ; t被授予,因而错误。

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

答案 15 :(得分:2)

我遇到了类似的问题,其背后的主要原因是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

另一个解决方案,这可以是系统上正在运行其他一些占用大量内存的服务,请检查服务器/机器/实例上是否正在运行其他服务,并在不需要时停止该服务。要检查计算机上运行的所有服务,请使用service --status-all

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

答案 16 :(得分: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)

答案 17 :(得分:1)

就我而言,这是因为我只是使用快速方法安装了redis。因此,redis不是以root身份运行。 我能够按照其Quick Start GuideInstalling Redis more properly部分下的说明来解决此问题。这样做之后,问题已解决,redis现在以root用户身份运行。看看。

答案 18 :(得分:1)

对我

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

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

答案 19 :(得分:1)

如今,Redis的写访问问题将此错误消息提供给客户端,并重新出现在官方redis码头工人容器中。

来自the official redis image

Redis尝试将.rdb文件写入容器/data文件夹中,这很不幸,因为它是根目录拥有的文件夹,并且它也是一个非永久性位置(如果您的容器/容器崩溃,则其中写入的数据将消失。

因此,在一个小时的不活动之后,如果您以非root用户身份运行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文件夹映射到外部位置(非root用户在这里:1007,具有写访问权限,例如主机上的/tmp ),例如:

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

因此,是产生此“定时炸弹”的官方docker映像(应写入/tmp而不是/data的错误配置),您很可能仅在生产中遇到……在一些特别安静的假期周末:/

答案 20 :(得分:1)

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

kinit USERNAME_HERE -l 30d && aklog

答案 21 :(得分:0)

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

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

答案 22 :(得分: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

答案 23 :(得分:0)

检查目录中的权限:var/lib/redis 应该是redis:redis

答案 24 :(得分:0)

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

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

在 redis-cli 中输入:

coverage --version

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

使用终端去这个位置

config get dir

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

cd 
cd /usr/local/var/db

这将更改为所有者。

这对我有用。

答案 25 :(得分:0)

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

答案 26 :(得分:0)

就我而言,Ubuntu 虚拟机的磁盘空间已满,这就是我收到此错误的原因。从磁盘中删除一些文件后问题已解决。

答案 27 :(得分:0)

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

在我的情况下,计算机用尽了 RAM 。当主机上没有 可用磁盘空间 时,也会发生这种情况。

答案 28 :(得分:0)

使用brew upgrade升级Redis后,我遇到了这个问题。

重新启动后,它工作正常。也许重启redis实例可能会有所帮助。

brew services restart redis

答案 29 :(得分:0)

就我而言,这与磁盘可用空间有关。 (您可以使用df -h bash命令进行检查),当我释放一些空间时,该错误消失了。

答案 30 :(得分:0)

您必须chmod并锁定新文件夹

小丑-R redis 和chmod ...

答案 31 :(得分:0)

如果您使用的是 docker / docker-compose ,并且要防止Redis写入文件,则可以创建Redis配置并挂载到容器中

docker.compose.override.yml

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

您可以从here

下载默认配置

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

save 900 1
save 300 10
save 60 10000

您可以查看更多用于删除持久数据here

的解决方案

答案 32 :(得分:0)

如果您在Windows计算机上本地运行Redis,请尝试以#34;以管理员身份运行&#34;看看它是否有效对我来说,问题是Redis位于&#34; Program Files&#34;文件夹,默认情况下限制权限。应该如此。

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

答案 33 :(得分:0)

在我的情况下,原因是磁盘中的可用空间非常低(仅35 Mb)。我做了以下 -

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

    sudo rm /var/lib/redis/*

  4. 删除所有现有数据库的所有密钥

    sudo redis-cli flushall

  5. 重启所有celery任务并检查相应日志是否存在任何问题

答案 34 :(得分:0)

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

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

答案 35 :(得分:-1)

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

chmod 777 -Rf data/

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

答案 36 :(得分:-1)

解决@Govind Rai''将dump.rdb文件保存在启动服务器的目录中':

右键单击Redis文件夹,单击“属性”,然后单击“安全”选项卡。 单击“编辑”以打开“权限”对话框。

单击所有应用程序包

在“权限”框中,选中“允许”复选框“完全控制”。