持久化数据是将内存中的数据写入到硬盘里面,大部分原因是为了之后重用数据(比如重启机器、机器故障之后恢复数据),或者是为了防止系统故障而将数据备份到一个远程位置
Redis 是内存型数据库,支持将内存中数据持久化到磁盘。一方面,可保证数据断电后不丢失,另一方面,保存中间结果,不必重新计算。
Redis 支持 2 种持久化:
- RDB (redis database) 持久化
- AOF (append only file) 持久化
RDB 持久化即快照持久化,通过创建快照来获得 Redis 存储在内存中数据在某个时间点上的副本。在创建快照后,用户可对快照备份,可以将快照复制到其他服务器从而创建具有相同数据的服务器副本,还可以将快照留在原地以便重启服务器的时候使用。
快照持久化是 Redis 默认采用的持久化方式,可在 Redis.conf 文件中进行配置:
save 60 1
# 在60秒(1分钟)之后,如果至少有1个键发生变化,Redis 就会自动触发 BGSAVE 命令创建快照。
stop-writes-on-bgsave-error yes
# 表示备份进程出错的时候,主进程就停止接收新的写入操作,是为了保护持久化数据的一致性。
rdbcompression no
# RDB 的压缩设置为 no,因为压缩会占用更多的 CPU 资源客户端向 Redis 发送 BGSAVE 命令来创建一个快照。对于支持 BGSAVE 命令的平台来说(基本上所有平台支持,除了 Windows 平台),Redis 会调用 fork 来创建一个子进程,然后子进程负责将快照写入硬盘,而主进程则继续处理命令请求。
对于如下命令:
save 60 10000表示从 Redis 最近一次创建快照之后算起,满足 “60 s 内 10000 次写入”,Redis 会自动触发 BGSAVE 命令。
AOF 持久化将被执行的写命令写到 AOF 文件末尾,记录数据发生的变化。
Redis 值只要从头到尾重新执行一次 AOF 文件包含的所有写命令,就可恢复 AOF 文件所记录的数据。
默认情况下,Redis 没有开启 AOF(append only file)方式的持久化,可以通过 appendonly 参数开启:
appendonly yesappendfsync always # 同步选项
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb使用 AOF 持久化需要设置同步选项,从而确保写命令同步到磁盘文件上的时机。
这是因为对文件进行写入并不会马上将内容同步到磁盘上,而是先存储到缓冲区,然后由操作系统决定什么时候同步到磁盘。有以下同步选项:
| 同步选项 | 同步频率 | 说明 |
|---|---|---|
| always | 每个 Redis 写命令都要同步写入磁盘 | 当系统发生崩溃时,丢失的数据减到最少; 需要对磁盘大量写入,速度会受到磁盘限制 |
| everysec | 每秒执行一次同步,显示地将多个写命令同步到磁盘 | 性能上和不使用任何持久化特性时相差无几, 可保证数据即使出现系统崩溃,用户也最多只会丢失 1 秒内产生的数据 |
| no | 由操作系统来决定何时进行同步 | 不会对 Redis 性能产生影响,但系统崩溃将导致 Redis 丢失不定量的数据, 若用户写入磁盘处理写入速度不够快,当缓冲区被等待写入磁盘的数据填满时,Redis 写入操作会被阻塞,并导致 Redis 处理命令请求变慢 |
AOF 持久化存在的问题:
- 随着 Redis 不断运行,AOF 文件的体积会不断增长,占用更多的磁盘空间
- 若 AOF 文件体积非常大,则恢复的时间可能会比较长
为了解决 AOF 文件不断增大的问题,我们采用重写/压缩 AOF 文件的方式:
用户发送 BGREWRITEAOF 命令,通过移除 AOF 文件中冗余命令来重写 AOF 文件来减小 AOF 文件的体积。也就是说,AOF 重写产生了一个新的 AOF 文件,这个新的 AOF 文件和原有的 AOF 文件所保存的数据库状态一样,但体积更小。
BGREWRITEAOF 原理:
Redis 维护一个 AOF 重写缓冲区(aof_rewrite_buf)。在子进程创建新的 AOF 文件期间,记录服务器执行的所有写命令。当子进程完成创建新 AOF 文件的工作之后,服务器会将重写缓冲区中的所有内容追加到新 AOF 文件的末尾,使得新旧两个 AOF 文件所保存的数据库状态一致。最后,服务器用新的 AOF 文件替换旧的 AOF 文件,以此来完成 AOF 文件重写操作。
| 持久化方式 | 优点 | 缺点 |
|---|---|---|
| RDB | 文件小,恢复快 | 如果系统发生故障,会丢失最近一次生成快照后写入的数据; 是压缩文件,可读性较差 |
| AOF | 可读性好; 数据不易丢失(丢失 1 秒内产生的数据) |
文件体积大,占用磁盘空间; 恢复时间长 |
Redis 4.0 开始支持 RDB和 AOF 的混合持久化。默认是关闭的,需要配置:
aof-user-rdb-preamble yes如果把混合持久化打开,AOF 重写的时候就直接把 RDB 的内容写到 AOF 文件开头。这样做的好处是可以结合 RDB 和 AOF 的优点, 快速加载同时避免丢失过多的数据。当然缺点也是有的, AOF 里面的 RDB 部分是压缩格式不再是 AOF 格式,可读性较差。
