1、什么是持久化
持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中、XML数据文件中等等。
2、Redis为什么要持久化?
Redis优秀的性能是由于其将所有的数据都存储在内存中,虽然memcached也是这样做的,但是为什么Redis能够脱颖而出呢,很大程度上是因为Redis有出色的持久化机制。
持久化能够保证服务器因故障崩溃或重启后,数据不会丢失,因为在下次重启时可以利用之前持久化文件实现数据恢复。
3、Redis持久化方式
Redis支持RDB和AOF两种持久化机制。
3.1 RDB介绍
在 Redis 运行时, RDB 程序将当前内存中的数据库快照保存到磁盘文件中, 在 Redis 重启动时, RDB 程序可以通过载入 RDB 文件来还原数据库的状态,触发RDB持久化过程分为手动触发和自动触发。
RDB 持久化主要由 rdbSave 和 rdbLoad 两个函数来实现。其中,前者用于生成 RDB 文件到磁盘, 后者则将 RDB 文件中的数据重新载入到内存中。
![](https://img.haomeiwen.com/i15961406/b49a380bbe2e7cc2.png)
rdbSave 函数负责将内存中的数据库数据以 RDB 格式保存到磁盘中, 如果 RDB 文件已存在, 那么新的 RDB 文件将替换已有的 RDB 文件。当 Redis 服务器启动时, rdbLoad 函数就会被执行, 它读取 RDB 文件, 并将文件中的数据库数据载入到内存中。在载入期间, 服务器每载入 1000 个键就处理一次所有已到达的请求, 不过只有 PUBLISH 、 SUBSCRIBE 、 PSUBSCRIBE 、 UNSUBSCRIBE 、 PUNSUBSCRIBE 五个命令的请求会被正确地处理, 其他命令一律返回错误。 等到载入完成之后, 服务器才会开始正常处理所有命令。
3.1.1 触发机制
1) save
SAVE 直接调用 rdbSave ,阻塞 Redis 主进程,直到保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任何请求。当 SAVE 正在执行时, 新的 SAVE 、 BGSAVE 或 BGREWRITEAOF 调用都不会产生任何作用。只有在上一个 SAVE 执行完毕、 Redis 重新开始接受请求之后, 新的 SAVE 、 BGSAVE 或 BGREWRITEAOF 命令才会被处理。 因为 AOF 写入由后台线程完成, 而 BGREWRITEAOF 则由子进程完成, 所以在 SAVE 执行的过程中, AOF 写入和 BGREWRITEAOF 可以同时进行。
2)bgsave
BGSAVE fork 出一个子进程,子进程负责调用 rdbSave ,并在保存完成之后向主进程发送信号,通知保存已完成。因为 rdbSave在子进程被调用,所以 Redis 服务器在 BGSAVE 执行期间仍然可以继续处理客户端的请求。这样做可以避免 SAVE 和 BGSAVE 调用的两个 rdbSave 交叉执行, 造成竞争条件。
3)BGREWRITEAOF 和 BGSAVE 不能同时执行:
如果 BGSAVE 正在执行,那么 BGREWRITEAOF 的重写请求会被延迟到 BGSAVE 执行完毕之后进行,执行 BGREWRITEAOF 命令的客户端会收到请求被延迟的回复。如果 BGREWRITEAOF 正在执行,那么调用 BGSAVE 的客户端将收到出错信息,表示这两个命令不能同时执行。
![](https://img.haomeiwen.com/i15961406/3234a0733f7cd1cf.png)
4)bgSave执行流程
a. 执行bgsave命令,Redis父进程判断当前是否存在正在执行的子进程,如只RDB/AOF子进程,如果存在bgsave命令直接返回。
b. 父进程执行fork操作创建子进程,fork操作过程中父进程会阻塞,通过info stats命令查看latest_fork_usec选项,可以获取最近一个fork以操作的耗时,单位为微秒。
c. 父进程fork完成后,bgsave命令返回“Background saving started”信息并不再阻塞父进程,父进程可以继续响应其他命令。
d. 子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。执行lastsave命令可以获取最后一次生成尺RDB的时间,对应info统计的rdb_last_save_time选项。
e. 进程发送信号给父进程衣示完成,父进程更新统计信息,具体见info Persistence下的rdb_*相关选项。
5)save和bgSave优缺点分析
Save的优点在于节约系统资源,不需要fork子进程。缺点是其在执行时会阻塞redis进程,阻塞期间,服务器无法响应其他的处理,直到执行完成为止。如果数据量小,用此命令可能感觉不出有什么区别,但是当数据量很大的时候,就需要谨慎使用这个命令了,可能会导致数据丢失。
bgSave的优点是执行此命令的时候,redis会fork出一个子进程去完成备份持久化,而不会影响redis处理其他的请求。但由于会fork一个进程,因此更消耗内存。
3.1.2 RDB配置文件
1) 设置触发条件
在redis.conf文件中进行设置,下面的触发条件之间是或的关系。即只要一个满足,就进行备份。
![](https://img.haomeiwen.com/i15961406/3131a8c4e1171b0e.png)
2) 设置rdb文件保存路径
![](https://img.haomeiwen.com/i15961406/1141e0f49cce2efc.png)
3)设置文件是否压缩
![](https://img.haomeiwen.com/i15961406/4d7ca6acdd2e317a.png)
压缩的有点缺分析
压缩。优点:减少磁盘存储空间;缺点:消耗CPU资源
不压缩。优点:不消耗CPU资源;缺点:占用磁盘空间
网友评论