在写入 Redis ( SET foo bar
) 期间,我收到以下错误:
MISCONF Redis 配置为保存 RDB 快照,但目前无法持久保存在磁盘上。可能修改数据集的命令被禁用。请检查 Redis 日志以获取有关错误的详细信息。
基本上我知道问题是redis无法将数据保存在磁盘上,但不知道如何摆脱这个问题。
以下问题也有同样的问题,很久以前就被放弃了,没有答案,很可能没有尝试解决问题。
使用redis-cli
,您可以阻止它尝试保存快照:
config set stop-writes-on-bgsave-error no
这是一个快速的解决方法,但如果您关心使用它的数据,您应该首先检查以确定 bgsave 失败的原因。
重启你的 redis 服务器。
brew services restart redis
):。sudo service redis restart
/sudo systemctl restart redis
services.msc
,Enter-> 搜索,Redis
然后单击restart
。在使用 Brew ( ) 升级 redis 后,我个人遇到了这个问题brew upgrade
。重新启动笔记本电脑后,它立即工作。
如果您遇到错误并且无法丢弃正在运行的 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
is already0
和rdb_last_bgsave_status
is ok
。之后,您现在可以开始在安全的地方备份生成的rdb
文件。
由于内存不足,在 bgsave 过程中可能会出现错误。试试这个(来自redis后台保存FAQ)
echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf
sysctl vm.overcommit_memory=1
由于 BGSAVE 失败而发生此错误。在 BGSAVE 期间,Redis 分叉一个子进程以将数据保存在磁盘上。虽然可以从日志中检查 BGSAVE 失败的确切原因(通常在/var/log/redis/redis-server.log
linux 机器上),但很多时候 BGAVE 失败是因为 fork 无法分配内存。很多时候,由于操作系统的优化冲突,fork 无法分配内存(尽管机器有足够的可用 RAM)。
可以从Redis FAQ中阅读:
Redis 后台保存模式依赖于现代操作系统中 fork 的写时复制语义:Redis forks(创建子进程)是父进程的精确副本。子进程将数据库转储到磁盘上并最终退出。理论上,子进程应该使用与作为副本的父进程一样多的内存,但实际上由于大多数现代操作系统实现的写时复制语义,父进程和子进程将共享公共内存页面。仅当页面在子级或父级中发生更改时,才会复制页面。由于理论上所有页面都可能在子进程保存时发生变化,Linux 无法提前知道子进程将占用多少内存,因此如果将 overcommit_memory 设置设置为零,除非有足够的可用 RAM,否则 fork 将失败需要真正复制所有父内存页面,
将 overcommit_memory 设置为 1 表示 Linux 放松并以更乐观的分配方式执行分叉,这确实是您想要的 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
如果您在 linux 机器上工作,还要重新检查数据库的文件和文件夹权限。
可以通过以下方式获得数据库及其路径:
在redis-cli
:
配置获取目录
配置获取数据库文件名
并在命令行中ls -l
。目录的权限应该是755,文件的权限应该是644。此外,通常 redis-server 以 user 身份执行redis
,因此通过执行来授予用户redis
文件夹的所有权也很好sudo chown -R redis:redis /path/to/rdb/folder
。这已在此处的答案中进行了详细说明。
感谢大家检查问题,显然错误是在bgsave
.
对我来说,输入config set stop-writes-on-bgsave-error no
shell 并重新启动 Redis 解决了这个问题。
如果您正在运行 MacOS 并且最近升级到 Catalina,您可能需要按照本期brew services restart redis
的建议运行。
上面的答案肯定会解决您的问题,但实际情况如下:
存储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 用于另一个项目时,转储文件将在您当前项目的目录中创建,而不是在硬编码路径的项目目录中。
遇到了这个错误,并且能够从日志中找出错误是因为磁盘空间不足。不再需要插入到我的案例中的所有数据。所以我试图冲洗。由于 redis-rdb-bgsave 进程正在运行,它也不允许刷新数据。我按照以下步骤操作并能够继续。
在上述步骤之后,进程 redis-rdb-bgsave 不再运行。
$ redis-cli
配置集 stop-writes-on-bgsave-error 否
根据 Redis 文档,仅当您没有启用 RDB 快照或者您不关心快照中的数据持久性时,才建议这样做。
“默认情况下,如果启用 RDB 快照(至少一个保存点)并且最新的后台保存失败,Redis 将停止接受写入。这将使用户(以一种艰难的方式)意识到数据没有正确地保存在磁盘上,否则,强烈的文字很有可能没有人注意到,并且会发生一些灾难。”
你应该做的是:
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 后台保存开始 127.0.0.1:6379> 请确保 /data/tmp有足够的磁盘空间。
我遇到了类似的问题,这背后的主要原因是 redis 的内存(RAM)消耗。我的 EC2 机器有 8GB RAM(大约 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 命令并UPGRADE YOUR REDIS MACHINE。
仅供参考:您可能需要安装htop才能使这项工作:sudo apt-get install htop
对此的另一种解决方案可能是在您的系统上运行其他一些 RAM 重的服务,检查您的服务器/机器/实例上运行的其他服务,并在不需要时停止它。要检查您机器上运行的所有服务,请使用service --status-all
并且建议人们直接粘贴配置命令,请在使用此类命令之前进行一些重新搜索并至少警告用户。正如@Rodrigo 在他的评论中提到的那样:“忽略这些错误看起来并不酷。”
- -更新 - -
当达到特定的内存限制时,您还可以配置maxmemory
和定义 Redis 的行为。maxmemory-policy
例如,如果我想保持 6GB 的内存限制并从 DB 中删除最近最少使用的键以确保 redis mem 使用不超过 6GB,那么我们可以设置这两个参数(在 redis.conf 或 CONFIG SET命令):
maxmemory 6gb
maxmemory-policy allkeys-lru
您可以为这两个参数设置许多其他值,您可以从这里阅读:https ://redis.io/topics/lru-cache
一个更永久的修复可能是在 /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
为了我
config set stop-writes-on-bgsave-error no
我重新加载我的mac,它可以工作
所有这些答案都不能解释 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] 杀死进程 28416 (redis-server) total-vm:7660204kB, anon-rss:2285492kB,文件-rss:0kB
这就对了!这个进程(redis save rdb)被OOM杀手杀死
指:
如今,向客户端提供此错误消息的 Redis 写访问问题重新出现在官方redis
docker 容器中。
官方redis
镜像中的Redis尝试将 .rdb 文件写入容器/data
文件夹,这是相当不幸的,因为它是 root 拥有的文件夹并且它也是一个非持久位置(如果您的容器/pod 写入那里的数据将会消失崩溃)。
redis
因此,在闲置一个小时后,如果您以非 root 用户身份运行容器(例如,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
not /data
)产生这个“定时炸弹”,你很可能只会在生产中遇到......在某个特别安静的假期周末过夜:/
在线redis.conf
让~235
我们尝试像这样更改配置
- stop-writes-on-bgsave-error yes
+ stop-writes-on-bgsave-error no
FWIW,我遇到了这个问题,解决方案是简单地将交换文件添加到盒子中。我使用了这种方法:https ://www.digitalocean.com/community/tutorials/how-to-add-swap-on-ubuntu-14-04
我知道这个线程稍微旧一点,但是当我早些时候遇到这个错误时,这对我有用,因为我知道我离内存限制还很远——两个答案都在上面找到了。
希望这可以在将来需要时对某人有所帮助。
再次 - 不确定 DIR 文件夹的权限是如何更改的,但我假设 CHMOD 回到 755 并重新启动 redis-server 处理它,因为我之后能够 ping redis 服务器。
另请注意,redis 确实拥有 dbfilename 和 DIR 文件夹的所有权。
我也面临同样的问题。两个答案(最受支持的一个和接受的一个)都只是给出了一个临时解决方案。
此外,这config set stop-writes-on-bgsave-error no
是一种忽略此错误的可怕方法,因为此选项的作用是停止 redis 通知写入已停止并继续前进而不将数据写入快照中。这只是忽略了这个错误。
参考这个
至于redis-cli中的设置dir
,config
一旦你重启redis服务,这个也会被清除,同样的错误会再次弹出。dir
inredis.conf
的默认值为./
,如果您以 root 用户身份启动 redis,则./
不会/
授予其写入权限,因此会出现错误。
最好的方法是dir
在 redis.conf 文件中设置参数并对该目录设置适当的权限。大多数 debian 发行版都应该包含它/etc/redis/redis.conf
在最终解决了这么多 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)
是的,这是因为当前使用没有修改“dump.rdb”的权限。
因此,除了创建新的 RDB 文件之外,您还可以授予旧文件的权限(更改它的所有权)。
在 redis-cli 中输入:
config get dir
你会得到“/usr/local/var/db/redis”(这是redis写入数据的位置)
使用终端转到此位置
cd
cd /usr/local/var/db
键入此命令(使用我们的用户名):
sudo chown -R [username] db
这将更改为所有者。
这对我有用。
如果您使用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
我可以在此处查看更多删除持久数据的解决方案
在我的情况下,Ubuntu 虚拟机的磁盘空间已满,这就是我收到此错误的原因。从磁盘中删除一些文件后,问题已解决。
Permission Denied
我在使用 AFS 磁盘空间的服务器上工作时遇到了这个问题,因为我的身份验证令牌已过期,当 redis-server 尝试保存时会产生响应。我通过刷新我的令牌解决了这个问题:
kinit USERNAME_HERE -l 30d && aklog
就我而言,它发生是因为我刚刚redis
使用快速方式安装。所以redis没有以root身份运行。按照他们的快速入门指南Installing Redis more properly
部分下的说明,我能够解决这个问题。这样做之后,问题就解决了,现在以 root 身份运行。看看这个。redis
在采取任何行动之前检查您的 Redis 日志。此线程中的某些解决方案可能会擦除您的 Redis 数据,因此请小心您正在做的事情。
就我而言,机器内存不足。当主机上没有更多可用磁盘空间时,也会发生这种情况。
如果您在 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 文件夹移动到您知道具有正确权限的文件夹中。
就我而言,它与磁盘可用空间有关。(你可以用df -h
bash 命令检查它)当我释放一些空间时,这个错误消失了。
请注意,当您的服务器受到攻击时会出现此错误。刚刚发现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
检查 dir 中的权限: var/lib/redis 它应该是 redis:redis
正如@Chris 所指出的,问题很可能是内存不足。当我们为 MySQL ( ) 分配了过多的 RAM 时,我们开始遇到这种情况innodb_buffer_pool_size
。
为了确保 Redis 和其他服务有足够的 RAM,我们减少innodb_buffer_pool_size
了 MySQL。
就我而言,原因是磁盘中的可用空间非常低(只有 35 Mb)。我做了以下 -
删除redis转储文件(如果不需要现有数据)
sudo rm /var/lib/redis/*
删除所有现有数据库的所有键
sudo redis-cli flushall
你必须 chmod 和 chown 新文件夹
chown -R redis 和 chmod ...