Redis持久化机制(RDB,AOF,混合持久化)
前言
Redis是一个支持持久化的内存数据库,需要频繁的将数据同步到磁盘来保证持久化,避免因进程的退出而造成的数据丢失。Redis提供了两种持久化方法。一种方法叫做
快照(snapshotting)
,它可以将存在于某一时刻的所有数据写入到磁盘里。另外一种叫只追加文件(append-only file,AOF)
,它会在执行写命令时,将写命令复制到硬盘里
一、快照持久化
快照持久化就是将当前的数据生成一个快照(.rdb)文件保存到磁盘里
1.快照生成的情况
1.1 手动执行bgsave命令
客户端向redis发送bgsave命令来创建一个快照,redis调用fork创建一个子进程将快照写进磁盘,而父进程继续处理客户端的请求
1.2 手动执行save命令
与bgsave命令的区别在于,接收save命令后,Redis不再接收客户端的命令,发生阻塞,因此使用该命令时需谨慎
1.3 save配置
Redis设置了save配置,当条件满足时,Redis就会触发bgsave命令,如果配置了多个save配置项,任意一个条件满足时都会触发bgsave命令
# Save the DB on disk:
#
# save <seconds> <changes>
#
# Will save the DB if both the given number of seconds and the given
# number of write operations against the DB occurred.
#
# In the example below the behaviour will be to save:
# after 900 sec (15 min) if at least 1 key changed
# after 300 sec (5 min) if at least 10 keys changed
# after 60 sec if at least 10000 keys changed
#
# Note: you can disable saving completely by commenting out all "save" lines.
#
# It is also possible to remove all the previously configured save
# points by adding a save directive with a single empty string argument
# like in the following example
#
# save ""
save 900 1 # 900秒内1个key发生变化就触发
save 300 10 # 300秒内10个key发生变化触发
save 60 10000
查看dump.rdb文件
1.4 shutdown命令
当执行shutdown命令后,会执行save命令保存数据,执行完成后关闭服务器
1.5 复制操作
当Redis服务器连接另外一台Redis服务器时,并发送sync命令开始复制时,如果主服务器或者刚刚没有执行bgsave命令,那么主服务器会立即执行bgsave命令
2.快照方式的缺点
- 无法保证实时持久化,每次都要创建子进程,频繁操作成本过高
- 保存后的二进制文件,存在老版本不兼容的问题
二、AOF持久化
1.AOF配置
# 默认为no 设置为yes开启aof持久化方式
appendonly yes
# 每收到写命令时会强制立即写入磁盘,最慢,但是保证完全持久化,不推荐使用
# appendfsync always
# 每秒强制写入磁盘一次,性能和持久化做了折中,推荐使用
appendfsync everysec
# appendfsync no
# 正在导出rdb快照的过程中,要不要停止同步aof
no-appendfsync-on-rewrite yes
# aof文件大小比起上次重写时的大小,增长率100%时,重写
auto-aof-rewrite-percentage 100
# aof文件,至少超过64M时,重写
auto-aof-rewrite-min-size 64mb
2.AOF持久化流程
- 所有的写命令都会追加到AOF缓冲区内
- AOF缓冲区会向硬盘做同步操作
- AOF文件大的时候,会进行文件压缩
- Redis服务重启时,会优先加载AOF文件
3.重启加载RDB与AOF文件的顺序
- Redis启动时会检查是否开启AOF,开启AOF则检查AOF文件是否存在,文件存在加载AOF文件
- 若没有开启AOF或者没有检测到AOF文件,则加载RDB文件
4.AOF与RDB两种方式对比
快照 | AOF |
---|---|
全量备份,一次保存整个数据库 | 增量备份,一次保存一个修改数据库的命令 |
保存时间间隔比较长 | 保存时间间隔默认一秒 |
数据还原快 | 数据还原慢 |
适合数据备份,默认开启 | 适合保存数据,默认关闭 |
save阻塞,bgsave不会阻塞 | 不会阻塞 |
启动优先级低 | 启动优先级高 |
体积小 | 体积较大 |
恢复速度快 | 恢复速度慢 |
数据安全性低,会丢失数据 | 数据安全性:根据策略决定 |
轻重:重 | 轻重:轻 |
三、混合持久化
重启Redis时,我们很少使用RDB来恢复内存状态,因为会丢失大量数据。我们通常使用AOF日志重放,但是重放AOF日志性能相对于RDB来说慢很多,在Redis实例大的情况下,启动需要花费很长时间,Redis4.0之后提供了新的持久化机制,混合持久化
修改配置开启混合持久化(需开启aof)
aof‐use‐rdb‐preamble yes
如果开启了混合持久化,AOF在重写时,不再单纯的将内存数据转换为resp命令写入AOF文件,而是将重写这一刻之前的内存做了RDB快照处理,并且将RDB快照内容和增量AOF修改内存数据的命令存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换。在Redis重启时,可以先加载RDB内容,然后再重放增量AOF日志就可以完全替代之前的AOF全量文件重放,重启效率大幅度提升
混合持久化AOF文件结构:
四、Redis数据备份策略
1.写crontab定时调度脚本,每小时都copy一份rdb或aof到一个目录中去,仅仅保留最近48小时的备份
2.每天都保留一份单日的数据到一个目录中去,可以保留最近一个月的备份
3.每次copy备份的时候,都把太旧的备份给删了
4.每天晚上将当前机器上的备份复制一份到其他机器上,防止机器损坏