报错信息

raise response
redis. exceptions. ResponseError: MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error

这个报错是因为 Redis 配置了保存 RDB 快照,但是当前无法将快照持久化到磁盘上。可能的原因是硬盘空间已满,权限问题导致的保存快照失败(Redis 没有 RDB 文件的写权限)或者 Redis 没有足够的内存来执行这个操作。

一般情况下是磁盘空间问题,首先检查一下磁盘空间,清理一下内存。重启一下 redis 数据库。

  • macOS (brew)brew services restart redis.
  • Linux: sudo service redis restart / sudo systemctl restart redis
  • Windows: Windows + R -> Type services.msc, Enter -> Search for Redis then click on restart.
  • 容器:docker restart <redis_container_name>

重启完测试一下写数据,一般就正常了。

1
2
3
4
5
6
7
8
9
10
11
from redis import Redis, ConnectionPool  

conn_pool = ConnectionPool(decode_responses=True, host='', port=, db=)
__conn = Redis(connection_pool=conn_pool)

keys = __conn.keys()
print(keys)
# 写数据
__conn.set('name', 'flyrr')
# 读数据
print(__conn.get('name'))

我检查了磁盘空间正常,检查了 Redis 的日志发现

1
Failed opening the RDB file root (in server root dir /etc/crontabs) for saving: Permission denied

意思是 Redis 没有权限打开 RDB 文件,保存快照失败。(RDB 用于将当前内存中的数据创建一个快照文件保存到磁盘上,里面有 Redis 数据库的状态,包括键、值以及键的过期时间等)

两种解决办法,修改后需要重启 redis

  1. 检查 Redis 配置文件中 redis.conf 的目录路径,确保 Redis 使用具有写权限的目录。修改配置文件的 dir 字段,默认值是当前目录 ./,如果要将数据存储到 /data/redis 目录,修改为 dir /data/redis
  2. 考虑使用 AOF 持久化模式,以避免这种错误发生,因为 AOF 持久化是将 Redis 操作追加到文件中而不是写入整个数据库快照。修改配置文件的 appendonly:appendonly yes

使用 AOF 持久化可以解决该问题,因为 AOF 持久化是将 Redis 操作以追加的形式写到一个文件中,而非像 RDB 一样保存整个内存快照,因此不会出现 RDB 权限不足而导致无法保存的情况。但是使用 AOF 时,redis 会定期将内存数据写入磁盘,频繁写入 AOF 文件可能会影响 Redis 的性能,AOF 文件可能会变得很大,存变动不大时建议可开启。

Redis 持久化

AOF (Append Only File)

开启时,Redis 会在每次数据变更时将数据写入 AOF 文件。这样在 Redis 服务宕机或者重启的情况下,可以通过读取 AOF 文件的内容重建数据库的状态。还可以提高 Redis 的写性能,因为它可以在内存中追加数据,而不是在每次写操作后更新整个数据集。
如果内存变动不大, 建议可开启,修改配置文件开启 AOF:appendonly yes

RDB (Redis DataBase file)

内存变动较大时最好使用 RDB
启用 AOF 持久化特性可以带来一定的数据安全性保证,但是相对于 RDB 持久化会带来更高的 I/O 负担,因为 Redis 需要在每次数据变更时进行磁盘 I/O。
在 RDB 持久化机制中,Redis 会定期(例如每隔 60 秒)地对内存中的数据进行快照,并将快照的结果存入到磁盘上的一个 RDB 文件中。如果 Redis 实例在快照之前停止运行,那么 RDB 文件就是最后一次持久化数据的副本。
要开启 RDB 持久化,需要在 redis. conf 配置文件中设置如下参数:

1
save <seconds> <changes>
  • seconds:指定当数据库中有多少个 key 被修改后,Redis 将数据快照(RDB 文件)写入磁盘。
  • changes:指定在多长时间内至少有多少次 key 修改,Redis 才会写入一次快照。

举个例子,如果设置为:

1
save 30 1

则意味着:如果 30 秒内至少有一个 key 被修改,Redis 就会写入一次快照。