Redis支持RDB(Redis DataBase)和AOF(Apend Only File)两种持久化机制。持久化功能有效地避免因进程退出造成的数据丢失问题,下次重启时利用之前持久化的文件即可实现数据恢复。
RDB
RDB是一种快照机制。Redis工作在内存中,RDB就是每隔一段时间对内存中的数据做一次快照,保存在dump.rdb的二进制文件中。Redis会单独创建fork()一个子进程,将当前父进程的数据库数据复制到子进程的内存中,然后由子进程写入到临时文件中,持久化的过程结束了,再用这个临时文件替换上次的快照文件,然后子进程退出,内存释放。而主进程是不会进行任何IO操作的,这样就确保了Redis极高的性能。
RDB的优缺点
优点:
全量数据快照,文件小,恢复快
缺点:
每次快照持久化都会将主进程的数据库数据复制一遍,导致内存开销加倍,若此时内存不足,则会阻塞服务器运行,直到复制结束释放内存;都会将内存数据完整写入磁盘一次,所以如果数据量大的话,而且写操作频繁,必然会引起大量的磁盘I/O操作,严重影响性能,并且最后一次持久化后的数据可能会丢失
手动触发和自动触发
手动触发分别对应save和bgsave命令。
save命令:阻塞当前Redis服务器,直到RDB过程完成为止,线上环境要杜绝save的使用。
bgsave命令:Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,阻塞只发生在fork阶段。
以下场景下会自动触发:
1)使用save相关配置,如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave
2)如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点
3)执行debug reload命令重新加载Redis时
4)执行shutdown命令时,如果没有开启AOF持久化功能则自动执行bgsave
1、执行bgsave命令,Redis父进程判断当前是否存在正在执行的子进程,如RDB/AOF子进程,如果存在bgsave命令直接返回
2、父进程执行fork操作创建子进程,fork操作过程中父进程会阻塞
3、父进程fork完成后,bgsave命令返回“Background saving started”信息并不再阻塞父进程,可以继续响应其他命令
4、子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换
5、进程发送信号给父进程表示完成,父进程更新统计信息
AOF
以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF命令以Redis协议追加保存每次写的操作到文件末尾。Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。默认的AOF持久化策略是每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中),因为在这种情况下,Redis仍然可以保持很好的处理性能,即使Redis故障,也只会丢失最近1秒钟的数据。
因为采用了追加方式,如果不做任何处理的话,AOF文件会变得越来越大,为此,Redis提供了AOF文件重写机制,即当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。
1)所有的写入命令会追加到aof_buf(缓冲区)中
2)AOF缓冲区根据对应的策略向硬盘做同步操作
3)随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的
4)当Redis服务器重启时,可以加载AOF文件进行数据恢复
命令写入
AOF命令写入的内容直接是文本协议格式,文本有良好的兼容性。开启AOF后,所有写入命令都包含追加操作,直接采用协议格式,避免二次处理开销。文本协议具有可读性,方便直接修改处理
AOF为什么把命令追加到aof_buf中?
Redis使用单线程响应命令,如果每次写入AOF文件命令直接追加到硬盘,会带来非常高的磁盘IO,影响整体性能。
重写机制
随着命令不断写入AOF,文件会越来越大,Redis引入重写机制压缩文件体积
1、在重写期间,由于主进程依然在响应命令,为了保证最终备份的完整性;因此它依然会写入旧的AOF file中,如果重写失败,能够保证数据不丢失
2、为了把重写期间响应的写入信息也写入到新的文件中,因此也会为子进程保留一个buf,防止新写的file丢失数据
3、重写是直接把当前内存的数据生成对应命令,并不需要读取老的AOF文件进行分析、命令合并
4、AOF文件直接采用的文本协议,主要是兼容性好、追加方便、可读性高、可易于修改修复
重写后AOF文件为什么变小
1、进程内已经超时数据不再写入文件
2、旧的AOF文件含有无效命令
3、多条命令合并
AOF的优缺点
优点:
可读性高,适合保存增量数据,数据不易丢失
缺点:
文件体积大,恢复时间长
从持久化中恢复数据
数据的备份、持久化完成后,如何从这些持久化文件中恢复数据呢?如果一台服务器上有既有RDB文件,又有AOF文件,该加载谁呢?其实想要从这些文件中恢复数据,只需要重新启动Redis即可:启动时会先检查AOF文件是否存在,如果不存在就尝试加载RDB。那么为什么会优先加载AOF呢?因为AOF保存的数据更完整,通过上面的分析我们知道AOF基本上最多损失1s的数据。
Redis 4.0 混合持久化
重启 Redis 时,很少使用 RDB来恢复内存状态,因为会丢失大量数据。通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 RDB来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。 Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。
AOF在重写时将重写这一刻之前的内存RDB快照文件的内容和增量的 AOF修改内存数据的命令日志文件存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,原子的覆盖原有的AOF文件,完成新旧两个AOF文件的替换;AOF根据配置规则在后台自动重写,也可以人为执行命令bgrewriteaof重写AOF。于是在 Redis 重启的时候,可以先加载 RDB的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重启效率因此大幅得到提升。
补充:
AOF会不会产生脏数据?
会产生,AOF文件过大时内部会进行逻辑重写,比如执行i++一百次,底层重写后值变为100。你如果再查i++50次的值是拿不到150的,所以会产生脏数据。
RDB(快照)和AOF(日志)适用场景:
RDB和AOF的选择之感
- 对数据非常敏感,建议使用默认的AOF持久化方案
AOF持久化策略使用erverysecond,每秒钟fsync一次。该策略redis仍然可以保持很好的处理性能,当出现问题时,最多丢失0-1秒中的数据 - 数据呈现阶段有效性,建议使用RDB持久化方案
数据可以良好的做到阶段内无丢失且恢复速度较快,阶段点数据恢复通常采用RDB方案
综合对比:
1、如不能承受数分钟以内得数据丢失,对业务数据非常敏感,选用AOF
2、如能承受数分钟以内数据丢失,且追求大数据集得恢复速度,选用RDB
灾难恢复选用RDB
3、双保险策略,同时开启RDB和AOF,重启后,Redis优先使用AOF来恢复数据,降低丢失数据的量
本文详细介绍了Redis的两种持久化机制:RDB(快照)和AOF(追加日志)。RDB是内存数据的全量快照,恢复速度快但可能导致数据丢失;AOF记录每次写操作,文件大但数据完整。文章讨论了RDB的bgsave过程、AOF的重写机制以及恢复数据的方法,并分析了两者在不同场景下的适用性选择。
604

被折叠的 条评论
为什么被折叠?



