Redis 持久化
Redis是一种基于内存进行读写操作的Nosql数据库, 所以性能相对比较高. 但是如果数据始终保存在内存中没有持久化, 在服务器进行重启的时候那么数据将会丢失. 所以, Redis提供了持久化的解决方案. 这也是和Memcached的一个区别之一, Memcached是不提供持久化的.
持久化的方式
Redis采用三种方式进行持久化:
-
快照方式(RDB): 将某一时刻的内存数据, 以二进制的方式写入磁盘
-
文件追加的方式(AOF): 记录所有的操作命令, 并以文本行驶追加到文件中
-
混合持久化: 在Redis 4.0之后, 混合持久化融合了RDB和AOF的有点, 在写入时先将当前数据以RDB的形式写入到文件的开头, 再将后续的操作命令以AOF的格式写入到文件中, 这样可以保证redis的重启速度又能降低数据丢失的风险.
RDB持久化
触发时机
手动触发
手动触发的操作有两个: save 和 bgsave.两者的区别主要是是否阻塞线程.
-
save: 会阻塞主线程, 主线程会切换到RDB持久化的任务中
-
bgsave: 不会阻塞主线程, bgsave(background save) 顾名思义主线程会fork一个子线程用于RDB持久化任务. 主线程只有在fork子线程的过程中会发生阻塞
自动触发
自动触发的来源有以下几种情况:
-
save m n
: 指在m秒内n个key发生了变更, 触发RDB持久化. 我们可以在redis的配置文件中找到改设置.当满足条件是会自动触发一次bgsave
命令. -
主从同步触发: 在redis主从复制中, 当从节点执行全量复制操作时, 主节点会执行
bgsave
, 并将RDB文件发送给从节点, 该过程会触发持久化.
配置
我们可以在redis的配置文件中找到相关的配置信息:
RDB 保存的条件
save 900 1
save 300 10
save 60 10000
# bgsave 失败之后,是否停止持久化数据到磁盘,yes 表示停止持久化,no 表示忽略错误继续写文件。
stop-writes-on-bgsave-error yes
# RDB 文件压缩
rdbcompression yes
# 写入文件和读取文件时是否开启 RDB 文件检查,检查是否有无损坏,如果在启动是检查发现损坏,则停止启动。
rdbchecksum yes
# RDB 文件名
dbfilename dump.rdb
# RDB 文件目录
dir ./</pre>
RDB文件恢复
当服务启动时, redis会加载RDB文件dump.rdb, 恢复持久化数据. 所以启动时需要确认配置文件中指定的rdb文件目录是否有dump.rdb文件
RDB的优缺点
- 优点
- RDB为二进制内容, 占用内存更小
- RDB对灾难恢复非常有用, 可以更快的传输到远程服务器进行redis服务恢复
- RDB可以更大程度的提高redis运行效率, 因为每次持久化时redis都会fork子线程进行持久化, 而主线程不会有磁盘的IO操作
- 与AOF格式相比, RDB可以更快重启
- 缺点
- RDB只能每隔一段时间持久化数据, 所以在触发持久化空窗期发生服务宕机, 会丢失一部分数据
- RDB需要fork子线程才能进行持久化, 如果数据集很大, fork可能很耗时, 并且如果数据集很大且CPU性能不佳,可能导致Redis停止为客户端服务
AOF持久化
AOF的策略是对每个key的变更操作追加到日志文件中
触发时机
自动触发
两种情况可以出发AOF持久化, 分别是: 满足AOF设置的策略触发和满足AOF重写触发.
AOF策略触发:
- always: 每条redis操作命令都会写入到磁盘中, 最多丢失一条数据
- everysec: 每秒写入磁盘, 最多丢失一秒数据
- no: 不设置写入规则, 根据当前操作系统来决定何时写入, Linux默认是每隔30秒
# 开启每秒写入一次的持久化策略
appendfsync everysec
手动触发
在客户端执行bgrewriteaof
命令可以手动触发AOF持久化.
AOF重写
AOF通过记录redis的执行命令操作日志来记录日志, 时间越久AOF文件会越来越多, 不仅会增加存储压力在重启服务时, 重启速度也会变得很慢. 为了解决这个问题, redis提供了AOF重写功能.
什么是AOF重写
当我们设置一个值, 并对改值进行了100次操作, 显然会有101条操作记录. 所谓AOF重写就是减去中间的操作记录, 只记录最后一次操作的结果即可. 这样可以少掉很多不必要的中间结果记录.
AOF重写实现
在redis配置文件中配置相关配置:
- auto-aof-rewrite-min-size:允许 AOF 重写的最小文件容量,默认是 64mb
- auto-aof-rewrite-percentage:AOF 文件重写的大小比例,默认值是 100,表示 100%,也就是只有当前 AOF 文件,比最后一次(上次)的 AOF 文件大一倍时,才会启动 AOF 文件重写
AOF的重写流程是重新生成一个全新的文件, 并将当前数据的最少操作命令保存在新的文件上, 当所有数据都保存到新文件后, redis会交换两个文件, 并把最新的持久化操作命令追加到新文件上.
配置
# 是否开启 AOF,yes 为开启,默认是关闭
appendonly yes
# AOF 默认文件名
appendfilename "appendonly.aof"
# AOF 持久化策略配置
# appendfsync always
appendfsync everysec
# appendfsync no
# AOF 文件重写的大小比例,默认值是 100,表示 100%,也就是只有当前 AOF 文件,比最后一次的 AOF 文件大一倍时,才会启动 AOF 文件重写。
auto-aof-rewrite-percentage 100
# 允许 AOF 重写的最小文件容量
auto-aof-rewrite-min-size 64mb
# 是否开启启动时加载 AOF 文件效验,默认值是 yes,表示尽可能的加载 AOF 文件,忽略错误部分信息,并启动 Redis 服务。
# 如果值为 no,则表示,停止启动 Redis,用户必须手动修复 AOF 文件才能正常启动 Redis 服务。
aof-load-truncated yes
优缺点
- 优点
- 持久化数据更完整, 提供三种策略: 每个操作持久化, 每隔1秒持久化, 跟随系统的持久化策略. 其中每隔一秒持久化是在系统安全和性能两方面权衡下来更好的选择
- 采用命令追加的方式, 不会出现文件损坏问题, 即时由于某些意外原因, 导致持久化写入一般也可以通过
redis-check-aof
工具修复 - 持久化文件方便理解和解析
- 缺点
- 文件相对RDB要大
- redis负载比较高的情况下, RDB比AOF性能更好
- RDB使用快照形式来持久化整个redis数据库, AOF通过命令追加的方式. 理论上RDB健壮性更好
混合持久化
RDB和AOF各有利弊, 在新版本的redis中为了结合两者的优点退出了混合持久化的功能.
混合持久化的流程:

参考:
Redis 持久化——AOF