为什么要持久化
Redis是内存数据库,宕机后数据会消失,Redis重启后快速恢复数据,要提供持久化机制。
把内存中的数据持久化到磁盘中,防止数据丢失。
—当redis服务器开启时,会把磁盘中的数据加载到内存中进行计算。
Redis的两种持久化方式:RDB和AOF🍓
Redis持久化不保证数据的完整性,有可能会丢数据。当Redis用作DB时,DB数据要完整,所以一定要有一个完整的数据源(文件、mysql),在系统启动时,从这个完整的数据源中将数据load到Redis中。
1.RDB方式🍓
RDB(Redis DataBase),是redis默认的存储方式,RDB方式是通过快照( snapshotting )完成的。它保存的是某一时刻的数据并不关注过程。
RDB保存redis某一时刻的数据的快照
触发快照的方式
- 符合自定义配置的快照规则;(自动触发)
- 执行save或者bgsave命令;(手动输入命令触发)
- 执行flushall命令;
- 执行主从复制操作 (第一次)。
save触发🥝
该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。具体流程如下:
执行完成时候如果存在老的RDB文件,就把新的替代掉旧的。我们的客户端可能都是几万或者是几十万,这种方式显然不可取。
bgsave触发🥝
执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。具体流程如下:
bgsave在执行该命令时会fork出一个新的线程,单独执行rdb持久化操作,而不影响其他客户对redis服务的操作。
手动配置🥝
不管使用save还是bgsave都需要手动输入。我们也可以通过配置文件完成自动化rdb操作。
//配置好配置文件后要重新启动redis
//删除之前的 dump.rdb文件试一下是否配置成功
rm -rf dump.rdb
-
Redis父进程首先判断:当前是否在执行save,或bgsave/bgrewriteaof(aof文件重写命令)的子进程,如果在执行则bgsave命令直接返回;
-
父进程执行fork(调用OS函数复制主进程)操作创建子进程,这个过程中父进程是阻塞的,Redis不能执行来自客户端的任何命令;
-
父进程fork后,bgsave命令返回”Background saving started”信息并不再阻塞父进程,并可以响应其他命令;
-
子进程创建RDB文件,根据父进程内存快照生成临时快照文件,完成后对原有文件进行原子替换(RDB始终完整);
-
子进程发送信号给父进程表示完成,父进程更新统计信息。
-
父进程fork子进程后,继续工作。
RDB的优缺点🥝
优点
1.RDB是二进制压缩文件,占用空间小,便于传输(传给slaver);
2.主进程fork子进程,可以最大化Redis性能;
3.使用RDB文件来恢复数据较快。
缺点
1、不保证数据完整性,会丢失最后一次快照以后更改的所有数据;
2、父进程在fork子进程的时候如果主进程比较大会阻塞;
RDB快照持久化优缺点:
优点: ----数据恢复速度快。
缺点: ----数据完整性差–会丢失最后一段时间的数据。
2.AOF持久化🍓
日志追加持久化,当我们执行写操作,会触发一个函数write,把会把写操作的命令追加到一个日志文件appendfile中。当服务器启动时会把appendfile中的命令从新执行一遍。默认不开启。
AOF(append only file)是Redis的另一种持久化方式。Redis默认情况下是不开启的。开启AOF持久化后Redis 将所有对数据库进行过写入的命令(及其参数)(RESP)记录到 AOF 文件, 以此达到记录数据库状态的目的,这样当Redis重启后只要按顺序回放这些命令就会恢复到原始状态了。AOF会记录过程,RDB只管结果
AOF原理🥝
AOF文件中存储的是redis的命令,同步命令到 AOF 文件的整个过程可以分为三个阶段:
-
命令传播:Redis 将执行完的命令、命令的参数、命令的参数个数等信息发送到 AOF 程序中;
当一个 Redis 客户端需要执行命令时, 它通过网络连接, 将协议文本发送给 Redis 服务器。服务器在接到客户端的请求之后, 它会根据协议文本的内容, 选择适当的命令函数, 并将各个参数从字符串文本转换为 Redis 字符串对象( StringObject )。每当命令函数成功执行之后, 命令参数都会被传播到AOF 程序。 -
缓存追加:AOF 程序根据接收到的命令数据,将命令转换为网络通讯协议的格式,然后将协议内容追加到服务器的 AOF 缓存中。
当命令被传播到 AOF 程序之后, 程序会根据命令以及命令的参数, 将命令从字符串对象转换回原来的协议文本。协议文本生成之后, 它会被追加到 redis.h/redisServer 结构的 aof_buf 末尾。
redisServer 结构维持着 Redis 服务器的状态, aof_buf 域则保存着所有等待写入到 AOF 文件的协议文本(RESP)。 -
文件写入和保存:AOF 缓存中的内容被写入到 AOF 文件末尾,如果设定的 AOF 保存条件被满足的话,fsync 函数或者 fdatasync 函数会被调用,将写入的内容真正地保存到磁盘中。
每当服务器常规任务函数被执行、 或者事件处理器被执行时,aof.c/flushAppendOnlyFile 函数都会被调用, 这个函数执行以下两个工作:
WRITE:根据条件,将 aof_buf 中的缓存写入到 AOF 文件。
SAVE:根据条件,调用 fsync 或 fdatasync 函数,将 AOF 文件保存到磁盘中。因为 SAVE 是由 Redis 主进程执行的,所以在 SAVE 执行期间,主进程会被阻塞,不能接受命令请求。
AOF 保存模式:
AOF_FSYNC_NO :不保存。
在这种模式下, 每次调用 flushAppendOnlyFile 函数, WRITE 都会被执行, 但 SAVE 会被略过。当出现Redis 被关闭、AOF 功能被关闭 、 系统的写缓存被刷新(可能是缓存已经被写满,或者定期保存操作被执行)中任意一种情况都会触发save执行,并且会Redis 主进程阻塞。
AOF_FSYNC_EVERYSEC :每一秒钟保存一次。(默认)
在这种模式中, SAVE 原则上每隔一秒钟就会执行一次, 因为 SAVE 操作是由后台子线程(fork)调用的, 所以它不会引起服务器主进程阻塞。
AOF_FSYNC_ALWAYS :每执行一个命令保存一次。(不推荐)
在这种模式下,每次执行完一个命令之后, WRITE 和 SAVE 都会被执行。
手动开启aof模式🥝
1.更改配置文件
2.测试配置是否成功
//刷新配置文件
redis-server redis.conf
//启动redis
redis-cli
//结束redis进程
shutdown
//退出redis
exit
AOF优缺点🥝
-
优点: 数据完整性高—丢失最后一条指令。
-
缺点: 数据恢复慢。
3.混合持久化🍓
RDB和AOF各有优缺点,Redis 4.0 开始支持 rdb 和 aof 的混合持久化。如果把混合持久化打开,aofrewrite 的时候就直接把 rdb 的内容写到 aof 文件开头。在加载时,首先会识别AOF文件是否以REDIS字符串开头,如果是就按RDB格式加载,加载完RDB后继续按AOF格式加载剩余部分(一个文件中既有rdb的数据也有aof的日志)。
开启混合持久化:aof-use-rdb-preamble yes
先加载AOF的文件【它以数据完整性为主】。
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 数据不容易丢
缓存服务器 rdb 性能高
不建议 只使用 aof (性能差)
在数据还原时
有rdb+aof 则还原aof,因为RDB会造成文件的丢失,AOF相对数据要完整。
只有rdb,则还原rdb