文章目录
Redis是内存数据库,如果不将内存中的持久化状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失。所以Redis提供了持久化功能!
虽然redis是内存数据库,但是它为数据的持久化提供了两个技术:AOF 日志和 RDB 快照
所谓的快照,就是记录某一个瞬间东西,比如当我们给风景拍照时,那一个瞬间的画面和信息就记录到了一张照片。
所以,RDB 快照就是记录某一个瞬间的内存数据,记录的是实际数据,而 AOF 文件记录的是命令操作的日志,而不是实际的数据。
因此在 Redis 恢复数据时, RDB 恢复数据的效率会比 AOF 高些,因为直接将 RDB 文件读入内存就可以,不需要像 AOF 那样还需要额外执行操作命令的步骤才能恢复数据。
一、持久化之RDB(RedisDateBase)操作
1.1 概念
RDB持久化就是将当前进程中的数据生成快照保存在硬盘中(因此也称为快照持久化),保存的文件后缀是rdb;
当redis重新启动时,可以读取快照文件恢复数据。
它是在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读入内存里。
RDB持久化也是默认是持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。
一般Redis默认启动RDB。
1.2 快照怎么用
redis提供了两个命令来生成RDB文件,分别是 save 和 bgsave ,他们的区别就在于是否在「主线程」里执行:
- 执行了 save 命令,就会在主线程生成 RDB 文件,由于和执行操作命令在同一个线程,所以如果写入 RDB 文件的时间太长,会阻塞主线程;
- 执行了 bgsave 命令,会创建一个子进程来生成 RDB 文件,这样可以避免主线程的阻塞;
RDB 文件的加载工作是在服务器启动时自动执行的,Redis 并没有提供专门用于加载 RDB 文件的命令。
Redis 还可以通过配置文件的选项来实现每隔一段时间自动执行一次 bgsave 命令,默认会提供以下配置:
别看选项名叫 save,实际上执行的是 bgsave 命令,也就是会创建子进程来生成 RDB 快照文件。
只要满足上面条件的任意一个,就会触发一次RDB。
1.3 过程
redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换持久化好的文件,整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能,如果需要进行大规模数据的回复,且对于数据恢复的完整性不是特别敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能会丢失。
1.4 测试RDB机制
1.设置新的触发机制
2.登录客户端查看RDB文件的生成目录
config get dir
2.删除原来的rdb文件
查找rdb文件:
删除:
3.登录客户端,设置5个值
4.查看生成目录(60秒内新增5个key,所以生成了dump.rdb文件)
5.结束redis的进程(如果没有RDB,数据应该会丢失)
确认进程已经结束:
7.重新启动客户端,获取k1的值,如果可以获取到,证明持久化起到作用了。
8.删除rdb文件,再测试下直接清空数据库,看是否也会触发持久化
删除rdb文件:
在客户端执行flushall命令:
发现也生成了rdb文件:
1.5 触发机制
1.save规制满足情况下,会自动触发rdb规则,生成文件
2.执行flushall命令,也会触发rdb规则,生成文件
3.退出redis,也会触发rdb规则,生成文件
如何恢复rdb文件?
只需要将rdb文件放在redis启动目录下就可以,redis启动时,会自动检查dump.rdb文件恢复数据!
1.6 优缺点
优点:
- 适合大规模的数据恢复
- 对数据的完整性要求不高
缺点:
- Redis 的快照是全量快照,也就是说每次执行快照,都是把内存中的所有数据都记录到磁盘中。所以可以认为,执行快照是一个比较重的操作,如果频率太频繁,可能会对 Redis 性能产生影响。如果频率太低,服务器故障时,丢失的数据会更多。
- 需要一定时间间隔进行操作,如果redis意外宕机了,最后一次修改数据就没有了!(通常可能设置至少 5 分钟才保存一次快照,这时如果 Redis 出现宕机等情况,则意味着最多可能丢失 5 分钟数据。)
- 备份时占用内存,因为Redis 在备份时会独立创建一个子进程,将数据写入到一个临时文件(此时内存中的数据是原来的两倍哦),最后再将临时文件替换之前的备份文件。
二、持久化之AOF日志(Append Only File)
2.1 认识AOF
AOF日志是通过保存Redis写命令来记录数据库数据的。
以日志的形式来记录每一个写操作,将Redis执行过的所有指令记录下来(读操作不记录),只允许追加文件但不可以改写文件,Redis启动之初会读取该文件重新构建数据。换言之,Redis重启的话,就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
AOF保存的是appendonly.aof文件。
默认是不开启的,需要手动进行配置(将no改为yes,就开启了AOF)。重启Redis就生效了。
2.2 AOF的配置
# appendonly参数开启AOF持久化
appendonly no
# AOF持久化的文件名,默认是appendonly.aof
appendfilename "appendonly.aof"
# AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的
dir ./
# 同步策略
# appendfsync always
appendfsync everysec
# appendfsync no
# aof重写期间是否同步
no-appendfsync-on-rewrite no
# 重写触发配置(AOF重写)
#AOF会记录每个写命令到AOF文件,随着时间越来越长,AOF文件会变得越来越大。如果不加以控制,会对Redis服务器,甚至对操作系统造成影响,而且AOF文件越大,数据恢复也越慢。为了解决AOF文件体积膨胀的问题,Redis提供AOF文件重写功能来对AOF文件进行“瘦身”。Redis通过创建一个新的AOF文件来替换现有的AOF,新旧两个AOF文件保存的数据相同,但新AOF文件没有了冗余命令。
#简单来说,AOF重写就是把旧AOF日志文件的多条命令,在重写后变成新日志文件的一条命令。
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb #aof默认文件的无限制追加。如果aof文件大于64m,太大了,会fork一个新的进程来将文件重写
# 加载aof出错如何处理
aof-load-truncated yes
# 文件重写策略
aof-rewrite-incremental-fsync yes
2.3 redis-check-aof
如果这个aof文件有错位,这时候redis是启动不起来的,我们需要修复这个aof文件。redis给我们提供了一个工具 redis-check-aof --fix
开启AOF:
关闭进程,重启Redis:
查看aof文件是否存在:
增加命令:
查看aof文件里是否存在命令:
关闭redis进程,破坏aof文件:
再去启动redis,发现启动失败:
这时候,可以用检测文件自动修复文件:
查看aof文件是否修复成功:
如果文件正常,重启就可以恢复了。
2.4 如何实现AOF日志?
AOF日志记录Redis的每个写命令,步骤分为:命令追加(append)、文件写入(write)和文件同步(sync)。
2.4.1 命令追加
当AOF持久化功能打开了,服务器在执行完一个写命令之后,会以协议格式将被执行的写命令追加到服务器的 aof_buf 缓冲区。
2.4.2 文件写入和同步
关于何时将 aof_buf 缓冲区的内容写入AOF文件中,Redis提供了三种写回策略:
- Always,同步写回:每个写命令执行完,立马同步地将日志写回磁盘;
- Everysec,每秒写回:每个写命令执行完,只是先把日志写到AOF文件的内存缓冲区,每隔一秒把缓冲区中的内容写入磁盘;
- No,操作系统控制的写回:每个写命令执行完,只是先把日志写到AOF文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘。
2.5 优缺点
优点:
- 每一次修改都同步,文件的完整性会更好
- 每秒同步一次,可能会丢失一秒的数据
- 从不同步,效率最高
缺点:
- 相对于数据文件来说,AOF文件远远大于RDB文件,修复的速度也比RDB慢
- AOF运行效率比RDB慢
三、混合持久化
RDB 和 AOF 持久化各有利弊,RDB 可能会导致一定时间内的数据丢失,而 AOF 由于文件较大则会影响 Redis 的启动速度,为了能同时使用 RDB 和 AOF 各种的优点,Redis 4.0 之后新增了混合持久化的方式。
3.1 混合持久化工作在AOF的重写过程
当开启了混合持久化时,在 AOF 重写日志时,fork 出来的重写子进程会先将与主线程共享的内存数据以 RDB 方式写入到 AOF 文件,然后主线程处理的操作命令会被记录在重写缓冲区里,重写缓冲区里的增量命令会以 AOF 方式写入到 AOF 文件,写入完成后通知主进程将新的含有 RDB 格式和 AOF 格式的 AOF 文件替换旧的的 AOF 文件。(在开启混合持久化的情况下,AOF 重写时会把 Redis 的持久化数据,以 RDB 的格式写入到 AOF 文件的开头,之后的数据再以 AOF 的格式化追加的文件的末尾。)
混合持久化的数据存储结构:
3.2 混合持久化的加载流程
- 判断是否开启 AOF 持久化,开启继续执行后续流程,未开启执行加载 RDB 文件的流程;
- 判断 appendonly.aof 文件是否存在,文件存在则执行后续流程;
- 判断 AOF 文件开头是 RDB 的格式, 先加载 RDB 内容再加载剩余的 AOF 内容;
- 判断 AOF 文件开头不是 RDB 的格式,直接以 AOF 格式加载整个文件。
3.3 优缺点
优点:
- 混合持久化结合了 RDB 和 AOF 持久化的优点,开头为 RDB 的格式,使得 Redis 可以更快的启动,同时结合 AOF 的优点,有减低了大量数据丢失的风险。
缺点:
- AOF 文件中添加了 RDB 格式的内容,使得 AOF 文件的可读性变得很差;
- 兼容性差,如果开启混合持久化,那么此混合持久化 AOF 文件,就不能用在 Redis 4.0 之前版本了。
3.4 测试运行
3.4.1 开启混合持久化
查询是否开启混合持久化:
其中 yes 表示已经开启混合持久化,no 表示关闭,Redis 5.0 默认值为 yes。
如果关闭的情况下,可以通过以下两种方式开启:
- 通过命令行开启
config set aof-use-rdb-preamble yes
命令行设置配置的缺点是重启 Redis 服务之后,设置的配置就会失效。
- 通过修改 Redis 配置文件开启(redis.conf)
3.4.2 数据恢复
混合持久化的数据恢复和 AOF 持久化过程是一样的,只需要把 appendonly.aof 放到 Redis 的根目录,在 Redis 启动时,只要开启了 AOF 持久化,Redis 就会自动加载并恢复数据。