redis的持久化方式以及策略选择

321 阅读6分钟

目前Redis持久化的方式有两种: RDB 和 AOF

1.为什么要持久化

首先,我们应该明确持久化的数据有什么用,答案是用于重启后的数据恢复。
Redis是一个内存数据库,无论是RDB还是AOF,都只是其保证数据恢复的措施。
所以Redis在利用RDB和AOF进行恢复的时候,都会读取RDB或AOF文件,重新加载到内存中。

2.RDB持久化

RDB就是Snapshot快照存储,是默认的持久化方式。
可理解为半持久化模式,即按照一定的策略周期性的将数据保存到磁盘。
对应产生的数据文件为dump.rdb,通过配置文件中的save参数来定义快照的周期

Redis的RDB文件不会坏掉,因为其写操作是在一个新进程中进行的。
当生成一个新的RDB文件时,Redis生成的子进程会先将数据写到一个临时文件中,然后通过原子性rename系统调用将临时文件重命名为RDB文件。
这样在任何时候出现故障,Redis的RDB文件都总是可用的。

2.1 redis主从同步

Redis的RDB文件也是Redis主从同步内部实现中的一环。
第一次Slave向Master同步的实现是:
Slave向Master发出同步请求,Master先dump出rdb文件,然后将rdb文件全量传输给slave,然后Master把缓存的命令转发给Slave,初次同步完成。
第二次以及以后的同步实现是:
Master将变量的快照直接实时依次发送给各个Slave

Redis的主从复制是建立在内存快照的持久化基础上的,只要有Slave就一定会有内存快照发生。

2.2阻塞与非阻塞方式以及具体实现

➢ SAVE :阻塞Redis的服务器进程,直到RDB文件被创建完毕
➢ BGSAVE : Fork出一个子进程来创建RDB文件,不阻塞服务器进程

save 900 1    #当有一条Keys数据被改变时,900秒刷新到Disk一次 BGSAVE
save 300 10   #当有10条Keys数据被改变时,300秒刷新到Disk一次 BGSAVE
save 60 10000 #当有10000条Keys数据被改变时,60秒刷新到Disk一次 BGSAVE

可以很明显的看到,RDB有它的不足,就是一旦数据库出现问题,那么我们的RDB文件中保存的数据并不是全新的。
从上次RDB文件生成到Redis停机这段时间的数据全部丢掉了。

3.AOF持久化

AOF(Append-Only File)比RDB方式有更好的持久化性。
由于在使用AOF持久化方式时,Redis会将每一个收到的写命令都通过Write函数追加到文件中,类似于MySQL的binlog。
当Redis重启是会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。

3.1 AOF实现方式
redis.conf

appendonly yes #启用AOF持久化方式

appendfilename appendonly.aof #AOF文件的名称,默认为appendonly.aof

# appendfsync always #每次收到写命令就立即强制写入磁盘,是最有保证的完全的持久化,但速度也是最慢的,一般不推荐使用。

appendfsync everysec #每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,是受推荐的方式。

# appendfsync no #完全依赖OS的写入,一般为30秒左右一次,性能最好但是持久化最没有保证,不被推荐。

3.3 AOF的弊端

AOF的完全持久化方式同时也带来了另一个问题,持久化文件会变得越来越大。
比如我们调用INCR test命令100次,文件中就必须保存全部的100条命令,但其实99条都是多余的。
因为要恢复数据库的状态其实文件中保存一条SET test 100就够了。
为了压缩AOF的持久化文件,Redis提供了bgrewriteaof命令

3.4操作方式

a.手动触发命令bgrewriteaof

b.redis.conf

no-appendfsync-on-rewrite yes   #在日志重写时,不进行命令追加操作,而只是将其放在缓冲区里,避免与命令的追加造成DISK
IO上的冲突。

auto-aof-rewrite-percentage 100 #当前AOF文件大小是上次日志重写得到AOF文件大小的二倍时,自动启动新的日志重写过程。

auto-aof-rewrite-min-size 64mb  #当前AOF文件启动新的日志重写过程的最小值,避免刚刚启动Reids时由于文件尺寸较小导致频繁的重写

4.redis线上策略选择:

4.1.兼顾性能和安全性

4.2.持久化的选择必须与Redis的主从策略一起考虑,因为主从复制与持久化同样具有数据备份的功能,而且主机master和从机slave可以独立的选择持久化方案

4.3.但在多数情况下,我们都会配置主从环境,slave的存在既可以实现数据的热备,也可以进行读写分离分担Redis读请求,以及在master宕掉后继续提供服务。在这种情况下,一种可行的做法是:master:完全关闭持久化,这样可以让master的性能达到最好slave:关闭快照持久化,开启AOF和RDB(如果对数据安全要求不高,开启快照持久化关闭AOF也可以),并定时对持久化文件进行备份(如备份到其他文件夹,并标记好备份的时间);然后关闭AOF的自动重写,然后添加定时任务,在每天Redis闲时(如凌晨12点)调用bgrewriteaof。

4.4.AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。默认超过原大小100%大小时重写可以改到适当的大小

4.5当Redis服务器挂掉时,重启时将按照以下优先级恢复数据到内存:
   a.如果只配置AOF,重启时加载AOF文件恢复数据;
   b. 如果同时 配置了RDB和AOF,启动是只加载AOF文件恢复数据;
   c. 如果只配置RDB,启动是将加载dump文件恢复数据

所以同时RDB是备选,防止AOF文件损坏且无法修复。