前言
上一篇文章介绍了redis的过期策略,介绍完策略后,我们也提到了redis的持久化是如何处理过期键的,本文我们会关注redis的持久化技术。
在介绍redis持久化技术前,我们先来思考一个问题,redis为何要实现持久化?我们知道redis大部分是用作缓存的技术的,但是其实redis其实还有很多是作为数据库功能的,比如电商里的最近一周浏览列表的展示,对于这些数据我觉得确实没有存在mysql数据的必要的,那么选择redis来存储这样的数据很合适,那么问题来了如果redis做数据库用途,数据丢失了是不是很尴尬?我们都知道数据放在内存里是很不安全的,服务器一旦宕机数据就不复存在了,所以数据存储在磁盘里才是最安全的,因此,redis实现了持久化功能。
RDB持久化
RDB持久化的实现是将数据库里的键值对以二进制的形式保存在RDB文件里,但是何时将数据写入RDB文件是可以配置的,默认配置如下
save 900 1
save 300 10
save 60 10000
配置含义:
- 服务器在900秒内,对数据库进行了至少一次的修改
- 服务器在300秒内,对数据库进行了至少10次的修改
- 服务器在60秒内,对数据库进行了至少10000次修改
以上三个条件是并列的,只要满足任意一个条件都会进行RDB持久化,可以看出数据库变更越频繁RDB的持久化也越频繁,这是为了尽可能的减少数据丢失的风险。
RDB持久化命令
redis提供了两个RDB持久化命令,SAVE和BGSAVE。SAVE命令是由主进程去生成RDB文件的,会阻塞redis,拒绝客户端的请求,这个命令是不友好的,BESAVE是异步去生成RDB文件的,原理是有主进程fork一个进程去生成RDB文件。
save命令:
可以看到是返回了ok,说明是立即同步执行生成RDB文件的。
bgsave命令
可以看到是后台异步生成RDB文件的。
bgsave流程图
小结
到此RDB持久化已经基本介绍完了,文件的载入RDB和AOF没有什么差异,等写完AOF持久化一并画个图总结下,redis默认的持久化技术也是RDB,这里我抛出个问题,RDB持久化数据丢失的风险是多少?
AOF持久化
与RDB保存键值对方式不同,AOF保存的是客户端的写命令,可以理解为AOF保存的是操作日志,每当一个客户端发送一个写命令时,数据库保存完数据后就会向AOF文件写入一个操作日志,如果你仔细思考会不会发现AOF持久化拉长了redis处理客户端写请求的生命周期,是的!!!
针对上述问题,redis团队设计了一个aof_buf,即AOF缓存区,也就是说redis在收到一个写请求时不会立马将写命令写入aof文件中,而是先写到aof缓存区,然后再从缓存区同步到aof文件里,那么何时同步到aof文件是今天的一个重点,redis提供了三种同步aof文件的策略:
- always,每次写入命令都会写入aof文件中,这种策略的实现效率是最低的,但是数据的安全性是最高的,最差只能丢一条数据,如果对数据安全要求高的系统推荐使用。
- everysec,每隔一秒同步一次aof文件,个人觉得这个策略其实也不错,兼顾性能与数据安全,最坏情况丢失一秒钟的数据,我觉得大部分系统也是可以接收的。
- no,redis不限制什么时间同步aof文件,由操作系统自行决定,这种写入效率是最高的,但丢失数据的风险是最近一次同步aof文件后所有的写入命令。
现在我们可以来回答RDB持久化数据的丢失风险了,其实RDB的丢失数据风险是和AOF的同步策略为no时差不多的,其实选择哪种持久化以及哪种AOF持久化策略是根据不同系统实际情况来决定的,这里所说的丢失数据的额风险是redis宕机后重启所丢失的数据,对于中小型服务来说,redis根本没有宕机的风险,也就不存在数据丢失的风险,所以如何选择还是根据业务需要吧。
redis重启流程
AOF重写
由于aof持久化是保存操作命令的方式,所以随着系统运行时间的流逝,aof文件肯定会越来越大,如果不加以控制,肯定会影响redis的性能,甚至会影响整个宿主计算机的性能,所以aof文件瘦身也是重要的课题。
思考一个问题,随着时间的流逝,是不是会有操作命令没有意义了?
比如上图的操作,set gf lyf、set gf zta 对于持久化是没有意义的,所以随着时间的流逝对aof文件瘦身是有意义的,而对于这个操作redis团队设计了aof重写这个逻辑。
aof重写与旧的aof文件没有关系,aof重写的实现是将当前数据库里的所有有效key的写命令重新生成一个新的aof文件,然后用新的文件替换旧的文件,在生成文件期间的写命令将会被缓存在aof重写缓存池里,等到新文件生成完成后,追加进去即可。
总结
本文梳理了redis的两种持久化技术,介绍了其实现,也分析了性能和数据安全的问题,也简单讨论了该如何选择redis的持久化。主要内容再帮大家回顾下:
- RDB持久化
- RDB持久化的两种命令
- AOF持久化
- AOF持久化的aof文件同步策略
- AOF重写