Redis RDB ( Redis DataBase )持久化方案会在指定的时间点将内存的数据集快照存入磁盘。当 RDB 开始工作时, Redis 服务会将自己分叉( fork )出一个持久化进程,此时原服务进程的一切内存数据都相当于被保存了一份快照,然后持久化进程将它的内存进行压缩并写入磁盘。需要注意的是,如果这段时间并没有新的缓存 Set 操作,那么持久化的效率还是相当不错的,因为持久化进程并不需要从原服务进程复制内存,它们共享同一批虚拟内存页。但是如果在持久化过程中,原服务进程收到了缓存 Set 操作,那就意味着原服务进程中部分内存需要修改,此时操作系统内核会对涉及到的虚拟内存页进行一个写时复制 (copy onwrite)的操作,确保持久化进程地址空间中的数据不变而服务进程中的数据则被更新。
Redis 的AOF 方案则是将服务端接收到的所有写操作(包括 Set 和 Del)记入磁盘上的日志文件,该日志文件的格式和 Redis 协议保持一致,且只允许添加(append only format)。当服务重启时,Redis 会重放日志文件的内容来重新构建整个内存映像。
RDB的优点在于它的数据文件中包含了一系列经过压缩的 Redis 数据时间点快照,非常适合备份和灾后恢复。RDB 方案对于性能的影响要比 AOF 小,因为它不占用原服务进程的磁盘 IO。在大数据集情况下使用 RDB 方案的 Redis 服务重启时间要快于AOF。
RDB的缺点在于当系统死机时丢失的数据比AOF 多因为RDB只能保留数据到上一次持久化进程运行的那个时间点,该时间点到系统死机这段时间的数据就全部丢失了。而 AOF 则可以记录到系统死机前最后一次写操作的数据。另外RDB fork 进程的次数也会高于AOF 的,而fork 期间,Redis 对客户端的缓存 Set操作的响应会非常慢。(这段时间是内核在进行写时复制,Set 操作越多则响应越慢。)
AOF的优点就是较少的数据丢失,你可以配置各种不同的 fsync(指把缓存中的写指令纪录到磁盘中)策略:不主动进行 fsync,每秒进行一次 fsync,或者每个操作进行一次 fsync。默认是每秒进行一次 fsync,此时日志文件每秒都会被刷新到磁盘上一次,缓存的写操作依然具有不错的性能,而系统死机时最多也就丢失 1s的数据。AOF 的日志只允许添加,所以不会有数据损坏,日志最后如果有写到一半的命令也可以被轻易丢弃。
AOF 的缺点也不少:首先是同样数据量下会比 RDB 占用更多的磁盘空间,因为 AOF 会保存从服务初始状态到最终状态的所有内容:其次 AOF 的速度要比RDB 慢,因为它写入磁盘的频率会高于 RDB,所以受到磁盘 IO的影响也更大而磁盘IO 操作的速度要远远慢于内存读写操作。