我们知道,Redis是基于内存的数据库,如果遇到断电的情况,那么数据将会丢失。因此,我们需要将Redis中的数据同步到磁盘上,以实现数据的持久化。实现持久化的方式分为两种:(1)RDB(Redis Database);(2)AOF(Append Only File)
RDB(Redis Database)
在指定的时间间隔后,如果更改了指定次数的数据,则将内存中的数据集快照写入到磁盘;在恢复过程中,直接读取快照文件,进行数据的恢复。在默认情况下,Redis将数据库快照保存在名为 dump.rdb的二进制文件 中,文件名可以根据 Redis.conf 文件自行配置。
在进行RDB的时候,Redis的主线程并不会参与io操作,主线程会fork出一个子线程来完成该操作:
- Redis调用fork,同时拥有父进程和子进程;
- 子进程将数据集写入到一个临时的RDB文件中;
- 当子进程完成对新RDB的写入时,Redis用新的RDB文件替换原来旧的RDB文件,并删除原来旧的RDB文件。
触发机制:(1)save的规则满足的情况下,会自动触发RDB原则;(2)执行flushdb,会触发RDB原则;(3)退出Redis,也会自动产生RDB文件。
save命令:使用save
命令,会立刻对当前内存中的数据进行持久化,但是会阻塞,也就是不能进行其他操作了(由于save
命令是同步命令,会占用Redis的主线程。若Redis数据非常多时,save
命令执行速度会非常慢,阻塞所有客户端的请求;所以一般使用异步的bgsave
,即fork一个子进程,用来进行RDB文件的写操作,这样Redis主进程依然可以响应客户端的请求)。
save在redis配置文件中的默认设置:
默认情况下存在3中save:(1)如果900秒内,至少有1个key进行了修改,就进行持久化;(2)如果300秒内,至少有10个key进行修改,则进行持久化;(3)如果60秒内,有10000个key进行了修改,则进行持久化。
RDB的优点:(1)适合大规模的数据恢复(因为恢复过程直接读如RDB文件的数据即可);(2)对数据的完整性要求不高。
RDB的缺点:(1)需要一定时间间隔进行操作,如果Redis意外宕机,那么最后修改的数据就无了;(2)fork进程的时候,会占用一定的内存空间。
AOF(Append Only File)
AOF的思想是将我们所有的命令都记录下来,保存为历史命令,在恢复的时候把这个文件里记录的命令全部再执行一遍。
因此,AOF是以日志的形式来记录每一个写入Redis的操作,将所有执行过的指令都记录下来(读操作不记录),只许追加文件但不可以读写文件,Redis启动之初会读取该文件重新把日志中的指令都执行一遍,以恢复数据。
RDB并不是非常耐久,如果Redis服务器宕机,那么服务器将丢失最近写入、以及未保存到快照中的那些数据。因此从1.1开始,Redis增加了一种完全耐久的持久化方式:AOF持久化。
如果要使用AOF的持久化方式,需要修改下面默认的配置文件中的项:
appendonly yes
表示开启AOF,默认情况下是不开启的,需要手动配置并重启redis,就可以生效了。
如果这个AOF文件格式有错误,此时Redis是启动不起来的,需要修改这个AOF文件。此时可以借助Redis给我们提供的工具:redis-check-aof --fix
同步到AOF文件的方式有三种:
# appendfsync always # 每次修改都会sync 消耗性能
appendfsync everysec # 每秒执行一次 sync 可能会丢失这一秒的数据
# appendfsync no # 不执行 sync ,这时候操作系统自己同步数据,速度最快
默认情况下是每一秒同步一次,因此可能会丢失这一秒的数据。
AOF的优点:(1)如果是每一次修改都同步,文件的完整性会更好;(2)如果每一秒同步一次,则完整性较好,但可能丢失一秒内的数据;(3)如果设置成从不同步,那么效率是最高的。
AOF的缺点:(1)相对于数据文件来说,AOF远远大于RDB,且修复速度比RDB慢;(2)AOF的运行效率也要比RDB慢,因此Redis默认的配置就是RDB持久化
RDB和AOF的选择问题
RDB | AOF | |
---|---|---|
启动优先级 | 低 | 高 |
体积 | 小 | 大 |
恢复速度 | 快 | 慢 |
数据安全性 | 丢数据 | 根据策略决定 |
一般来说,最好是同时利用两种持久化功能。
如果非常关心数据,但是可以承受几分钟内的数据丢失,那么可以只使用RDB持久化。
有很多用户都只使用AOF方式,但不推荐。因为定时生成RDB快照非常便于进行数据库备份,并且RDB恢复数据集的速度也要比AOF恢复快很多。