redis有两种持久化的方式 RDB和AOF,今天我们来对比下两种方式的优缺点并详细介绍下在生产环境如何配合使用持久化。
先来简单说说RDB和AOF持久化的基本原理
RDB持久化机制: 是对redis中的数据周期性的写入磁盘。每次持久化的时候redis都会fork一个子进程来完成持久化快照的生成。
这个周期性可以通过配置文件来配置 下面列举了三个周期策略。
#每60s内有1w条数据写入内存则触发持久化
save 60 10000
#每300s内有100条数据写入内存则触发持久化
save 300 100
#每900s内有1条数据写入内存则触发持久化
save 900 1
AOF持久化机制: 是把每条写入命令作为日志,以append-only的模式写入一个日志文件,此时其实还未真正写入到磁盘,数据存在操作系统的os cache中 ,再通过fsync将写入os cache的数据刷到磁盘,完成持久化操作。
在reids重启的时候可以通过回放aof中的写指令重新构建整个数据集。
如果同时开启RDB和AOF,那么在持久化的时候会使用aof来构建数据。因为aof中的数据更全。
AOF的开启方式:
#标识开启aof持久化
appendonly no
#appendfsync always 表示每发送一条写指令就进行一次fsync刷到磁盘,不建议这样配置,因为这样redis的吞吐量会变得超级低
appendfsync everysec // 表示每秒fsyncy一次,生产环境几乎都如此配置
# appendfsync no //表示不开启fsync,依赖操作系统的持久化定时操作,此时数据的持久化就变得不可控
#表示aof文件大小操作上一次的百分之100则可能会进行rewrite操作
auto-aof-rewrite-percentage 100
#比较完上面的参数还需要比较是不是大于64M 如果此条件也满足才会进行rewrite操作
auto-aof-rewrite-min-size 64mb
下面我们来说说RDB和AOF的优缺点:
RDB优点:
- RDB会生成多个数据文件,每个文件代表某个时刻redis内存数据的完整快照,非常适合做冷备。比如每天备份redis快照文件上传到阿里云ODPS分布式存储上去。
- 通过bgsave持久化,通过fork子进程和copyonwrite技术在实现持久化的同时对读写服务的影响特别小,保持redis高性能。
- 相对于AOF来说基于RDB数据文件来重启和恢复redis更加快速。
RDB缺点:
- 如果想要在redis故障时尽可能少丢数据则AOF会比RDB更好。AOF会每个1s执行一次写命令的fsnyc,而RDB基于定期扫描通常是5分钟扫描一次。
- 如果RDB在fork子线程生成快照文件的时候,再数据文件特别大的情况下redis对客户端的服务可能会暂停数毫秒,甚至数秒。
AOF优点:
- AOF通常每个1s通过后台线程执行一次fsnyc操作,最多丢1s的数据。
- AOF通过append-only模式写入没有任何的磁盘寻址开销,写性能高,文件不易破损,即使文件尾破损,也易于修复。
- AOF文件过大的时候,fork子进程重写,不会影响客户端的读写性能。因为在rewrite log的时候会对文件进行压缩,创建一份需要恢复数据的最小日志出来,在创建新文件的时候,老日志文件还在照常写入。当新文件ready之后直接替换老文件即可。
- AOF的日志文件是非常可读的,这个特性特别适合做灾难性的误操作。比如某天某人使用flushall命名清空了所有数据。我们只需要在rewrite之前去除AOF文件,删除最后一条flushall即可。
AOF缺点:
- 一般来说AOF日志文件会比RBD文件更大 。
- AOF开启之后,QPS会比RDB支持的QPS低。因为fsync一般一秒执行一次。但是这个性能还是很高。单机几万不是问题
生产环境应该如何选择?
- 通常生产环境RDB和AOF都是开启的。
- 我们可以利用RDB适合做冷备的特性来定时生成备份文件上传到可靠的文件存储系统中去。方式AOF可能会出现的恢复机制的bug。
- 使用AOF尽量少丢数据。在发生服务不可用的情况下尽快重启服务,恢复数据。