AOF和RDB持久化的区别
redis
作为我们经常使用的工具之一,熟悉它的特性还是很有必要的,这次写这篇文章也是在这方面吃了点亏, 我在参加某计算机考试时,有道题询问了这方面知识,原题我也记不大清楚了,我当时答的不是很好,感觉这种题丢分很不应该,所以写下文章,方便自我反省。
首先就是在开发中这个缓存应该是十分常用的,但是作为开发可能对于一些细节并没有很多的了解,毕竟业务压身,身不由己,有时候过来看看还是因为要面试,实在是惭愧,这篇文章我们先对 AOF
RDB
做了一个回顾,然后从几个方面进行说明对比,分析他们的优缺点,选择合适的持久化方式。
AOF和RDB持久化过程回顾
从前两篇文章我们知道了 AOF
和 RDB
持久化的一些细节,忘了的可以再去看看哦!我们再来对比一下,什么环境选择什么持久化方式比较好?首先我们对两种持久化方式的过程进行回顾
AOF持久化过程
AOF
持久化是类似 Mysql
的 binlog
日志,记录所有的修改操作,所有客户端发送的命令都以 Redis命令协议
格式进行追加保存, 为了保证文件大小的适当, Redis
还在后台对 AOF
文件进行子进程创建重写,使得 AOF
文件体积不会超出保存数据集状态所需的实际大写,并在服务器启动时,通过执行这些命令来还原数据集,要注意, Redis会优先使用 AOF
文件来还原数据, 因为 AOF
文本保存的数据集一般比 RDB
所保存的数据集更完整,并且 存储的文件一般也比 RDB
的文件大。
RDB持久化过程
RDB
持久化是在指定的时间间隔内生成数据集的时间点快照,当满足配置文件里面的条件时,父进程在保存 RDB
文件时唯一要做的就是 fork 出一个子进程, 然后子进程就会处理接下来所有的工作父进程无须执行任何磁盘 I/O
操作,在保存 Redis
里面的数据集时,它会利用 lzf算法 进行字符压缩,来保证文件大小适当,RDB
在恢复大数据集时的速度比 AOF
的恢复速度要快,它不需要一条一条指令执行。
分析
在 RDB
和 AOF
的写入上就有不同的特点,一个是追加写入,一个是保存整个数据集,从这两个操作的数据量上面就可以看出, RDB
在进行写入的时候不能太频繁了,要控制好频率,还有一个就是每次 fork
一个子进程,同时也阻塞命令的执行,虽然 fork
创建的子进程不需要拷贝父进程的物理内存空间,但是会复制父进程的空间内存页表。例如对于 10GB
的 Redis
进程,需要复制大约 20MB
的内存页表,因此 fork
操作耗时跟进程总内存量息息相关。对于高流量的 Redis
实例 OPS
可达5万以上,如果 fork
操作耗时在秒级别将拖慢 Redis
几万条命令执行,对线上应用延迟影响非常明显。正常情况下 fork
耗时应该是每 GB
消耗 20毫秒
左右。可以在info stats
统计中查 latest_fork_usec
指标获取最近一次 fork
操作耗时,单位微秒。
优缺点总结与分析
RDB的优缺点
优点
RDB
是一个紧凑压缩的二进制文件,代表Redis
在某个时间点上的数据快照。非常适用于备份,全量复制等场景。比如每6小时执行bgsave
备份,并把RDB
文件拷贝到远程机器或者文件系统中(如hdfs),用于灾难恢复。Redis
加载RDB
恢复数据远远快于AOF
的方式。
缺点
RDB
方式数据没办法做到实时持久化/秒级持久化。因为bgsave
每次运行都要执行fork
操作创建子进程,属于重量级操作,频繁执行成本过高。RDB
文件使用特定二进制格式保存,Redis
版本演进过程中有多个格式的RDB
版本,存在老版本Redis
服务无法兼容新版RDB
格式的问题。- 针对
RDB
不适合实时持久化的问题,Redis
提供了AOF
持久化方式来解决。
AOF的优缺点
优点
- 采用
fsync
策略,可以较好地保证数据的完整性 - 拥有重写可以起到压缩文件大小的效果
- 执行了
flushall
命令,只要AOF
文件没有被重写,移除尾部flushall
命令,重启就可以恢复之前的状态
缺点
- 采用
fsync
策略会降低性能(这属于一个权衡点) - 由于数据较为完整,所以文件也会比
RBD
稍大
我们该如何选择?
如果 redis
里面存储的数据比较重要,你应该同时使用两种持久化功能。如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB
持久化。
有很多用户都只使用 AOF
持久化, 但我们并不推荐这种方式: 因为定时生成 RDB
快照(snapshot)
非常便于进行数据库备份, 并且 RDB
恢复数据集的速度也要比 AOF
恢复的速度要快, 除此之外,可还可以避免一些 AOF
的 BUG
。