Redis 持久化
Redis 持久化RDB 和 AOF 是 Redis 提供的两种缓存持久化机制两种机制各有优缺点为了保证较高的数据安全性实际应用中往往会结合使用① RDB 机制RDB 全称RedisDatabaseBackup fileRedis 数据备份文件也被叫做 Redis 数据快照。简单来说就是把内存中的所有缓存数据都记录到磁盘中。当 Redis 实例故障重启后会自动从磁盘读取快照文件即 RDB 文件并恢复数据。RDB 持久化主要会在以下四种情况下执行执行 save 命令save 命令会驱使 Redis 主进程执行 RDB整个过程其它所有命令都会被阻塞而当缓存数据量较大时备份执行时间也较长严重影响业务因此不推荐使用。执行 bgsave 命令bgsave 命令会开启独立的进程执行 RDB整个过程 Redis 主进程可以继续处理用户请求不会进入阻塞状态。Redis 停机时当正常停止 Redis 时会自动执行一次 RDB 操作用于备份数据而当使用 kill 命令或服务器宕机等原因导致 Redis 进程非正常停止时则不会执行。RDB 触发条件达成时在 Redis 的配置文件中可以对 RDB 机制的相关参数进行配置。# RDB触发条件配置(save 表示禁用RDB) # save [time] [count]:指定时间内(单位:秒)至少有指定数量个key发生变化则执行bgsave save 900 1 save 300 10 save 60 10000 # RDB文件是否压缩(由于压缩会影响CPU性能因此不建议开启) rdbcompression yes # RDB文件名称 dbfilename dump.rdb # 当RDB持久化出现问题时(如:磁盘空间不足)是否拒绝新的写入操作(默认为yes) stop-writes-on-bgsave-error no # RDB文件保存路径(默认为当前Redis运行路径) dir ./在间隔时间内若未达到指定修改频次则不会触发 RDB 机制若此时 Redis 宕机则会造成数据丢失因此 RDB 并不能保证数据的绝对安全实际使用中应配置合理的触发条件尽可能降低数据丢失的风险。建议不要将 RDB 文件与生产 Redis 服务器保存在一起以防生产机损坏后备份文件也丢失。bgsave 命令执行 RDB 原理当 bgsave 命令被执行时操作系统会根据 Redis 主进程 fork 出一个子进程子进程会拷贝主进程维护的页表信息因此可以共享主进程的内存数据然后由子进程读取内存数据并写入 RDB 文件。在此过程中物理内存中的缓存数据会进入只读状态当主进程执行写操作时会以 copy-on-write 的模式将只读的缓存数据拷贝一份进行修改同时更新主进程维护的页表信息从而做到与子进程读取数据操作的隔离因此在子进程读取数据过程中更新的缓存数据不会在此次 RDB 中被备份。虽然 bgsave 生成 RDB 文件的过程中不会阻塞 Redis 主进程但 fork 子进程的操作会阻塞主进程若执行太过频繁或数据量过大也会严重影响 Redis 的性能。因此实际使用中要合理评估 RDB 触发的频率并保证单个 Redis 节点中的数据量不要过大。在子进程读取数据的过程中若主进程执行了大量的写操作会造成大量的缓存数据被拷贝从而导致内存使用率增大。因此在实际使用中要预留足够的剩余内存避免在 RDB 过程中发生内存溢出问题。② AOF 机制AOF 全称为AppendOnlyFile追加文件Redis 处理的每一个写命令都会以追加的方式记录在 AOF 文件因此可以看做是 Redis 的命令日志文件AOF 机制默认是关闭的需要在 Redis 配置文件中进行相关配置来开启# 是否开启AOF功能(默认为no) appendonly yes # AOF文件的名称 appendfilename appendonly.aof # AOF刷盘策略配置(默认为appendfsync everysec) # 每执行一次写命令立即写入AOF文件 # appendfsync always # 写命令执行完后先存入AOF缓冲区,每隔1秒将缓冲区数据写入AOF文件 appendfsync everysec # 写命令执行完后先存入AOF缓冲区,在操作系统调度下将缓冲区数据写入AOF文件 # appendfsync no # AOF文件重写配置 # AOF文件体积最小达到多少时才开启重写 auto-aof-rewrite-min-size 64mb # AOF文件比上次触发重写后体积增长达到多少百分比时触发 auto-aof-rewrite-percentage 100AOF 文件的保存路径和 RDB 文件的保存路径一样都是通过 dir 参数来进行配置。AOF 刷盘策略当命令到达 Redis Server 以后并不是直接写入 AOF 文件而是将其先存入 AOF 缓存中再根据配置的刷盘策略将缓存中的数据写入 AOF 文件。当 AOF 刷盘策略配置为 always 时会造成大量的磁盘 IO严重影响性能。配置为 no 则无法预知刷盘的时机若在 AOF 缓冲区中的数据还未写入 AOF 文件时 Redis 宕机则会造成缓冲区中数据的丢失。因此在实际使用中通常采用 everysec 的策略将数据丢失的影响范围控制在 1 秒之内的同时保证性能AOF 文件重写由于 AOF 持久化需要不断将写命令记录到 AOF 文件中随着 Redis 的不断运行AOF 文件中会包含很多冗余操作如对同一个 Key 的多次写操作其实只有记录最终状态才有意义造成内存的浪费。我们可以通过配置 AOF 文件重写机制或手动执行 bgrewriteaof 命令触发 AOF 文件重写功能对 AOF 文件的内容进行压缩只保留可以恢复数据的最小指令集。AOF 重写原理与 RDB 相似AOF 重写时也会 fork 一个子进程进行日志重写在此期间新来的写入命令都会被保存到 AOF 重写缓冲区aof_rewrite_buf_blocks中直到子进程完成重写后才会将缓冲区中的数据写到新的 AOF 文件中。在进行 AOF 重写时原 AOF 文件的处理工作会如常进行这样即使在重写的过程中发生停机现有的 AOF 文件也是可用的。③ 混合机制在同时开启 RDB 和 AOF 持久化时Redis 启动时只会加载 AOF 文件不会加载 RDB 文件将 Redis 配置文件中 aof-use-rdb-preamble 配置项的值设为 yes 即可开启混合持久化机制aof-use-rdb-preamble yes混合持久化机制只作用于 AOF 文件的重写过程当开启混合持久化时执行 AOF 重写时 fork 出的子进程会先将当前的全量数据以 RDB 方式写入新的 AOF 文件然后再将 AOF 重写缓冲区中的增量命令以 AOF 方式写入写入完成后通知主进程将新的 AOF 文件替换旧的的 AOF 文件。