redis持久化介绍
将存储在内存中的数据,从内存中同步到硬盘上,这个过程叫做持久化过程。
redis的两种持久化操作,rdb方式,和aof方式,两者可以单独使用也可以结合使用。
RDB:
在指定时间间内将内存中的数据集快照隔写入硬盘,实际操作是fork一个子进程,先将数据集写入临时文件,写入成功后,在替换之前的文件,用二进制压缩存储。
将Redis内存中的数据,完整的生成一个快照,以二进制格式文件(后缀RDB)保存在硬盘当中。当需要进行恢复时,再从硬盘加载到内存中。
Redis主从复制,用的也是基于RDB方式,做一个复制文件的传输。
AOF:
将以日志,记录每一个操作,服务器启动后就构建数据库,以文本的方式记录,打开可以看到详细的操作记录。
RDB 的三种触发方式
save命令触发(同步):save执行是,会造成redis的阻塞,所有数据作命令都要排队等待他完成。新生成一个新的临时文件,当save执行完之后,用新的替换老的。
bgsave命令触发方式(异步):客户端对Redis服务器下达bgsave命令时,Redis会fork出一个子进程进行RDB文件的生成。当RDB生成完毕后,子进程再反馈给主进程。fork子进程时也会阻塞,不过正常情况下fork过程都非常快的。新生成一个新的临时文件,当save执行完之后,用新的替换老的。
规则自动触发方式:
某些条件达到时,自动生成RDB文件。
比如我们配置如下:
配置 | seconds | changes | 说明 |
---|---|---|---|
save | 900 | 1 | 900秒内改变1条数据,自动生成RDB文件 |
save | 300 | 10 | 300秒内改变10条数据,自动生成RDB文件 |
save | 60 | 10000 | 60秒内改变1万条数据,自动生成RDB文件 |
以上任一条件达到时,都会触发生成RDB文件。不过这种方式对RDB文件的生成频率不太好控制。如果写量大,RDB生成会很频繁。不是一种好的方式。
不容忽略的触发方式
1.全量复制
主从复制是,主会自动生成RDB文件
2.debug reload
Redis中的debug reload提供debug级别的重启,不清空内存的一种重启,这种方式也会触发RDB文件的生成。
3.shutdown
会触发RDB文件的生成。
RDB总结
- RDB是Redis内存到硬盘的快照,用于持久化;
- save通常会阻塞redis;
- bgsave通常不会阻塞redis,但是会fork新进程;
- save自动配置满足任一就会被执行;
- 有些触发机制不容忽视。
RDB存在的问题
1.耗时,耗内存,耗io性能
将内存中的数据全部存到硬盘中,耗时,bgsave的fork()紫禁城耗内存,大量硬盘读写耗费io性能
2.不可控,丢失数据
宕机时,上次快照之后写入的内存数据将会丢失
AOF三种策略
首先Redis执行写命令,将命令刷新到硬盘缓冲区当中。
always
always策略让缓冲区中的数据即时刷新到硬盘。
everysec
everysec策略让缓冲区中的数据每秒刷新到硬盘。相比always,在高写入量的情况下,可以保护硬盘。出现故障可能会丢失一秒数据。
no
刷新策略让操作系统来决定。
通常使用everysec策略,这个也是aof的默认策略。
AOF重写
随着时间的推移,命令的逐步写入。AOF文件也会逐渐变大。当我们用AOF来恢复时会很慢,而且当文件无限增大时,对硬盘的管理,对写入的速度也会有产生影响。Redis当然考虑到这个问题,所以就有了AOF重写。
AOF重写就是把过期的、没用的、重复的以及可优化的命令,进行化简。只取最终有价值的结果。虽然写入操作很频繁,但系统定义的key的量是相对有限的。
AOF重写可以大大压缩最终日志文件的大小。从而减少磁盘占用量,加快数据恢复速度。比如我们有个计数的服务,有很多自增的操作,比如有一个key自增到1个亿,对AOF文件来说就是一亿次incr。AOF重写就只用记1条记录。
参考文章:
https://segmentfault.com/a/1190000012316003#articleHeader10
https://www.cnblogs.com/chenliangcl/p/7240350.html