众所周知,Redis是一种基于内存的可持久化的数据库,因为它是基于内存,所以它的数据读写速度快,但是数据没有持久化,意味着下一次启动redis服务这些数据就不在了。那么就引出了两种Redis的可持久化数据的方式,RDB和AOF。
宏观来说,RDB和AOF最显然的区别是RDB是存储内容,而AOF是存储命令。RDB可以看成在特定时刻对内存数据进行的一次快照,触发快照需要达到的条件可以自己指定,比如save 5 1,意思就是在5秒内发生了至少一次更新操作,就会触发rdb,每次rdb会生成一个新的rdb文件,redis在启动服务时会加载这个rdb文件从硬盘中恢复数据。注意这个触发rdb的频率不能太高,比如设置1s一次rdb,上次rdb还没有完成就又来了一次,显然是不合适的。
从上面来看,rdb不失为一种数据持久化的合理方式,那么它有什么缺陷呢? 我们知道磁盘的IO速度是比较慢的,所以每一次rdb其实需要消耗不小的系统资源,需要等待的时间也比较长,那么如果在某次rdb过程中服务器发生了宕机,而你设置的rdb频率为5min一次,那么你就会丢失上次rdb之后的5min的数据,即数据安全性的问题。
其次,在实际的数据持久化的过程中,不是主进程在进行操作,而是由父进程fork()出的一个子进程在操作,当数据量非常大时,fork()会很耗时。
那么AOF又比RDB好到哪里呢?我们知道,AOF是对命令进行存储,当redis启动时会加载aof文件,把文件里的命令从头到尾执行一遍,那么也就实现了数据的恢复。AOF的频率一般来说比RDB高,默认是一秒一次,就算在这一秒之内发生了宕机,那也只是丢失一秒钟的数据,比RDB的数据安全性要高得多,这是AOF的优点。相对的,AOF的安全性高必然导致其性能较低,当redis启动时要加载所有命令,比较耗时。其次,由于aof存储的是命令,只要是命令,都会存储,那么如果我写了1000条重复的无意义的命令,那么文件大小就会无意义的增大。对此也有解决方式,redis提供了对命令的压缩方案,我们可以手动开启。