Redis持久化机制
RDB(默认)
**思想:**保存整个数据库的快照,也就是RDB文件,有两种保存方式,前台保存save和后台保存bgsave,前者会阻塞主进程程,后者则是fork一个子进程去完成备份操作,不会阻塞。
注意:fork子进程的过程是阻塞的,完成之后不再阻塞
**开启方式:**默认开启
设置备份频率
特点:
- 数据恢复速度快(响应速度很重要,所以默认用RDB):使用 RDB 文件恢复数据,直接解析还原二进制数据即可,不需要一条一条地执行命令,速度非常快。
- 备份的RDB文件AOF文件小很多,因为RDB只记录最终值,而AOF会完整记录变化过程
- 安全性相对较低,因为全量备份时开销比较大,故无法实时备份,备份的间隔长
- 备份期间的对性能影响比较大,因为是全量备份,且每次都需要fork一个子进程
思考问题:如果子进程读取数据写入到RDB文件的期间,数据发生了变化,如何处理?
用了copyonwrite机制,对于要写的那部分数据,先进行拷贝,然后再写,写入RDB的数据不会有变化。
AOF
思想:记录所有执行的写命令到AOF文件中,备份时只需要往原本的AOF文件追加指令即可,当重启时将AOF文件的指令全部执行一遍即可恢复
**开启方式:**修改redis.conf配置文件,把appendonly 设置为 yes
appendonly yes
持久化过程:
- 执行修改命令
- 更改内存中的数据结构
- 记录到AOF缓冲区
- 根三种同步(刷盘)策略,将缓冲区数据同步到AOF文件中(AOF过大时可以重写AOF文件进行压缩)
- 重启,加载AOF文件,执行命令,恢复数据
AOF同步(刷盘)的三种策略:
三种策略的对比
特点:
- 安全性高,能够做到实时(秒级)的备份
- 备份轻量,只需要追加命令即可,不像RDB的全量备份那么消耗CPU 资源和内存资源
- 恢复速度慢,因为需要一条一条执行AOF文件记录的语句
- 备份的文件较大,可以用REWRITEAOF命令重写,但体积还是会比RDB大
思考问题:执行写命令时,是先记录执行命令还是先记录到AOF文件中?为什么?
一般的数据库(如 MySQL)通常都是执行命令之前先记录好日志,这样方便故障恢复,防止数据丢失。但是Redis是先执行命令,再记录到AOF。
优点:
- 保证实时可见性,响应速度快,即用户执行完写操作后用户能够立即读取到更新后的数据。
- 查减少写操作的延迟,提高吞吐量,因为在记录日志前不需要再对命令做语法检。
缺点:如果命令执行完,但没有来得及写入AOF,服务器宕机了,此时数据会丢失。不过redis的AOF的间隔比较短,只会丢失少量数据。真正的数据源一般都在mysql里面,故影响不大。
选用RDB还是AOF?
- 正常情况使用RDB,因为他数据恢复速度快,而丢失一些数据相对影响没这么大,真正的数据还在数据库中。
- 只有当对安全性有很高要求时,选择AOF,可以做到秒级别的备份。