redis 提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。
RDB,简而言之,就是在不同的时间点,将 redis 存储的数据生成快照并存储到磁盘等介质上;
AOF,则是换了一个角度来实现持久化,那就是将 redis 执行过的所有写指令记录下来,在下次 redis 重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。
其实 RDB 和 AOF 两种方式也可以同时使用,在这种情况下,如果 redis 重启的话,则会优先采用 AOF 方式来进行数据恢复,这是因为 AOF 方式的数据恢复完整度更高。
如果你没有数据持久化的需求,也完全可以关闭 RDB 和 AOF 方式,这样的话,redis 将变成一个纯内存数据库,就像 memcache 一样。
redis持久化RDB
RDB 是 Redis 默认的持久化方案。在指定的时间间隔内,执行指定次数的写操作,则会将内存中的数据写入到磁盘中。即在指定目录下生成一个dump.rdb文件。Redis 重启会通过加载dump.rdb文件恢复数据。
从配置文件了解RDB
官方配置文档:https://raw.githubusercontent.com/redis/redis/6.0/redis.conf
打开redis.conf文档,找到SNAPSHOTTING 对应内容
- RDB核心规则配置
save <指定时间间隔> <执行指定次数更新操作>,满足条件就将内存中的数据同步到硬盘中。官方出厂配置默认是 900秒内有1个更改,300秒内有10个更改以及60秒内有10000个更改,则将内存中的数据快照写入磁盘。 若不想用RDB方案,可以把 save "" 的注释打开,下面三个注释掉
-
指定本地数据库文件名,默认是dump.rdb
-
指定本地数据库存放目录,一般使用默认配置
-
默认开启数据压缩
配置存储至本地数据库时是否压缩数据,默认为yes。Redis采用LZF压缩方式,但占用了一点CPU的时间。若关闭该选项,但会导致数据库文件变的巨大。建议开启
触发RDB快照
- 在指定的时间间隔内,执行指定次数的写操作
- 执行save(阻塞, 只管保存快照,其他的等待) 或者是bgsave (异步)命令
- 执行flushall 命令,清空数据库所有数据,意义不大。
- 执行shutdown 命令,保证服务器正常关闭且不丢失任何数据,意义...也不大。
通过RDB文件恢复数据
将dump.rdb 文件拷贝到redis的安装目录的bin目录下,重启redis服务即可。在实际开发中,一般会考虑到物理机硬盘损坏情况,选择备份dump.rdb
RDB的优缺点
优点:
- RDB文件小,非常适合定时备份,用于灾难恢复
- Redis加载RDB文件的速度比AOF快很多,因为RDB文件中直接存储的时内存数据,而AOF文件中存储的是一条条命令,需要重演命令。
缺点:
- 数据的完整性和一致性不高,因为RDB可能在最后一次备份时宕机了。
- 备份时占用内存,因为Redis 在备份时会独立创建一个子进程,将数据写入到一个临时文件(此时内存中的数据是原来的两倍哦),最后再将临时文件替换之前的备份文件。
所以Redis 的持久化和数据的恢复要选择在夜深人静的时候执行是比较合理的。 - 存在老版本的Redis不兼容新版本RDB格式文件的问题
redis持久化AOF
AOF :Redis 默认不开启。它的出现是为了弥补RDB的不足(数据的不一致性),所以它采用日志的形式来记录每个写操作,并追加到文件中。Redis 重启的会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
从配置文件了解AOF
官方配置文档:https://raw.githubusercontent.com/redis/redis/6.0/redis.conf
打开redis.conf文档,找到APPEND ONLY MODE对应内容
-
redis 默认关闭AOF,开启需要手动把no改为yes
-
指定本地数据库文件名,默认值为 appendonly.aof
-
指定更新日志条件
always:同步持久化,每次发生数据变化会立刻写入到磁盘中。性能较差当数据完整性比较好(慢,安全)
everysec:出厂默认推荐,每秒异步记录一次(默认值)
no:不同步
- 配置重写触发机制
当AOF文件大小是上次rewrite后大小的一倍大于64M时触发,一般都设置为3G,64M太小了
触发AOF快照
根据配置文件触发,可以是每次执行触发,可以是每秒触发,可以不同步
手动触发直接调用bgrewriteaof命令
redis-cli -h ip -p port bgrewriteaof
根据AOF文件恢复数据
正常情况下,将appendonly.aof 文件拷贝到redis的安装目录的bin目录下,重启redis服务即可。但在实际开发中,可能因为某些原因导致appendonly.aof 文件格式异常,从而导致数据还原失败,可以通过命令redis-check-aof --fix appendonly.aof 进行修复
。
AOF的重写机制
为什么要重写?
AOF的工作原理是将写操作追加到文件中,文件的冗余内容会越来越多。所以聪明的 Redis 新增了重写机制。当AOF文件的大小超过所设定的阈值时,Redis就会对AOF文件的内容压缩。
重写原理:Redis会fork出一条新进程,读取内存中的数据,并重新写到一个临时文件中,并没有读取旧文件,最后替换旧的aof文件。
触发机制:当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。这里的“一倍”和“64M” 可以通过配置文件修改。
AOF的优缺点
优点
AOF只是追加写日志文件,对服务器性能影响较小,速度比RDB要快,消耗的内存较少
缺点
- AOF方式生成的日志文件太大,需要不断AOF重写,进行瘦身。
- 即使经过AOF重写瘦身,由于文件是文本文件,文件体积较大(相比于RDB的二进制文件)。
- AOF重演命令式的恢复数据,速度显然比RDB要慢。
RDB和AOF选择
-
不要仅仅使用RDB这样会丢失很多数据。
-
也不要仅仅使用AOF,因为这样会有两个问题,第一通过AOF做冷备没有RDB做冷备恢复的速度快;第二RDB每次简单粗暴生成数据快照,更加健壮。
-
综合AOF和RDB两种持久化方式,用AOF来保证数据不丢失,作为恢复数据的第一选择;用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,可以使用RDB进行快速的数据恢复。
Redis 4.0 混合持久化
混合持久化只发生于 AOF 重写过程。使用了混合持久化,重写后的新 AOF 文件前半段是 RDB 格式的全量数据,后半段是 AOF 格式的增量数据。
- 仅使用RDB快照方式恢复数据,由于快照时间粒度较大,时回丢失大量数据。
- 仅使用AOF重放方式恢复数据,日志性能相对 rdb 来说要慢。在 Redis 实例很大的情况下,启动需要花费很长的时间。
Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。将 rdb 文件的内容和增量的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,而是自持久化开始到持久化结束的这段时间发生的增量 AOF 日志,通常这部分 AOF 日志很小。相当于:
- 大量数据使用粗粒度(时间上)的rdb快照方式,性能高,恢复时间快。
- 增量数据使用细粒度(时间上)的AOF日志方式,尽量保证数据的不丢失。
在 Redis 重启的时候,可以先加载 rdb 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重启效率因此大幅得到提升。