持久化
Redis 有 RDB 和 AOF 两种持久化方式,持久化功能有效的避免因进程退出造成的数据丢失问题,下次重启时利用以前持久化的文件即可恢复数据。
RDB:
将数据以快照的形式保存下来。触发方式为手动触发和自动触发。
手动触发:
手动触发分别对应 save 和 bgsave 命令。
- save 命令:阻塞当前服务器,直到 RDB 过程完成为止,对于内存 比较大的实例会造成长时间阻塞,线上环境不建议使用。
- bgsave 命令:Redis 进程执行 fork 操作创建子进程,RDB 持久化过程由子 进程负责,完成后自动结束。阻塞只发生在 fork 阶段,一般时间很短。
自动触发:
- 使用 save 相关配置,如“save m n”。表示 m 秒内数据集存在 n 次修改 时,自动触发 bgsave。
- 如果从节点执行全量复制操作,主节点自动执行 bgsave 生成 RDB 文件并发送给从节点。(主从复制时)
- 执行 debug reload 命令重新加载 Redis 时,也会自动触发 save 操作。
- 默认情况下执行 shutdown 命令时,如果没有开启 AOF 持久化功能则 自动执行 bgsave。
优点:
- RDB 是一个紧凑压缩的二进制文件,代表 Redis 在某个时间点上的数据 快照。非常适用于备份,全量复制等场景。比如每 6 小时执行 bgsave 备份, 并把 RDB 文件拷贝到远程机器或者文件系统中(如 hdfs),用于灾难恢复。
- Redis 加载 RDB 恢复数据远远快于 AOF 的方式。
缺点:
- RDB 方式数据没办法做到实时持久化/秒级持久化。因为 bgsave 每次运 行都要执行 fork 操作创建子进程,属于重量级操作,频繁执行成本过高。
- RDB 文件使用特定二进制格式保存,Redis 版本演进过程中有多个格式 的 RDB 版本,存在老版本 Redis 服务无法兼容新版 RDB 格式的问题。
AOF:
以独立日志的方式,记录每次写命令,重启时再重新执行 AOF 文件中的命令达到恢复数据的目的。AOF 的主要作用 是解决了数据持久化的实时性,目前已经是 Redis 持久化的主流方式。
开启 AOF 功能需要设置配置:appendonly yes,默认不开启。
AOF 的工作流程操作:
命令写入 (append)、文件同步(sync)、文件重写(rewrite)、重启加载 (load):
- 所有的写入命令会追加到 aof_buf(缓冲区)中。不直接写到磁盘文件是为了提升效率,是磁盘负载不成为性能瓶颈。还有另一个好处,Redis 可以提供多种缓冲区同步硬盘的策略,在性能和安全性方面做出平衡。
- AOF 缓冲区根据对应的策略向硬盘做同步操作。
- 随着 AOF 文件越来越大,需要定期对 AOF 文件进行重写,达到压缩的目的。
- 当 Redis 服务器重启时,可以加载 AOF 文件进行数据恢复。
重写后的 AOF 文件为什么可以变小?
执行 bgrewriteaof 命令可以重写 AOF 文件。
- 进程中已经超时的文件不在写入。
- 旧的 AOF 文件含有无效命令,重写使用进程内数据直接生成,这样新的 AOF 文件只保留最终数据的写入命令。
- 多条写命令可以合并为一个,为了防止单条命令过大造成客户端缓冲区溢 出,对于 list、set、hash、zset 等类型操作,以 64 个元素为界拆分为多条。
AOF 重写降低了文件占用空间,除此之外,另一个目的是:更小的 AOF 文件可以更快地被 Redis 加载。
手动触发:直接调用 bgrewriteaof 命令。
自动触发:根据 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数确定自动触发时机。自动触发时机=aof_current_size>auto-aof-rewrite-minsize&&(aof_current_size-aof_base_size)/aof_base_size>=auto-aof-rewritepercentage。
启动流程:
- AOF 持久化开启且存在 AOF 文件时,优先加载 AOF 文件。
- AOF 关闭或者 AOF 文件不存在时,加载 RDB 文件。
- 加载 AOF/RDB 文件成功后,Redis 启动成功。
- AOF/RDB 文件存在错误时,Redis 启动失败并打印错误信息。