RDB 是一个紧凑压缩的二进制文件,代表 Redis 在某个时间点上的数据快照。非常适合于备份,全量复制等场景。例如每 6 个消时执行 bgsave 备份,并把 RDB 文件拷贝到远程机器或者文件系统中,用于灾难恢复。
Redis 加载 RDB 恢复数据远远快于 AOF 的方式。
Q4:RDB 持久化的缺点?RDB 方式数据无法做到实时持久化/秒级持久化,因为 bgsave 每次运行都要执行 fork 操作创建子进程,属于重量级操作,频繁执行成本过高。针对 RDB 不适合实时持久化的问题,Redis 提供了 AOF 持久化方式。
RDB 文件使用特定二进制格式保存,Redis 版本演进过程中有多个格式的 RDB 版本,存在老版本 Redis 服务无法兼容新版 RDB 格式的问题。
Q5:AOF 持久化的原理?AOF 持久化以独立日志的方式记录每次写命令,重启时再重新执行 AOF 文件中的命令达到恢复数据的目的。AOF 的主要作用是解决了数据持久化的实时性,目前是 Redis 持久化的主流方式。
开启 AOF 功能需要设置:appendonly yes,默认不开启。保存路径同 RDB 方式一致,通过 dir 配置指定。
AOF 的工作流程操作:命令写入 append、文件同步 sync、文件重写 rewrite、重启加载 load:
所有的写入命令会追加到 aof_buf 缓冲区中。
AOF 缓冲区根据对应的策略向硬盘做同步操作。
随着 AOF 文件越来越大,需要定期对 AOF 文件进行重写,达到压缩的目的。
当服务器重启时,可以加载 AOF 文件进行数据恢复。
Q6:AOF 命令写入的原理?AOF 命令写入的内容直接是文本协议格式,采用文本协议格式的原因:
文本协议具有很好的兼容性。
开启 AOF 后所有写入命令都包含追加操作,直接采用协议格式避免了二次处理开销。
文本协议具有可读性,方便直接修改和处理。
AOF 把命令追加到缓冲区的原因:
Redis 使用单线程响应命令,如果每次写 AOF 文件命令都直接追加到硬盘,那么性能完全取决于当前硬盘负载。先写入缓冲区中还有另一个好处,Redis 可以提供多种缓冲区同步硬盘策略,在性能和安全性方面做出平衡。
Q7:AOF 文件同步的原理?Redis 提供了多种 AOF 缓冲区文件同步策略,由参数 appendfsync 控制,不同值的含义如下:
always:命令写入缓冲区后调用系统 fsync 操作同步到 AOF 文件,fsync 完成后线程返回。每次写入都要同步 AOF,性能较低,不建议配置。
everysec:命令写入缓冲区后调用系统 write 操作,write 完成后线程返回。fsync 同步文件操作由专门线程每秒调用一次。是建议的策略,也是默认配置,兼顾性能和数据安全。
no:命令写入缓冲区后调用系统 write 操作,不对 AOF 文件做 fsync 同步,同步硬盘操作由操作系统负责,周期通常最长 30 秒。由于操作系统每次同步 AOF 文件的周期不可控,而且会加大每次同步硬盘的数据量,虽然提升了性能,但安全性无法保证。
Q8:AOF 文件重写的原理?文件重写是把 Redis 进程内的数据转化为写命令同步到新 AOF 文件的过程,可以降低文件占用空间,更小的文件可以更快地被加载。
重写后 AOF 文件变小的原因:
进程内已经超时的数据不再写入文件。
旧的 AOF 文件含有无效命令,重写使用进程内数据直接生成,这样新的 AOF 文件只保留最终数据写入命令。
多条写命令可以合并为一个,为了防止单条命令过大造成客户端缓冲区溢出,对于 list、set、hash、zset 等类型操作,以 64 个元素为界拆分为多条。
AOF 重写分为手动触发和自动触发,手动触发直接调用 bgrewriteaof 命令,自动触发根据 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数确定自动触发时机。
重写流程: