【问题标题】:Redis telling me "Failed opening .rdb for saving: Permission denied"Redis 告诉我“无法打开 .rdb 进行保存:权限被拒绝”
【发布时间】:2017-02-26 23:47:40
【问题描述】:

我在 Debian 服务器 8.5 上运行 Redis 服务器 2.8.17。我使用 Redis 作为 Django 1.8.4 应用程序的会话存储。

我已经有几个月没有更改服务器上的软件配置了,直到一周前 Django 开始引发以下错误时,一切都运行良好:

MISCONF Redis is configured to save RDB snapshots but is currently not able to persist to disk.  Commands that may modify the data set are disabled.  Please check Redis logs for details...

我检查了 redis 日志,发现这种情况大约每秒发生一次:

1 changes in 900 seconds.  Saving...
Background saving started by pid 22213
Failed opening .rdb for saving: Permission denied
Background saving error

我已经阅读了这两个 SO 问题12,但它们并没有帮助我找到问题所在。

ps 显示用户“redis”正在运行服务器:

redis   26769   ...   /usr/bin/redis-server *.6379

我检查了我的配置文件中的 redis 文件名和路径:

grep ^dir /etc/redis/redis.conf =>
dir /var/lib/redis

grep ^dbfilename /etc =>
dbfilename dump.rdb

/var/lib/redis 的权限为 755,归 redis:redis 所有。 /var/lib/redis/dump.rdb 的权限是 644,它也归 redis:redis 所有。

我还在服务器进程上运行了 strace:

ps -C redis-server  # pid = 26769
sudo strace -p 26769 -o /tmp/strace.out

但是当我检查输出时,我没有看到任何错误。特别是,我没有看到预期的“权限被拒绝”错误。

另外,/var/lib/redis 不是 NFS 目录。

有谁知道还有什么可能导致这种情况?我不想不得不停止使用 Redis。我知道我可以运行命令“set stop-writes-on-bgsave-error yes”,但这并不能解决问题。

现在每天都在发生这种情况,我可以阻止错误的唯一方法是重新启动 Redis 服务器。

谢谢。

【问题讨论】:

  • 这个输出:grep ^dir /etc/redis/redis.conf => dir /var/lib/redisredis/redis.conf准确吗?
  • 另外,为什么您的日志文件引用一个 PID 22213,而您的 ps 命令显示另一个?这只是时间上的怪癖,还是您在调试命令之间重新启动了 redis?
  • 抱歉,这是我在问题中修正的 grep 中的错字。我相信 PID 22213 是指一个新的后台保存进程,而不是 PID 为 26769 的 Redis 服务器进程本身。
  • 你已经完成lsof /var/lib/redis/dump.rdb了吗?

标签: django redis


【解决方案1】:

我刚刚遇到了类似的问题。尽管我的配置文件是正确的,但当我在 redis-client 中检查实际的 dbfilename 和 dir 时,它们是不正确的。

运行redis-cli,然后

CONFIG GET dbfilenamewhich 应该返回类似

1) "dbfilename"
2) "dump.rdb"

1) 只是键和 2) 值。同样,然后运行 ​​CONFIG GET dir 应该返回类似

1) "dir"
2) "/var/lib/redis"

确认这些是正确的,如果不正确,请将它们设置为CONFIG SET dir /correct/path

希望这会有所帮助!

【讨论】:

  • 帮帮我,我的设置为/。谢谢!
【解决方案2】:

如果您已将 Redis 移动到新的挂载卷:/mnt/data-01

sudo vim /etc/systemd/system/redis.service

Set ReadWriteDirectories=-/mnt/data-01

sudo mkdir /mnt/data-01/redis

在新的 redis 数据目录和 rdb 文件上设置 chown 和 chmod。
/var/lib/redis 的权限是 755,它归 redis:redis 所有
/var/lib/redis/dump.rdb 上的权限是 644,它归 redis:redis 所有

在 redis 运行时切换配置

$ redis-cli
127.0.0.1:6379> CONFIG SET dir /data/tmp
redis-cli 127.0.0.1:6379> CONFIG SET dbfilename temp.rdb
127.0.0.1:6379> BGSAVE
tail /var/log/redis/redis.cnf(确认已保存)

【讨论】:

  • 我在从14.04升级到16.04的过程中遇到了这个问题,将redis从版本2升级到版本3。数据目录是非标准的,需要在/ etc中添加为ReadWriteDirectories /systemd/system/redis.service 文件。非常感谢!
【解决方案3】:

在Redis有写权限的目录下启动Redis Server

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

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

由于您说您的 redis 服务器已经运行了一段时间并且这才刚刚开始发生,因此您似乎已经开始在 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 用于另一个项目时,转储文件将在你当前项目的目录中创建,而不是在硬编码路径的项目目录中。

【讨论】:

    【解决方案4】:

    在 redis 3.2 之前,它附带了相当疯狂的默认设置,向公众开放了端口。结合CONFIG SET 指令,每个人都可以轻松地从外部更改您的 redis 配置。如果错误在一段时间后开始出现,则可能有人更改了您的配置。

    在你的本地机器上检查

    telnet SERVER_IP REDIS_PORT
    

    被拒绝。否则检查你的配置,你应该有设置

    bind 127.0.0.1
    

    已启用。

    取决于运行 redis 的用户,您还应该检查入侵者造成的损害。

    【讨论】:

      【解决方案5】:

      你可以通过进入redis-cli解决这个问题

      在终端输入redis-cli

      然后写config set stop-writes-on-bgsave-error no,它解决了我的问题。

      希望它能解决您的问题

      【讨论】:

        猜你喜欢
        • 2014-04-05
        • 1970-01-01
        • 2017-03-25
        • 2019-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-11
        • 2012-07-07
        相关资源
        最近更新 更多