本文为您介绍redis的持久化机制以及持久化的选型。
目录
持久化策略
RDB(RedisDatabase)快照
AOF(Append Only File)
混合持久化策略
RDB与AOF对比
持久化策略使用建议
Redis数据备份策略建议
补充知识
save与bgsave对比
bgsave的写时复制(COW)机制
持久化策略
Redis提供了很多跟数据持久化相关的配置,大体上,可以组成以下几种策略:
- 无持久化:完全关闭数据持久化,不保证数据安全。相当于将Redis完全当做缓存。
- RDB(RedisDatabase)快照:按照一定的时间间隔缓存Redis所有数据快照。
- AOF(Append Only File):记录Redis收到的每一次写操作。这样可以通过操作重演的方式恢Redis的数据。
- RDB+AOF:同时保存Redis的数据和操作。
更多内容,请参见https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/
RDB(RedisDatabase)快照
- 定义:RDB可以在指定的时间间隔,备份当前时间点的内存中的全部数据集,并保存到餐盘文件当中。在恢复时,再将磁盘中的快照文件直接都会到内存里。
- 特点:RDB存的是全量数据,你甚至可以直接用RDB来传递数据。例如如果需要从一个Redis服务中将数据同步到另一个Redis服务(最好是同版本),就可以直接复制最近的RDB文件。
- 储存位置:通常是dump.rdb文件。
- 触发时机:
- 满足配置文件中默认的快照配置时,会自动触发RDB快照。
- 手动执行save或者bgsave指令时,会触发RDB快照。
- 其中save方法会在备份期间阻塞主线程。
- bgsve则不会阻塞主线程。但是他会fork一个子线程进行持久化,这个过程中会要将数据复制一份,因此会占用更多内存和CPU。
- 主从复制时会触发RDB备份。
LASTSAVE指令查看最后一次成功执行快照的时间。时间是一个代表毫秒的LONG数字,在linux中可以使用date -d @{timestamp} 快速格式化。
- 核心配置参数
这些配置直接影响 RDB 持久化的安全性、性能和存储效率,实际配置时需根据业务对数据一致性的要求、服务器资源(CPU / 磁盘)情况综合权衡。配置参数 含义 默认值 配置建议 dir 指定 RDB 文件和 AOF 文件的存储目录 无默认值,需手动配置 建议设置为独立的持久化目录,如 /var/lib/redis
dbfilename 指定 RDB 快照文件的名称 dump.rdb 保持默认即可,如需区分不同实例可修改,如 dump-6379.rdb
rdbcompression 是否启用 RDB 文件压缩(使用 LZF 算法) yes 1. 建议保持默认 yes
,节省磁盘空间
2. 若 CPU 资源紧张且磁盘充足,可设为no
提升性能stop-writes-on-bgsave-error 当 bgsave 快照写入失败时,是否停止接受新的写入请求stop-writes-oin-bgsave-error 。 yes 1. 生产环境建议保持默认 yes
,避免数据不一致
2. 若有其他数据一致性保障机制,可设为no
rdbchecksum 是否对 RDB 文件启用 CRC64 校验 yes 1. 建议保持默认 yes
,确保数据完整性
2. 若追求极致性能且能接受一定数据风险,可设为no
(约提升 10% 性能)
AOF(Append Only File)
- 定义:以日志的形式记录每个写操作(读操作不记录)。
- 特点:只允许追加文件而不允许改写文件。
- 触发时机:每次写操作后。
- 核心参数配置
配置参数 含义 默认值 配置建议 appendonly 是否开启 AOF 持久化功能 no 1. 需持久化时设为 yes
2. 与 RDB 配合使用时建议开启appendfilename 指定 AOF 文件的名称 appendonly.aof 保持默认即可,多实例可区分命名(如 appendonly-6379.aof
)appendfsync AOF 同步策略
-no
:由操作系统决定何时同步
-everysecond
:每秒同步一次
-always
:每次操作都同步everysecond 1. 推荐默认 everysecond
(平衡安全性和性能)
2. 极高安全性需求用always
(性能损耗大)
3. 性能优先且可容忍数据丢失用no
appenddirname AOF 文件存储子目录
实际路径为{dir}/{appenddirname}
无默认值 Redis 7 + 新增参数,建议设置单独子目录(如 aof
)便于管理auto-aof-rewrite-percentage AOF 重写触发的增长率阈值 100(%) 与 auto-aof-rewrite-min-size
配合使用,默认值可满足多数场景auto-aof-rewrite-min-size AOF 重写的最小文件大小阈值 64mb 避免小文件频繁重写,可根据业务量调整(如 128mb) no-appendfsync-on-rewrite AOF 重写期间是否暂停 appendfsync
操作no 1. 设为 yes
可提高重写速度,但可能增加数据丢失风险
2. 追求安全性保持默认no
(重写期间仍按策略同步)补充说明
- AOF 重写可通过
BGREWRITEAOF
命令手动触发,用于紧急优化 AOF 文件。 - Redis 7 + 的 AOF 重写会生成
base.rdb
(基础快照)和incr.aof
(增量操作),结合了 RDB 和 AOF 的优势。 - 同步策略和重写参数需根据业务对 "数据安全性" 和 "性能" 的要求综合调整。
- AOF 重写可通过
混合持久化策略
- 定义:RDB和AOF两种持久化策略各有优劣,所以在使用Redis时,是支持同时开启两种持久化策略的。
- 开启方式:在redis.conf配置文件中,有一个aof-use-rdb-preamble参数可以同时打开RDB和AOF两种持久化策略。但此策略,必须先开启aof。
- 写入过程:如果开启了混合持久化,AOF在重写时,不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将重写这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换。
于是在 Redis 重启的时候,可以先加载 RDB 的内容,然后再重放增量 AOF 日志就可以完代替替代之前的AOF 全量文件重放,因此重启效率大幅得到提升。混合持久化AOF文件结构如下:
RDB与AOF对比
对比维度 | RDB(Redis DataBase) | AOF(Append Only File) |
---|---|---|
核心优点 | 1. 文件紧凑,占用存储空间小,适合定期备份 2. 灾难恢复场景中,全量数据恢复效率高 3. 备份时仅 fork 子线程处理,对主线程 IO 性能几乎无影响 4. 大数据量重启时,加载速度远快于 AOF | 1. 安全性更高,默认每秒同步(最多丢失 1 秒数据),支持实时同步(always )2. 采用 “追加写入” 模式,无记录不完整问题,可通过 redis-check-aof 工具修复3. 自动触发日志重写,避免单个文件过大 4. 日志为可读的操作指令,可手动编辑(如删除误操作 FLUSHALL )实现数据恢复 |
核心缺点 | 1. 仅定期快照,无法实时备份,宕机时可能丢失快照间隔内的所有数据 2. fork 子线程时需克隆内存数据,数据量大 / CPU 性能差时,会导致 Redis 短暂服务停顿 | 1. 相同数据集下,AOF 文件体积通常远大于 RDB 文件 2. 写操作频繁时,IO 开销更高,备份性能弱于 RDB |
适用场景 | 1. Redis 作为缓存使用,对数据丢失容忍度较高 2. 需定期全量备份、快速恢复的场景 3. 非核心业务数据,优先保障 Redis 运行性能 | 1. 对数据安全性要求高,仅能容忍秒级数据丢失的场景 2. 需避免误操作导致数据丢失,需手动修复日志的场景 |
持久化策略使用建议
- 如果您只是把Redis当做一个缓存来用,可以直接关闭持久化。
- 如果您更关注数据安全性,并且可以接受服务异常宕机时的小部分数据损失,那么可以简单的使用RDB策略。这样性能是比较高的。
- 不建议单独使用AOF。RDB配合AOF,可以让数据恢复的过程更快。
Redis数据备份策略建议
-
写crontab定时调度脚本,每小时都copy一份rdb或aof的备份到一个目录中去,仅仅保留最近48小时的备份。
-
每天都保留一份当日的数据备份到一个目录中去,可以保留最近1个月的备份。
-
每次copy备份的时候,都把太旧的备份给删了。
-
每天晚上将当前机器上的备份复制一份到其他机器上,以防机器损坏。
补充知识
save与bgsave对比
save和bgsave都能生成RDB快照,那么他么有什么区别呢?
他们最大的区别就是save⽅法会在备份期间阻塞主线程。bgsve则不会阻塞主线程。但是它会fork⼀个⼦线程进⾏持久化,这个过程中会要将数据复制⼀份,因此会占⽤更多内存和CPU。具体对比如下:
配置自动生成rdb文件后台使用的是bgsave方式。
bgsave的写时复制(COW)机制
Redis 借助操作系统提供的写时复制技术(Copy-On-Write, COW),在生成快照的同时,依然可以正常处理写命令。
简单来说,bgsave 子进程是由主线程 fork 生成的,可以共享主线程的所有内存数据。
bgsave 子进程运行后,开始读取主线程的内存数据,并把它们写入 RDB 文件。此时,如果主线程对这些数据也都是读操作,那么,主线程和 bgsave 子进程相互不影响。但是,如果主线程要修改一块数据,那么,这块数据就会被复制一份,生成该数据的副本。然后,bgsave 子进程会把这个副本数据写入 RDB 文件,而在这个过程中,主线程仍然可以直接修改原来的数据。