使用缓存的时候,我们经常需要对内存中的数据进行持久化(将内存中的数据写入到硬盘中)。
原因:重用数据(比如重启机器、机器故障之后恢复数据),做数据同步(比如 Redis 集群的主从节点通过 RDB 文件同步数据)
RDB持久化:
Redis Database Backup redis数据备份
定义
:通过创建快照文件把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。
快照文件成为RDB文件,默认保存咋当前运行目录
用途:复制到其他服务器创建具有相同数据的服务器副本, 重启服务器恢复数据
RDB 创建快照时会阻塞主线程吗?
Redis 提供了两个命令来生成 RDB 快照文件:
save
: 同步保存操作,会阻塞 Redis 主线程;不推荐,适合停机之前使用bgsave
: fork 主线程出一个子进程,异步执行,读取内存数据写入新的RDB文件,用新的RDB文件替换旧的RDB文件。
bgsave实现细节:
主进程执行写操作时,会拷贝写数据,因为存在所有数据被修改的可能,所以可能最终拷贝出等体积大小的数据。因此必须redis执行时要留存一部分内存用于RDB。
触发机制
默认redis服务停机时,会自动触发一次RDB,初次之外按下面方法自定义触发机制
save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发bgsave命令创建快照。
save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发bgsave命令创建快照。
save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发bgsave命令创建快照。
RDB缺点:
1.执行间隔时间长,两次RDB之间写入数据有丢失风险
2.fork出子进程、压缩、写入RDB文件耗时
AOF持久化:
AOF全程Append Only File 追加文件
定义:
Redis处理每个写命令都会记录在磁盘中的AOF文件,可以看作命令日志文件。
AOF工作基本流程:
1. append命令追加: 每次写命令append到AOF缓冲区
2. write文件写入:将AOF缓冲区数据写入到系统内核缓冲区
3.fsync持久化:fsync 将内核缓冲区刷新到磁盘中的AOF文件
4. bgrewriteaof重写:记录每次命令导致AOF文件比RDB文件大得多。而且AOF记录会对同一个key多次写操作,但只有最后一次写操作才有意义。
当AOF大到一定程度时,通过重写出新的AOF文件用最少命令达到相同效果。并替换原AOF文件
AOF持久化(刷盘)方式有哪些
区别在于write到内核缓冲区后的刷盘时机
1. 每执行一次写命令,立刻刷盘到AOF文件
2. 写命令执行完先放入内核缓冲区,每隔一秒将缓冲区数据刷盘到AOF文件
3. 写命令执行完先放入内核缓冲区,与操作系统决定何时刷盘
AOF为什么执行完命令之后记录日志
1.避免额外的检查开销,AOF记录日志不会对命令进行语法检查
2. 在命令执行完之后再记录,不会阻塞当前的命令执行。
风险:1、刚执行完命令 redis就宕机会导致对应的修改丢失
2、可能阻塞后续其他命令的执行(AOF 记录日志是在 Redis 主线程中进行的)
如何选择RDB和AOF?
1、RDB定时对整个内存做快照,AOF记录每次执行的命令日志
2、 RDB文件更小,AOF文件更大
3、RDB数据完整性低,AOF相对完整(可以实时或者秒级持久化数据)
4、RDB恢复数据更快(直接解析原数据),AOF更慢(一条一条执行命令)
5、RDB文件系统资源占用更高(Bgsave开新线程占用CPU),AOF占用更少(仅仅追加命令行,很轻量)
综上:
- Redis 保存的数据丢失一些也没什么影响的话,可以选择使用 RDB。
- 不建议单独使用 AOF,因为时不时地创建一个 RDB 快照可以进行数据库备份、更快的重启以及解决 AOF 引擎错误。
- 如果保存的数据要求安全性比较高的话,建议同时开启 RDB 和 AOF 持久化或者开启 RDB 和 AOF 混合持久化。