Redis持久化剖析
Redis持久化意义
我们在互联网场景应用里,缓存服务是必不可少了,提高读写性能,对DB流量保护等。那么,常见的缓存服务就有redis、memcache等。那么,其中,redis最大的一个特点,就是支持持久化。支持持久化的意义在于什么呢?举一个例子,当我们的缓存服务宕机了,再重启的时候,如果没有持久化机制,那么重启后内存中就丢失了宕机前的所有数据,没有了缓存命中,接下来所有的请求都会打到DB上,发生雪崩,你会发现应用刚启动又报错了。有了持久化这种容灾机制,我们就不必担心,大面积丢失命中问题。
持久化实现
redis的持久是怎么实现的呢,首先redis支持两种持久化方式:rdb(数据全量的快照),aof(append only 操作指令)。
rdb
先说说rdb的流程原理。在redis.conf里默认有rdb触发的定时规则,如图
默认的触发规则为,60s内有1W条数据change,300s(5min)内有10条数据change,900s(15min)内有1条数据change。都会触发redis执行fork函数复制出一个子进程,来进行快照操作生成当前时刻内存中全量数据的rdb文件。rdb是一个数据的压缩文件。当启动redis时,redis又可以根据rdb文件把数据初始化到内存中。由于,rdb的定时触发规则,我们可以备份不同版本的数据。
当然,这个定时触发规则,我们也可以根据自己的实际应用场景做调配。但要注意:1,触发太频繁会加重磁盘io操作。2,如果间隔太长,有可能会导致较多数据丢失,另外,如果cpu处理能力不够强大,加上数据集较大fork的子进程执行io时间较长,会影响客户端服务,出现卡顿(这是一个坑)。
aof
aof的原理是,会把对redis的指令操作记录到aof文件中。流程是当对redis有新增数据指令时,首先redis会把指令append到Linux的os cache中,再由fsync策略觉定持久化到磁盘上(默认为每秒)。
另外,fsync策略有3种可配:1,always(来一条,持久化一条),2,everysec(每秒把os cache数据sync到磁盘上),3,no(只在os cache中,持久化靠操作系统自身策略)。
always,数据持久化有保证,数据不丢失,但吞吐性能大降。
everysec,因为是每秒,所以会丢失前一秒数据,但性能良好。
no,虽然性能最优,但依靠操作系统持久机制,不可控,不稳定。
由于,aof这种方式是把指令都append到一个文件中,文件打到一定,会触发rewrite机制。
触发rewirte
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
rewirte,首先,redis会触发垃圾回收机制。比如LRU算法,清除后的数据会重写成一个新的aof文件,那么在rewirte过程中有新增的数据会先持久化到就aof文件上,当新aof同步完,再把rewirte过程中新增的数据指令再同步给新的aof。
扩展
我们可以根据,redis的持久化机制,做一些备份策略。比如,弄一台远程的云服务做冷备服务器,按照RDB的各个版本按时间备份,以便错误数据故障恢复等。也可以,自己写较复杂shell把aof的文件按照rewirte节点前copy走备份。这里有一个深坑,要注意一下,当aof和rdb同时存在时,那redis默认按照aof文件去初始化内存数据,再去覆盖掉rdb文件,作者本人就掉过坑。所以,应该怎么处理,你懂的!