目录
前言
Redis持久化的策略有2种,分别是RDB和AOF。
Redis支持3种持久化方式,分别是RDB、AOF和 混合持久化。
为什么需要持久化?
因为redis的数据都是存在内存中的,要是服务器宕机或者服务重启,那么内存中的数据就会丢失掉,因此持久化可以有效的避免这种数据丢失的问题。可以在重启前先将持久化的数据先加载至内存。
RDB方式
是将内存中的数据全部生成快照保存至硬盘中,可以自动触发,也可以手动触发。会生成一个dump.rdb 的二进制文件。
dump.rdb文件保存在dir配置的指定目录下
redis默认是采用LZF算法对生成的RDB文件进行压缩处理的,压缩后的文件远小于内存的大小,默认开启。
1、手动触发
手动触发是通过save和bgsave命令
save命令:是一个同步操作,阻塞redis的其他操作,直到RDB持久化完成为止。当内存较大时会是redis其他操作阻塞时间较长。谨慎使用
bgsave命令:是一个异步操作,redis会创建一个子线程,然后通过子线程进行RDB操作。并不会阻塞redis的其他操作。
2、自动触发
a、需要配置reids配置文件中的save相关配置。
如:save m n 表示在m秒内数据集存在n次修改时,则会触发一次bgsave
b、在执行debug reload 命令时重新加载redis时,也会触发save 操作
c、默认情况下执行shutdown命令时,如果没有开启AOF持久化则会自动执行bgsave命令
bgsave的写时复制(COW)机制
Redis 借助操作系统提供的写时复制技术(Copy-On-Write, COW),在生成快照的同时,依然可以正常 处理写命令。简单来说,bgsave 子进程是由主线程 fork 生成的,可以共享主线程的所有内存数据。 bgsave 子进程运行后,开始读取主线程的内存数据,并把它们写入 RDB 文件。此时,如果主线程对这些 数据也都是读操作,那么,主线程和 bgsave 子进程相互不影响。但是,如果主线程要修改一块数据,那 么,这块数据就会被复制一份,生成该数据的副本。然后,bgsave 子进程会把这个副本数据写入 RDB 文 件,而在这个过程中,主线程仍然可以直接修改原来的数据。
优点:
- RDB是被压缩的二进制文件,大小要小很多
- redis加载RDB恢复数据要比AOF快很多
缺点:
- 每次通过bgsave持久化都要创建子线程,操作很重,成本很高
- RDB是二进制文件保存的,新老版本不兼容
AOF 方式
是将每次的修改数据的操作记录在aof日志中,重启的时候通过aof中的命令重新执行一遍操作,从而恢复数据。
开启AOF需要修改配置,设置appendonly yes,默认是关闭的
持久化流程:
- 所有的写入命令会追加到aof_buf(缓冲区)中
- 缓冲区的数据会进行持久化
- 重写机制,AOF文件越来越大时,会定期对AOF文件进行重写。从而达到了压缩文件的目的
- redis重启时,通过加载AOF文件来进行数据恢复
AOF文件同步有3种策略:
1、appendfsync always:每次有新命令追加到 AOF 文件时就执行一次 fsync ,非常慢,也非常安全。
2、appendfsync everysec:每秒 fsync 一次,足够快,并且在故障时只会丢失 1 秒钟的数据。
3、appendfsync no:从不 fsync ,将数据交给操作系统来处理。更快,也更不安全的选择。
重写机制
为什么需要重写?
1、因为AOF文件中有很多无效的命令,我们主需要保留最终数据的写入命令即可。
如set key a 、set key b 、set key c 这种,前面两句完全可以不用要,我们只保留
set key c即可
2、多条命令合并成1条。
如 lpush list a 、lpush list b 、lpush list c 可以将3条合并为1条,lpush list a b c
AOF重写也分为手动触发和自动触发
手动触发:执行bgrewriteaof
自动触发:修改配置
1 # auto‐aof‐rewrite‐min‐size 64mb //aof文件至少要达到64M才会自动重写,文件太小恢复速度本来就 很快,重写的意义不大
2 # auto‐aof‐rewrite‐percentage 100 //aof文件自上一次重写后文件大小增长了100%则再次触发重写
注意,AOF重写redis会fork出一个子进程去做(与bgsave命令类似),不会对redis正常命令处理有太多 影响
RDB和AOF对比
RDB | AOF | |
启动优先级 | 低 | 高 |
占用空间 | 小 | 大 |
恢复速度 | 快 | 慢 |
数据丢失情况 | 较多 | 较少 |
混合持久化
从上面可以看出RDB和AOF 各有优缺点,因此redis在4.0之后有了一种新的持久化方式,RDB和AOF的混合持久化。
混合持久化默认是关闭的,需要通过如下配置打开
# aof‐use‐rdb‐preamble yes
开始的时候是以AOF格式进行持久化的,在AOF重写的时候,跟单纯的AOF重写不同了,而是在重写的时候将此时之前的内存数据以RDB的方式生成快照,在生成RDB快照期间继续的写入命令继续以AOF的方式持久化,然后将RDB快照内容和增量的AOF日志命令合在一起,生成一个新的AOF文件,开始不叫appendonly.aof文件,等重写完新的AOF文件才会覆盖之前的appendonly.aof文件。
Redis 在重启的时候,会先加载文件中RDB的内容,然后再重新加载AOF日志的内容。
实际工作中如何持久化:
- 通过定时任务和脚本,根据自己的业务场景合理的将备份文件额外复制到指定的目录中
- 需要将持久化文件复制一份至其他机器中,防止当前机器磁盘损坏等问题
- 复制的备份文件根据自己的需求保留最新一段时间的文件即可,如保留48小时或1个月等