Redis底层原理&面试知识 (一)AOF & RDB
AOF 和 RDB --- 两种持久化方式
AOF是运用log shipping,只记录了每一条操作,并且支持“重写策略”,用来压缩当前的log。比如多个incr,可以压缩成一条
将Redis操作指令追加到以.aof结尾的文件中,默认是每秒(everysec)记录一次,
当aof文件超过大小时,系统会fork一个进程来对aof文件进行重写操作,即:auto-aof-rewrite。
相关参数配置:
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
优点:
1)记录内容完整,在数据恢复时丢失数据会比RDB少;
缺点:
1)操作记录较多,文件内容很大;
2)恢复速度比RDB慢;
3)由于记录频繁,相当耗性能;
RDB是运用snapshot,保存当前redis中的所有数据
由系统fork出一个进程来执行
默认是根据自定义的时间间隔内发生的变化,来触发是否需要生成快照文件进行保存,
当然也可以使用命令来强制立刻保存,如:save...等命令
相关参数配置:
save 900 1
save 300 10
save 60 10000
优点:
1)恢复速度快,容易备份;
缺点:
1)由于是根据间隔生成快照,出现故障时会丢失间隔内数据;
2)如果数据过大,每次系统fork进程进行快照生成,相当消耗性能,有可能会导致终止客户端请求。
RDB备份时分为save or bgsave (即background save),从C底层来说,就是父进程是否调用waitpid函数
save是同步的,会将redis阻塞,大数据想要RDB save会占用很多的时间,阻塞主进程
通常使用bgsave,主进程会进行fork,然后子进程在后台进行备份
、
AOF重写策略
由于redis已经在buf中了,正如前文提到的,AOF可以设置alwasy,everysecond等,因此会有两个buf(3.1 & 3.2)来保证log不会直接写在AOF文件里(减少IO)。当新的AOF生成后,将替代旧的AOF
两者各有千秋,
crash丢失的数据不同:RDB会丢弃上一次checkpoint到现在的所有数据 | AOF根据策略,如everysecond会丢失1s的
可调的自由程度不同:可以控制RDB写入的条件 | AOF可以控制 always、everysecond、no等写入方式
载入的速度不同:RDB很快,直接替代snapshot即可 | AOF略慢,需要rollback
优先级不同:无特殊配置,AOF会先于RDB执行
AOF,或者说是log shipping,也用于RPC的分布式存储,例如mit6.824的aurora,备份的时候在不同的AZ之间采用log shipping的方式,大大提升了效率。