litterfrog 2020-05-11
持久化:将内存中的数据存储硬盘进行保存,在特定的时间将保存的数据进行恢复,防止数据的意外丢失,比如服务器重启或者宕机,可以保证数据安全,Redis有两种持久化方案,一个是持久化数据,叫做RDB;一个是持久化命令,叫做AOF
定期将内存中的数据生成快照保存到磁盘里面,保存的文件为后缀为.rdb的压缩过的二进制文件,当redis重启后,会读取rdb文件恢复数据。RDB 功能最核心的是 rdbSave 和 rdbLoad 两个函数, 前者用于生成 RDB 文件并保存到磁盘,而后者则用于将 RDB 文件中的数据重新载入到内存中
RDB 文件是一个单文件的全量数据,很适合数据的容灾备份与恢复,通过 RDB 文件恢复数据库耗时较短,通常 1G 的快照文件载入内存只需 20s 左右。Redis 提供了手动触发保存、自动保存间隔两种 RDB 文件的生成方式,下面先介绍 RDB 的创建和载入过程。
方式一:执行 save
命令,手动执行保存操作,立即执行,但是save命令因为是立即执行,是同步的,所以会阻塞当前的Redis服务器,直到当前RDB过程完成为止,有可能会造成长时间的阻塞,所以并不推荐使用!
方式二:bgsave
命令,手动启动保存操作,在后台执行;是异步的,bgsave的原理是在后台使用fork函数复制一份当前进程的副本(子进程)去执行;bgsave是对save造成阻塞的问题做了优化,将生成rdb文件的操作放在后台执行,Redis内部涉及rdb的操作都用bgsave完成
bgsave执行流程:
1.客户端发起 BGSAVE 命令,Redis 主进程判断当前是否存在正在执行备份的子进程,如果存在则直接返回
2.如果没有的话会fork一个子进程,子进程根据父进程的内存数据生成临时的快照文件,然后替换原文件
3.子进程备份完毕后向父进程发送完成信息,父进程更新统计信息
save和bgsave对比:
命令 | save | bgsave |
---|---|---|
IO 类型 | 同步 | 异步 |
是否阻塞 | 全程阻塞 | fork时阻塞 |
优点 | 不会消耗额外的内存 | 不阻塞客户端 |
缺点 | 阻塞客户端 | fork子线程会消耗内存 |
在redis.conf中进行配置save,当满足了条件时会自动执行持久化,该操作也是通过bgsave完成的;
#配置自动持久化的 条件 save 90 1 --90秒内有一次变更 save 300 10 --300秒内有10次变更 save 60 10000 --60秒内有10000次变更 dbfilename dump.rdb --持久化文件名称 stop-writes-on-bgsave-error yes -- 在持久化过程中出错的话停止写入,默认开启 rdbcompression yes -- 使用压缩校验,会加大CPU压力,但是会减少文件体积 dir ./ 持久化文件写入的目录。默认为当前启动目录。
持久化的流程:
1.父进程继续接收并处理客户端发来的命令,而子进程开始将内存中的数据写入硬盘中的临时文件
2.当子进程写入完所有数据后会用该临时文件替换旧的RDB文件,至此一次快照操作完成。
可能会有一个问题,那就是当子进程执行的时候,父进程如果此时又有新的写命令怎么办呢?
执行 fork函数时会使用写时(copy-write)策略,即fork执行的那一刻父子进程共享一份数据,当父进程有写的命令时,也会复制一份到子进程,保证子进程的数据不受影响
RDB优点:
RDB缺点:
将redis执行的写命令记录到aof日志文件中,服务器重启时再次执行aof文件中的命令恢复数据;AOF主要是为了解决数据持久化的实时性,保证数据不丢失,目前是主流方式
相关配置:
appendonly yes|no --开启AOF持久化功能 appendfsync always|everysec|no --策略 #重写相关配置 no-appendfsync-on-rewrite yes|no --是否开启重写机制,默认触发规则是上一次重写的64倍且大于1M auto-aof-rewrite-percentage 100 --默认触发规则是上次 rewrite 的一倍 auto-aof-rewrite-min-size 64mb --大于 64M
AOF文件写入的三个步骤:
1.命令追加:将Redis 执行的写命令追加到 AOF 的缓冲区 aof_buf
2.文件写入(write)和文件同步(fsync):AOF 根据对应的策略将 aof_buf 的数据同步到硬盘
3.文件重写(rewrite):定期对 AOF 进行重写,从而实现对写命令的压缩。
AOF优点:
AOF缺点 :
在重启 Redis 服务器时,一般很少使用 RDB 快照文件来恢复内存状态,因为会丢失大量数据。更多的是使用 AOF 文件进行命令重放,但是执行 AOF 命令性能相对 RDB 来说要慢很多。这样在 Redis 数据很大的情况下,启动需要消耗大量的时间。
鉴于 RDB 快照可能会造成数据丢失,AOF 指令恢复数据慢,Redis 4.0 版本提供了一套基于 AOF-RDB 的混合持久化机制,保留了两种持久化机制的优点。这样重写的 AOF 文件由两部份组成,一部分是 RDB 格式的头部数据,另一部分是 AOF 格式的尾部指令。
Redis 4.0 版本的混合持久化功能默认是关闭的,通过配置 aof-use-rdb-preamble 为 yes 开启此功能:
aof-use-rdb-preamble yes
1.当 AOF 持久化功能开启时,Redis 服务器启动时优先执行 AOF 文件的命令恢复数据,只有当 AOF 功能关闭时,才会优先载入 RDB 快照的文件数据
2.当 AOF 功能开启,且 AOF 文件不存在时,即使 RDB 文件存在也不会加载
方案 | RDB | AOF |
---|---|---|
存储效率 | 快 | 慢 |
恢复速度 | 快 | 慢 |
数据安全性 | 不安全 | 安全 |