1、为什么要持久化
Redis 的数据 全部存储 在 内存 中,如果 突然宕机,数据就会全部丢失,因此必须有一套机制来保证 Redis 的数据不会因为故障而丢失,这种机制就是 Redis 的 持久化机制,它会将内存中的数据库状态 保存到磁盘 中。
2、redis的持久化方式:RDB和AOF
RDB持久化:原理是将Reids在内存中的数据库记录定时保存到磁盘上。(定时对内存中的数据生成快照,以文件形式保存在硬盘中)
AOF持久化(append only file):原理是将Reids 的操作日志以追加的方式写入文件,类似于MySQL的binlog。(类似于Mysql的二进制日志)(以追加的方式将写和删的操作命令记录到AOF文件中)
由于AOF持久化的实时性更好,即当进程意外退出时丢失的数据更少,因此AOF是目前主流的持久化方式,不过RDB持 久化仍然有其用武之地。(RDB体积小,恢复速度更快。对性能影响较小。)
3、RDB持久化(每隔一段时间进行快照存储)
描述:类似于快照。在某个时间点,将 Redis 在内存中的数据库状态(数据库的键值对等信息)保存到磁盘里面。RDB 持久化功能生成的 RDB 文件是经过压缩的二进制文件。
RDB触发快照的机制
1、符合自定义配置的快照规则-----------自动触发
2、执行save或者bgsave命令-------------手动触发
3、执行flushall命令
4、执行主从复制操作(第一次)
【1】save触发
该命令会阻塞当前的Redis服务器,执行save命令期间,rRedis不能处理其他命令,直到RDB过程完成为止。具体流程如下:
执行完成时候如果存在老的RDB文件,就把新的替代掉旧的。我们的客户端可能都是几万或者是几十万,这种方式显然不可取。
【2】bgsave触发
执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。具体流程如下:
bgsave在执行该命令时会fork出一个新的线程,单独执行rdb持久化操作,而不影响其他客户对redis服务的操作。
不管使用save还是bgsave都需要手动输入,我们也可以通过配置文件完成自动化rdb操作。
【3】手动配置
文件配好后需要重启redis服务,可以删除dump.rdb检查是否配置成功
删掉dump.rdb文件
重启服务
存储数据
自动生成文件
RDB的执行流程
1. Redis父进程首先判断:当前是否在执行save,或bgsave/bgrewriteaof(aof文件重写命令)的子进程,如果在执行则bgsave命令直接返回;
2. 父进程执行fork(调用OS函数复制主进程)操作创建子进程,这个过程中父进程是阻塞的,Redis不能执行来自客户端的任何命令;
3. 父进程fork后,bgsave命令返回”Background saving started”信息并不再阻塞父进程,并可以响应其他命令;
4. 子进程创建RDB文件,根据父进程内存快照生成临时快照文件,完成后对原有文件进行原子替换(RDB始终完整);
5. 子进程发送信号给父进程表示完成,父进程更新统计信息。
6. 父进程fork子进程后,继续工作。
4、RDB的优缺点
优点:
- RDB 快照是某一时刻 Redis 节点内存数据,非常适合做备份,上传到远程服务器或者文件系统中,用于容灾备份
- 数据恢复时 RDB 要远远快于 AOF
缺点:
- RDB 持久化方式数据没办法做到实时持久化/秒级持久化。我们已经知道了 bgsave 命令每次运行都要执行 fork 操作创建子进程,属于重量级操作,频繁执行成本过高。
- RDB 文件使用特定二进制格式保存,Redis 版本演进过程中有多个格式 的 RDB 版本,存在老版本 Redis 服务无法兼容新版 RDB 格式的问题
优点: ----数据恢复速度快。
缺点: ----数据完整性差--会丢失最后一段时间的数据
5、AOF持久化
日志追加持久化,当我们执行写操作,会触发一个函数write,把会把写操作的命令追加到一个日志文件appendfile中。当服务器启动时会把appendfile中的命令从新执行一遍。默认不开启。
描述:保存 Redis 服务器所执行的所有写操作命令来记录数据库状态,并在服务器启动时,通过重新执行这些命令来还原数据集。
原理
AOF 持久化功能的实现可以分为三个步骤:命令追加、文件写入、文件同步。
命令追加:当 AOF 持久化功能打开时,服务器在执行完一个写命令之后,会将被执行的写命令追加到服务器状态的 aof 缓冲区(aof_buf)的末尾。
文件写入与文件同步:可能有人不明白为什么将 aof_buf 的内容写到磁盘上需要两步操作,这边简单解释一下。
Linux 操作系统中为了提升性能,使用了页缓存(page cache)。当我们将 aof_buf 的内容写到磁盘上时,此时数据并没有真正的落盘,而是在 page cache 中,为了将 page cache 中的数据真正落盘,需要执行 fsync / fdatasync 命令来强制刷盘。这边的文件同步做的就是刷盘操作,或者叫文件刷盘可能更容易理解一些。
开启AOF模式
检查是否配置成功
6、AOF的优缺点
AOF 的优点
1)AOF 比 RDB可靠。你可以设置不同的 fsync 策略:no、everysec 和 always。默认是 everysec,在这种配置下,redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据。
2)AOF文件是一个纯追加的日志文件。即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机等等), 我们也可以使用 redis-check-aof 工具也可以轻易地修复这种问题。
3)当 AOF文件太大时,Redis 会自动在后台进行重写:重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。整个重写是绝对安全,因为重写是在一个新的文件上进行,同时 Redis 会继续往旧的文件追加数据。当新文件重写完毕,Redis 会把新旧文件进行切换,然后开始把数据写到新文件上。
4)AOF 文件有序地保存了对数据库执行的所有写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。如果你不小心执行了 FLUSHALL 命令把所有数据刷掉了,但只要 AOF 文件没有被重写,那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。
AOF 的缺点
1)对于相同的数据集,AOF 文件的大小一般会比 RDB 文件大。
2)根据所使用的 fsync 策略,AOF 的速度可能会比 RDB 慢。通常 fsync 设置为每秒一次就能获得比较高的性能,而关闭 fsync 可以让 AOF 的速度和 RDB 一样快。
3)AOF 在过去曾经发生过这样的 bug :因为个别命令的原因,导致 AOF 文件在重新载入时,无法将数据集恢复成保存时的原样。(举个例子,阻塞命令 BRPOPLPUSH 就曾经引起过这样的 bug ) 。虽然这种 bug 在 AOF 文件中并不常见, 但是相较而言, RDB 几乎是不可能出现这种 bug 的。
7、RDB与AOF对比
1、RDB存某个时刻的数据快照,采用二进制压缩存储,AOF存操作命令,采用文本存储(混合);
2、RDB性能高、AOF性能较低;
3、RDB在配置触发状态会丢失最后一次快照以后更改的所有数据,AOF设置为每秒保存一次,则最多丢2秒的数据;
4、Redis以主服务器模式运行,RDB不会保存过期键值对数据,Redis以从服务器模式运行,RDB会保存过期键值对,当主服务器向从服务器同步时,再清空过期键值对;
5、AOF写入文件时,对过期的key会追加一条del命令,当执行AOF重写时,会忽略过期key和del命令。
如果rdb和aof都使用,当服务器重启时会加载哪个文件?
先加载AOF的文件【它以数据完整性为主】
8、应用场景
内存数据库 rdb+aof 数据不容易丢
缓存服务器 rdb 性能高
不建议 只使用 aof (性能差)
在数据还原时
有rdb+aof 则还原aof,因为RDB会造成文件的丢失,AOF相对数据要完整。
只有rdb,则还原rdb