Redis提供了多种持久化选择
- RDB:RDB是以指定间隔时间将Redis进行快照
- AOF:AOF记录每一次写操作,当Redis服务重启后,会通过日志重新恢复数据集。命令被以一种Redis规定的格式记录。
- No persistence:可以完全禁止持久化
- RDB+AOF:可以复合使用,当有AOF时,Redis会优先使用AOF
优缺点分析
|
| RDB | AOF | | —- | —- | —- | | 优点 |
1. RDB持久化方式是一个紧凑方式,方便传输
2. 主线程不参与持久化,也就是不参与I/O操作
3. 比AOF更快的恢复时间
|
1. AOF更可靠,默认1秒持久化一次,可以设置具体策略
2. 有工具修复AOF
3. AOF记录的东西可以看得懂
| | 缺点 |
1. RDB可能会丢失一些数据
2. 数据集很大时fork()会花很多时间
|
1. 比RDB的文件大(相同数据量)
2. AOF可能会损失Redis一些性能
3. 有个别bug
|
通常我们会将RDB和AOF都进行开启,如果你能忍受几分钟的数据丢失情况,可以单独使用RDB。
很多人单独使用AOF,但是这不被推荐。
RDB官方介绍
默认RDB是开启的,默认记录一个二进制文件dump.rdb。触发刷盘的行为有以下三个:
- 执行save命令
- 执行bgsave命令
- 配置文件中指定save 规则
当需要进行刷盘时,Redis会执行的动作:
- Redis会开启子进程
- 子进程将数据先刷到一个临时的RDB文件中
- 当子进程将数据同步到临时RDB后,替换旧的
尚硅谷说: save:会阻塞,就是说执行完save后,才能执行其他命令 bgsave:则会fork子进程,不阻塞
RDB操作
- 生成RDB文件
- 手动save or bgsave
- 触发配置文件中的条件
- 使用RDB文件
- redis重启后自动使用RDB,前提AOF未开启
RDB的配置项梳理
- save 配置
- save N秒之后 至少N个key发生变化
- save “” 禁用save或者 注释所有save配置
- stop-writes-on-bgsave-error
- 若刷盘错误,直接禁止写操作
- rdbcompression
- 是否压缩rdb
- rdbchecksum
- 校验rdb文件
AOF
AOF持久化大体流程
- 客户端将写命令先追加到AOF缓冲区(内存中)
- 根据配置的AOF持久化策略,将AOF缓冲区刷到磁盘上
若AOF文件过大的话会依据配置的重写,缩减AOF大小。也可以手动重写
AOF配置
appendfsync 追加存盘 策略
- always:每次写操作都会直接入盘
- everysec:每秒同步一次
- no:redis不主动同步而是将同步时机交给操作系统
- no-appendfsync-on-rewrite
- 当重写操作进行时,是否进行AOF的刷盘操作。
- yes:客户端依旧可以执行写命令,但是这段写命令暂时不会刷盘
- no:就是可以继续向旧AOF中写,客户端写命令可能会阻塞(注意是可能会阻塞,可能会阻塞)
- auto-aof-rewrite-percentage
- 当前文件时上次rewrite后大小的 N倍后执行 rewrite
auto-aof-rewrite-min-size
判断是否有bgsave或者bgrewriteaof在运行,有则等待
- fork出一个子进程,并开始同步一个新的aof
- 此时客户端的写请求同时写入 aof_buf 和 aof_rewrite_buf
- aof_buf用于旧的aof文件同步,aof_rewrite_buf用于将新的命令同步到rewrite的新的aof中
- fork的子进程完成新aof 对 旧aof文件的重写和 aof_rewrite_buf中新命令,两部分的重写后。通知主进程。
- 主进程将新AOF替换旧AOF
其中aof_buf到旧的AOF文件中的这一步,看如何设了(no-appendfsync-on-rewrite)。若是yes的话就不会进行旧AOF的更新。若是no的话,会进行旧AOF的更新操作。
AOF修复工具
Redis为我们提供了修复aof文件的工具,比如我们使用flushall命令清空Redis时,我们想恢复Redis数据。
可以打开AOF将flushall删除,之后,通过redis-check-aof工具修复,重启Redis后即可。
尚硅谷优化建议
- 当新的AOF生成完成后。
- 在将新AOF替换旧AOF动作完成前
- 所有的客户端写操作时不被执行的。所以可能阻塞
参考文章
- 官方文档-https://redis.io/topics/persistence#snapshotting
- 尚硅谷《Redis6笔记》