一. Redis持久化的意义
Redis为什么要做持久化?首先我们要先定义一下,什么是持久化?从百度百科上查询到持久化的定义是,把数据保存到可永久保存的存储设备中。我的理解就是将不易存储的数据,转化为可以长期存储的数据,并且两种类型的数据可以相互转化。
Redis作为一款数据库中间件,数据主要存储在运行内存中。运行内存做为易失性存储器,一旦服务器发生灾难性故障,那么Redis的数据将会全部丢失,并且无法恢复原始数据。Redis持久化可以最大程度减少这部分损失,尽可能地恢复故障前的数据。
二. Redis持久化方式
Redis持久化的方式有三种
· RDB(Redis DataBase): 快照持久化。RDB持久化是通过快照的方式,将指定时刻的内存数据转存为文件保存至磁盘中。
· AOF(Append Only File): 指令持久化。AOF持久化是将每一条增删改指令保存到文件中。
· 混合: Redis 4.0 中提出了一个混合使用 AOF 日志和内存快照的方法。简单来说,内存快照以一定的频率执行,在两次快照之间,使用 AOF 日志记录这期间的所有命令操作。
三. AOF与RDB介绍
RDB
Redis配置RDB(配置文件)
# 在100秒内发生了10次的键变更,触发RDB
save 100 10
# 在60秒内发生了30次的键变更,触发RDB
save 60 30
# 以下设置方式为关闭RDB快照功能
save ""
主从同步触发RDB
在 Redis 主从复制中,当从节点执行全量复制操作时,主节点会执行RDB操作,并将存储文件发送给从节点。
指令触发RDB
save命令触发RDB,该命令触发RDB会使Redis处于阻塞状态,导致Redis服务被中断,直到数据备份完成。不推荐使用该方法来触发。flushall命令作用是清空 Redis 数据库,当 Redis 执行了flushall命令之后,则会触发自动持久化,把 RDB 文件清空。debug reload命令作用是保存内存数据至存储文件,并清空当前数据库,重新加载存储文件数据到内存中。debug reload命令作用是保存内存数据至存储文件,并清空当前数据库,重新加载存储文件数据到内存中。bgsave命令触发RDB,执行该命令会fork一个子进程,由子进程执行RDB,RDB过程中,只有fork的时候,会造成Redis服务不可用,内存数据存储的过程中不会影响Redis的正常使用。 bgsave启动流程
RDB的优点
- RDB文件是某个时间节点的快照,默认使用LZF算法进行压缩,压缩后的文件体积远远小于内存大小,适用于备份、全量复制等场景
- Redis加载RDB文件恢复数据要远远快于AOF方式
RDB的缺点
-
RDB方式实时性不够,无法做到秒级的持久化
-
每次调用bgsave都需要fork子进程,fork子进程属于重量级操作,频繁执行成本较高
AOF
AOF会将每一条数据变更指令都记录到存储文件中,随着记录的时间越来越长,文件中无用的指令就会越来越多,存储文件也变的越来越大。存储文件无限制的增长下去,严重会影响操作系统,并且Redis从AOF中恢复也需要花费更多的时间。为了解决这个问题,Redis提供了AOF重写的功能。
Redis 配置AOF(配置文件)
# appendonly参数开启AOF持久化
appendonly no
# AOF持久化的文件名,默认是appendonly.aof
appendfilename "appendonly.aof"
# AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的
dir ./
# 同步策略 将日志数据真正写入存储文件的操作设置。这一点与Linux对磁盘设备的操作方式有关,有兴趣的同学可以去学习一下这块内容。
# always 同步写入,每执行完一条语句就写入存储文件。优点:精准性高,每次请求都能够写入文件。缺点:性能损耗大,每次请求都需要操作磁盘。
# everysec 每秒写入一次,字面意思,每一秒将执行语句写入存储文件。优点:中庸,相较于always,性能损耗小,相较于no,如果系统宕机,只会损失1秒的请求。
# no Redis不去管理磁盘写入,由操作系统来执行写入。优缺点与always相反。
# appendfsync always
appendfsync everysec
# appendfsync no
# AOF重写期间是否同步
# AOF在重写期间,Redis接收到的指令是否要写入新的存储文件中。
# 如果设置为no,则会在重写的时候造成Redis的阻塞,导致Redis的服务中断。
# 如果设置为yes,则在AOF期间的指令会被存储到缓存中,等到重写结束之后再写入存储文件中
no-appendfsync-on-rewrite no
# 加载aof出错如何处理
# aof文件出现异常,比如结束词不正确或者文件损坏时,Redis会做出怎样的反应。
# yes Redis打印异常日志,Redis正常运行
# no Redis服务会被中止
aof-load-truncated yes
# 是否开启混合模式
# yes 开启混合模式,aof的指令会以[RDB file][AOF tail]格式存储
# no 关闭混合模式
aof-use-rdb-preamble yes
# 重写aof文件入盘策略
# 在重写aof文件的时候,每当文件达到32MB的时候,会讲这部分文件先写入磁盘,避免大文件一次性写入占用过多的IO
# yes 开启
# no 关闭
aof-rewrite-incremental-fsync yes
AOF重写功能配置,以下两个配置可以设置重写的触发机制,只有两个同时满足时,才能触发重写。
# 当前aof文件大小和上一次重写后aof文件大小的差值,再除以上一次重写后aof文件大小。大于设置值的时候,触发重写机制。
# (AOF文件大小 - 上一次AOF文件大小)/ 上一次AOF文件大小
# 0代表关闭AOF
auto-aof-rewrite-percentage 100
# 表示运行AOF重写时文件的最小大小,默认为64MB
auto-aof-rewrite-min-size 64mb
手动触发 AOF
bgrewriteaof命令会在后台启动子进程进行AOF重写操作。
AOF的优点
- AOF实时性比RDB高出很多,数据记录完整性高出RDB很多。
AOF的缺点
- AOF运行效率低于RDB
- AOF存储文件要大于RDB
参考文章