目录
前言
Redis支持RDB和AOF两种持久化机制,持久化可以有效的避免因为进程退出而造成的数据丢失问题,当下次启动时会利用之前的持久化文件进行数据恢复的操作.
RDB
RDB持久化是将当前进程的数据生成快照保存到硬盘的过程,RDB持久化生成的文件是压缩之后的二进制文件,触发RDB持久化过程分为手动触发和自动触发.
触发机制
手动触发
手动触发使用save命令和bgsave命令.
- sava命令: 执行sava命令会阻塞当前Redis服务器,直到RDB结束,才会接触阻塞,这个命令对于内存比较大的实例,会造成长时间的阻塞,所以基本上不推荐使用.
- bgsava命令: Redis进程会执行fork操作创建子进程,RDB持久化的过程由子进程执行,完成后自动接收,阻塞阶段只发生在执行fork操作创建子进程的过程.一般时间比较短.
注意: Redis内部所有涉及到RDB的操作都采用类似bgsave的方式.
自动触发
自动触发机制在实际项目中是最有价值的.
- 使用sava配置: 如 sava m n 表示在m秒内数据发生了n次修改,自动触发RDB持久化.
- 从节点进行全量复制时,主节点自动进行RDB持久化,随后将RDB文件内容发送给从节点.
- 执行shutdown 命令关闭Redis时,执行RedisRDB持久化.
bgsave执行流程
校验:如果 Redis 启动时加载到损坏的 RDB 文件会拒绝启动。这时可以使用Redis 提供的 redischeck-dump 工具检测 RDB 文件并获取对应的错误报告
RDB的优缺点
- RDB是一个紧凑压缩的二进制文件,代表Redis在某一个时间点的数据快照,非常适用于备份,全量复制等操作,比如每6个小时执行bgsave操作,并把RDB文件复制到远程机器或者文件系统中,用于容灾.
- Redis加载RDB文件的速度要快于AOF文件.
- RDB 方式数据没办法做到实时持久化 / 秒级持久化。因为 bgsave 每次运行都要执行fork 创建子进程,属于重量级操作,频繁执行成本过高。
- RDB用特定的二进制方式保存,Redis 版本演进过程中有多个 RDB 版本,兼容性可能有分险。
AOF持久化
AOF以独立日志的方式来记录每次的写命令,重启时在重新执行AOF文件中的命令来达到恢复数据的目的,AOF的主要是解决数据持久化的实时性,
使用AOF
开启AOF功能需要在配置文件中设置:appendonly yes 默认是不开启的.
AOF的文件名通过appendfilename来配置(默认是appendonly.aof)
AOF的工作流程
- 所有的写命令会追加到 AOF缓冲区中.
- AOF 缓冲区根据对应的策略向硬盘做同步操作,
- 随着 AOF 文件越来越大,需要定期对 AOF文件进行重写,达到压缩的目的,
- 当 Redis 服务器启动时,可以加载 AOF文件进行数据恢复.
注意: AOF缓冲区的作用: Redis是单线程响应命令,如果每次AOF文件都直接写入到硬盘中去,那么Redis的性能会从内存读写变成IO读写.必然会下降,先写入缓冲区会减低IO次数.
Redis还提供了多种缓冲区同步策略,可以根据需求自己选择.
AOF重写机制
随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis 引入AOF 重写机制压缩文件体积。
AOF文件重写是把 Redis 进程内的数据转化为写命令同步到新的 AOF文件中.
重写后的 AOF 为什么可以变小?
有如下原因:
- 进程内已超时的数据不再写入文件
- 旧的 AOF 中的无效命令,例如 del、hdel、srem 等重写后将会删除,只需要保留数据的最终版本。
- 多条写操作合并为一条,例如 lpush list a、lpush list b、lpush list 从可以合并为 lpush list a b c。 较大的 AOF文件大大增加了硬盘空间占用,一方面可以提升启动 Redis 时数据恢复的速度。
Redis启动时的数据恢复
当Redis启动时,会根据RDB和AOF文件的内容,进行数据恢复.
总结
- Redis提供了两种持久化方案 RDB AOF
- RDB视为内存的快照,产生的内容更为紧凑,占用空间较小,恢复时速度更快,但是RDB开销较大,不适合实时持久化,一般用于冷备份或主从复制
- AOF视为对修改命令的保存,在恢复时需要重放命令.并且有重写机制来定期压缩AOF文件
- RDB 和 AOF 都使用fork 创建子进程,利用Linux 子进程拥有父进程内存快照的特点进行持久化, 尽可能不影响主进程继续处理后续命令。