MISCONF Redis 配置为保存 RDB 快照
Posted
技术标签:
【中文标题】MISCONF Redis 配置为保存 RDB 快照【英文标题】:MISCONF Redis is configured to save RDB snapshots 【发布时间】:2013-11-04 01:16:49 【问题描述】:在写入 Redis (SET foo bar
) 期间,我收到以下错误:
,但当前 无法在磁盘上持久化。可能修改数据集的命令是 禁用。有关错误的详细信息,请查看 Redis 日志。
基本上我知道问题是redis无法将数据保存在磁盘上,但不知道如何解决这个问题。
the following question 也有同样的问题,很久以前就放弃了,没有答案,很可能没有尝试解决问题。
【问题讨论】:
您能否解决此问题。如果是,请您协助完成这些步骤。因为我猜将 rdb 文件放在其他地方不会解决它。我想我在这里遗漏了一些东西 这个错误是因为在redis没有权限的目录下启动redis服务器。我建议在解决问题后恢复为默认设置:请参阅 answer 了解有关此问题的修复。 除了 Govind Rai 的回答:***.com/a/47880440/5649620 @GovindRai 我已经通过将组和所有者更改为redis
来授予 redis 权限,但没有帮助!
作为第一次快速检查,请确保磁盘上有剩余空间
【参考方案1】:
使用redis-cli
,您可以阻止它尝试保存快照:
config set stop-writes-on-bgsave-error no
这是一个快速的解决方法,但如果您关心使用它的数据,您应该首先检查以确定 bgsave 失败的原因。
【讨论】:
这是一个快速的解决方法,但您应该首先检查以确定 bgsave 失败的原因 如果你主要用redis做缓存和会话,这个是必须的。 这不危险吗?例如,NodeBB 使用 Redis 作为数据存储。 @LoveToCode 配置设置 stop-writes-on-bgsave-error 是 每当我重新启动服务器时,我都会再次遇到同样的问题。然后我必须重新设置它。我怎样才能让它永久化?【参考方案2】:重启你的 redis 服务器。
macOS (brew):brew services restart redis
.
Linux: sudo service redis restart
/ sudo systemctl restart redis
Windows: Windows + R -> 输入services.msc
,回车 -> 搜索Redis
然后点击在restart
。
在使用 Brew (brew upgrade
) 升级 redis 后,我个人遇到了这个问题。
重新启动笔记本电脑后,它立即工作。
【讨论】:
如果有人在读这篇文章,我也遇到了 Homebrew 的问题,但与升级无关:我只需要使用sudo
:brew services stop redis; sudo brew services start redis
启动服务。
伙计,这太明显了)谢谢
经典的“您是否尝试过将其关闭然后重新打开”的答案有帮助
在我的情况下(macOS),它有效!我认为是 Big Sur 更新导致的,因此某些 brew 系统需要更新一次
我尝试brew uninstall redis
和brew install redis
重新安装,但没有成功,但成功了!【参考方案3】:
如果遇到错误,在运行的redis实例上某些重要数据无法丢弃(rdb
文件或其目录权限错误,或者磁盘空间不足),可以随时重定向@ 987654322@ 文件写入其他地方。
使用redis-cli
,您可以执行以下操作:
CONFIG SET dir /tmp/some/directory/other/than/var
CONFIG SET dbfilename temp.rdb
之后,您可能需要执行BGSAVE
命令以确保将数据写入rdb
文件。确保当你执行INFO persistence
时,bgsave_in_progress
已经是0
并且rdb_last_bgsave_status
是ok
。之后,您现在可以开始将生成的rdb
文件备份到安全的地方。
【讨论】:
rdb_bgsave_in_progress:0 在 Persistence 下 由于某种原因,当我尝试任何配置集命令时,它就像永远加载一样。 对于那些在 Windows 上的不幸的人,我现在和哇正在使用 MSOpenTech 版本,您必须按照以下样式设置目录路径:dir C:/Temp/
。执行 bgsave 以验证它是否有效..
127.0.0.1:6379> CONFIG SET dir /root/tool (error) ERR 更改目录:权限被拒绝
BGSAVE
不会立即告诉您它是失败还是成功。你必须先重复INFO persistence
,然后等到rdb_bgsave_in_progress
变成0
。之后,检查rdb_last_bgsave_status
是否为ok
。【参考方案4】:
由于内存不足,在 bgsave 过程中可能会出现错误。试试这个(来自redis后台保存FAQ)
echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf
sysctl vm.overcommit_memory=1
【讨论】:
LInk: redis.io/topics/faq 搜索此内容:“即使我有很多可用 RAM,在 Linux 下后台保存也会失败并出现 fork() 错误!” 【参考方案5】:出现此错误是因为 BGSAVE 失败。在 BGSAVE 期间,Redis 分叉一个子进程以将数据保存在磁盘上。虽然可以从日志中检查 BGSAVE 失败的确切原因(通常在 Linux 机器上的 /var/log/redis/redis-server.log
),但很多时候 BGAVE 失败是因为分叉无法分配内存。很多时候,由于操作系统的优化冲突,fork 无法分配内存(尽管机器有足够的可用 RAM)。
可以从Redis FAQ阅读:
Redis 后台保存模式依赖于现代操作系统中 fork 的写时复制语义:Redis fork(创建子进程)是父进程的精确副本。子进程将数据库转储到磁盘上并最终退出。理论上,子进程应该使用与作为副本的父进程一样多的内存,但实际上由于大多数现代操作系统实现的写时复制语义,父进程和子进程将共享公共内存页面。仅当页面在子级或父级中发生更改时,才会复制页面。由于理论上所有页面都可能在子进程保存时发生变化,Linux 无法提前知道子进程将占用多少内存,因此如果将 overcommit_memory 设置设置为零,除非有足够的可用 RAM,否则 fork 将失败需要真正复制所有父内存页面,结果如果您有一个 3 GB 的 Redis 数据集和只有 2 GB 的可用内存,它将失败。
将 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
【讨论】:
systemctl status redis
的输出显示有一条警告建议完全更改 overcommit_memory=0
设置。改变这确实解决了我的问题。
这正确解决了问题,应该是公认的答案
所以 tldr 在默认设置下是这样的
@DanHastings - 是的。并且将 overcommit_memory 设置为 1 可以放宽这个要求。
@Bhindi:非常感谢 - 这对我来说非常有用!!!!一个快速的问题是这是否会影响任何其他与 sidekiq 相关的流程或任何重要的事情?【参考方案6】:
如果您在 linux 机器上工作,还要重新检查数据库的文件和文件夹权限。
可以通过以下方式获得数据库及其路径:
在redis-cli
:
配置获取目录
配置获取数据库文件名
在命令行中ls -l
。目录的权限应该是755,文件的权限应该是644。此外,通常 redis-server 以用户 redis
的身份执行,因此通过执行 sudo chown -R redis:redis /path/to/rdb/folder
来授予用户 redis
文件夹的所有权也很好。这已在答案here中详细说明。
【讨论】:
他们应该是什么权限?【参考方案7】:感谢大家排查问题,显然错误是在bgsave
期间产生的。
对我来说,在 shell 中输入 config set stop-writes-on-bgsave-error no
并重新启动 Redis 即可解决问题。
【讨论】:
这并没有“解决问题”,只是忽略了它。 在 Services.msc 中重新启动 RedisServer 对我有用。 每当我重新启动服务器时,我都会再次遇到同样的问题。然后我必须重新设置它。我怎样才能让它永久化? @ZiaQamar,你可以在redis.conf中永久设置属性,很可能在/etc/redis/redis.conf,设置“stop-writes-on-bgsave-error no” IMO 绝对不是解决方案。您只是告诉 Redis 不要记录这些错误。但是错误仍然存在...【参考方案8】:如果您正在运行 MacOS 并且最近升级到 Catalina,您可能需要按照 this issue 中的建议运行 brew services restart redis
。
【讨论】:
【参考方案9】:在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 可以写入该目录. 你可以搜索 *** 以了解如何做到这一点)。
您现在应该可以关闭 redis 服务器了。请注意,我们对路径进行了硬编码。硬编码很少是一种好的做法,我强烈建议从项目目录启动 redis 服务器并更改 dir key back to
./`。
CONFIG SET dir "./"
BGSAVE
这样当你需要 redis 用于另一个项目时,转储文件将在你当前项目的目录中创建,而不是在硬编码路径的项目目录中。
【讨论】:
确保授予非 root 用户对存储转储文件的目录的权限。就我而言,我有一个用户redis
,所以我这样做:sudo chown redis:redis /var/lib/redis
非常简单有用的解释【参考方案10】:
遇到了这个错误,并且能够从日志中找出错误是因为磁盘空间不足。不再需要插入到我的案例中的所有数据。所以我试图冲洗。由于 redis-rdb-bgsave 进程正在运行,它也不允许刷新数据。我按照以下步骤操作并能够继续。
-
登录redis客户端
执行config set stop-writes-on-bgsave-error no
执行FLUSHALL(不需要存储的数据)
执行config set stop-writes-on-bgsave-error yes
经过上述步骤,进程 redis-rdb-bgsave 不再运行。
【讨论】:
【参考方案11】:$ 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 有足够的磁盘空间。
【讨论】:
如何检查 BGSAVE 命令是否/何时完成?【参考方案12】:我遇到了类似的问题,这背后的主要原因是 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 命令并升级您的 REDIS 机器。
仅供参考:您可能需要安装 htop 才能完成这项工作:sudo apt-get install htop
另一个解决方案可以是您的系统上运行的其他一些 RAM 重的服务,检查您的服务器/机器/实例上运行的其他服务,如果不需要,请停止它。要检查您机器上运行的所有服务,请使用service --status-all
对于直接粘贴配置命令的人的建议,请在使用此类命令之前进行一些重新搜索并至少警告用户。正如@Rodrigo 在他的评论中提到的那样:“忽略这些错误看起来并不酷。”
---更新---
您还可以配置maxmemory
和maxmemory-policy
来定义达到特定内存限制时Redis 的行为。
例如,如果我想保持 6GB 的内存限制并从 DB 中删除最近最少使用的键以确保 redis mem 使用不超过 6GB,那么我们可以设置这两个参数(在 redis.conf 或 CONFIG SET命令):
maxmemory 6gb
maxmemory-policy allkeys-lru
您可以为这两个参数设置许多其他值,您可以从这里阅读:https://redis.io/topics/lru-cache
【讨论】:
【参考方案13】:更永久的解决方法可能是在 /etc/redis/redis.conf 中的 200-250 行附近查看 rdb 功能的设置,这些设置在 2.x 时代不是 redis 的一部分。
明显
dir ./
可以改成
dir /home/someuser/redislogfiledirectory
或者你可以注释掉所有的保存行,而不用担心持久性。 (参见 /etc/redis/redis.conf 中的 cmets)
还有,别忘了
service redis-server stop
service redis-server start
【讨论】:
停止并开始确实为我修复了它:)【参考方案14】:对我来说
config set stop-writes-on-bgsave-error no
然后我重新加载我的 mac,它可以工作
【讨论】:
【参考方案15】:所有这些答案都没有解释 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 killer杀死了
指:
https://github.com/antirez/redis/issues/1886
Finding which process was killed by Linux OOM killer
【讨论】:
【参考方案16】:如今,在官方redis
docker 容器中重新出现了向客户端提供此错误消息的 Redis 写访问问题。
来自the official redis
image 的 Redis 尝试将 .rdb 文件写入容器 /data
文件夹中,这是相当不幸的,因为它是根拥有的文件夹并且它也是一个非持久位置(写入那里的数据将如果您的容器/pod 崩溃,则消失)。
因此,在闲置一个小时后,如果您以非 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
),它产生了这个“定时炸弹”,你很可能只会在生产中遇到......在一夜之间,在一些特别安静的地方假期周末:/
【讨论】:
只是想在这里添加评论,因为这最终帮助解决了我在 Docker 中使用 redis 时遇到的问题。我们的 UAT 和 Dev Docker 服务器是 Windows。 Windows Defender 会将 RDB 文件识别为潜在病毒。因此挂载 /data 目录将暂时解决父问题;直到 Windows Defender 隔离该文件,导致另一个。确保在 Windows Defender 中将已挂载的数据目录添加为例外以解决此问题。 提醒我:Windows Defender 警报可能不一定是误报 - 即使在没有 root 的情况下运行并删除所有功能的情况下,加密矿工也可以感染官方 Redis 映像 - 将其端口暴露给网 谢谢,这很好。只是好奇,但是 RDB 文件将如何在主机上执行,尤其是 Windows 文件?我想它可能在容器本身内执行。但这并不特定于这个特定的容器。 对,payload 可能无法在 Windows 上执行,除非完全用 Lua 编写,因此与 Redis 本身一样跨平台...... eval 命令是魔鬼的发明,不管是什么语言跨度> 这是一次启发性的经历;非常感谢。显然,我们的 UAT/DEV 组合文件暴露了 Docker 网络之外的端口。我不知道这怎么可能,但这些实例正在接收管理命令,而且确实如此。正在启动一个加密矿工。我已经禁用了这些端口,关闭了本地 RDB 挂载,并重新设置了 Windows Defender 异常(不过,这与挂载无关)。我需要调查这些命令是如何通过我们的防火墙的,但我正在密切监视【参考方案17】:在redis.conf
行~235
让我们尝试像这样更改配置
- stop-writes-on-bgsave-error yes
+ stop-writes-on-bgsave-error no
【讨论】:
注意:在 macOS 上,这个文件位于 /usr/local/etc/redis.conf,你需要运行这个命令来重启 redis:brew services restart redis【参考方案18】:FWIW,我遇到了这个问题,解决方案是简单地将交换文件添加到框中。我用了这个方法:https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-ubuntu-14-04
【讨论】:
您是如何发现内存溢出问题的?我可能遇到了同样的问题。 @DarthSpeedious 我不记得了。如果我不得不猜测,我会说日志中的某些内容可能在抱怨无法分配内存。抱歉,我不能提供更多帮助。 首先我认为将交换和redis结合使用也是一个很好的解决方案,然后我做了一些研究并找到了这篇文章antirez.com/news/52,它声称这是使用redis的错误方式,反正我不是 100% 同意,你对使用 redis 和 swap 的表现满意吗? @DarthSpeedious 在您的 Redis 日志中,您会看到“无法分配内存”错误。请参阅此处了解如何查看日志文件:***.com/questions/16337107/…【参考方案19】:我知道这个线程稍微旧一点,但是当我早先遇到这个错误时,这对我有用,因为我知道我远未接近内存限制 - 两个答案都在上面找到。
希望这可以在将来需要时对某人有所帮助。
-
检查了 dir 文件夹上的 CHMOD... 发现符号符号有所不同。 CHMOD dir 文件夹到 755
dbfilename 权限很好,无需更改
重新启动redis-server
(应该先这样,但是啊)引用redis-server.log,发现错误是访问被拒绝的结果。
再次不确定 DIR 文件夹的权限是如何更改的,但我假设 CHMOD 回到 755 并重新启动 redis-server 处理它,因为之后我能够 ping redis 服务器。
还要注意,redis 确实拥有 dbfilename 和 DIR 文件夹的所有权。
【讨论】:
【参考方案20】:我也面临同样的问题。两个答案(最受支持的一个和接受的一个)都只是给出了一个临时解决方案。
此外,config set stop-writes-on-bgsave-error no
是一种忽略此错误的可怕方法,因为此选项的作用是阻止 redis 通知写入已停止,并继续前进而不将数据写入快照中。这只是忽略了这个错误。
Refer this
关于在redis-cli中设置config
中的dir
,一旦你重启redis服务,这个也会被清除,同样的错误会再次弹出。 redis.conf
中dir
的默认值是./
,如果你以root用户启动redis,那么./
是/
,不授予写权限,因此报错。
最好的方法是在 redis.conf 文件中设置dir
参数并对该目录设置适当的权限。大多数 debian 发行版都应该在/etc/redis/redis.conf
【讨论】:
【参考方案21】:在解决了这么多 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)
【讨论】:
【参考方案22】:是的,这是因为当前使用没有权限修改“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
这将更改为所有者。
这对我有用。
【讨论】:
【参考方案23】:如果您使用 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 文件中注释掉这 3 行
save 900 1
save 300 10
save 60 10000
你可以查看更多删除持久化数据的解决方案here
【讨论】:
【参考方案24】:在我的情况下,Ubuntu 虚拟机的磁盘空间已满,这就是我收到此错误的原因。从磁盘中删除一些文件后问题已解决。
【讨论】:
【参考方案25】:我在具有 AFS 磁盘空间的服务器上工作时遇到了这个问题,因为我的身份验证令牌已过期,当 redis-server 尝试保存时产生了 Permission Denied
响应。我通过刷新我的令牌解决了这个问题:
kinit USERNAME_HERE -l 30d && aklog
【讨论】:
【参考方案26】:就我而言,这是因为我刚刚使用快速方式安装了redis
。所以redis没有以root身份运行。
我能够按照他们的Quick Start Guide 的Installing Redis more properly
部分下的说明解决这个问题。这样做之后,问题就解决了,redis
现在以 root 身份运行。看看吧。
【讨论】:
【参考方案27】:在采取任何措施之前检查您的 Redis 日志。此线程中的某些解决方案可能会擦除您的 Redis 数据,因此请小心您的操作。
在我的例子中,机器的 RAM 用完了。当主机上没有更多可用磁盘空间时,也会发生这种情况。
【讨论】:
【参考方案28】:在我的情况下,它与磁盘可用空间有关。 (您可以使用df -h
bash 命令检查它)当我释放一些空间时,此错误消失了。
【讨论】:
【参考方案29】:如果您在 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 文件夹移动到您知道具有正确权限的文件夹中。
【讨论】:
【参考方案30】:请注意,当您的服务器受到攻击时会出现此错误。刚刚发现redis无法写入'/etc/cron.d/web',在更正权限后,添加了由挖掘算法和一些隐藏选项组成的新文件。
【讨论】:
以上是关于MISCONF Redis 配置为保存 RDB 快照的主要内容,如果未能解决你的问题,请参考以下文章
redis出现MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on
redis出现MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on
Redis "MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on di
MISCONF Redis is configured to save RDB snapshots
MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk