RDB
RDB就是把当前时刻redis内存中的数据,生成一个快照,保存到硬盘中,是一个全量备份。在生成RDB文件时程序会对数据库中的键进行检查,如果键过期了,那么就不会被保存到新创建的RDB文件中。
触发条件:手动触发和自动触发
-
手动触发:
- save:执行该命令后,会阻塞Redis服务器进程,直到RDB文件创建完成为止。
- bgsave:执行该命令会派生一个子进程,来创建RDB文件,因此不会阻塞服务器进程。
-
自动触发:在 Redis.conf 配置文件中默认有此下配置:
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文件
在启动Redis服务器时,如果服务器开启了RDB功能,那么服务器将对RDB文件进行载入:
❑如果服务器以主服务器模式运行,那么在载入RDB文件时,程序会对文件中保存的键进行检查,未过期的键会被载入到数据库中,而过期键则会被忽略,所以过期键对载入RDB文件的主服务器不会造成影响。
❑如果服务器以从服务器模式运行,那么在载入RDB文件时,文件中保存的所有键,不论是否过期,都会被载入到数据库中。不过,因为主从服务器在进行数据同步的时候,从服务器的数据库就会被清空,所以一般来讲,过期键对载入RDB文件的从服务器也不会造成影响。
AOF
在该持久化方式下,每执行一条更新命令,就会将其追加写入AOF缓冲区的末尾,然后在合适的时机将其刷盘到硬盘中的AOF文件中。当过期键被惰性删除或者定期删除之后,程序会向AOF文件追加(append)一条DEL命令,来显式地记录该键已被删除。
触发条件:手动触发和自动触发
-
手动触发:执行
bgRewriteAOF
命令 -
自动触发:由于redis的默认持久化方式是RDB,所以想要开启AOF持久化需要在配置文件中设置
appendonly yes
-
刷盘时机有三种:
- Always:每执行一个更新操作,就写入磁盘的AOF文件
- Everysec:每秒将AOF缓存中的命令刷盘到AOF文件中
- No:将命令写入到AOF缓存中,至于何时刷盘由操作系统决定
AOF重写
正常情况下,由于每执行一条更新命令,就会将其写入到AOF文件中,所以AOF文件可能变的很臃肿,比如说,我执行了三条命令:lpush list 1
; lpush list 2
; lpush list 3
;就会将这三条命令都写入AOF文件中,但是有了AOF重写之后,这三条命令就可以变成一条命令:lpush list 1 2 3
。基于这一点,那么重写的新的AOF 文件会代替旧的AOF文件,如此就可以压缩AOF的文件大小。
同时,和生成RDB文件时类似,在执行AOF重写的过程中,程序会对数据库中的键进行检查,已过期的键不会被保存到重写后的AOF文件中。新的AOF文件是基于当前redis数据状态生成的,而不会参考老的AOF文件。
AOF的重写是通过一个子进程来完成的,这样做有两个目的:
❑子进程进行AOF重写期间,服务器进程(父进程)可以继续处理命令请求。
❑子进程带有服务器进程的数据副本,使用子进程而不是线程,可以在避免使用锁的情况下,保证数据的安全性。
但是通过子进程来完成重写AOF的操作时,就会有数据不一致的问题,因为子进程重写AOF的过程中,主进程是可以执行其他更新操作的,为了解决这个问题,redis引入了AOF重写缓冲区,它可以和AOF缓冲区并列存在。也就是说,在子进程执行重写操作时,Redis启动了一个AOF缓冲区,如果子进程在重写过程中,主进程执行了更新操作,那么该更新操作会同时写入到AOF缓冲区和AOF重写缓冲区,子进程再将AOF重写缓冲区中的内容刷盘到重写的AOF文件中,如此就可以解决数据不一致的问题。
文章参考《Redis设计与实现》