likes
comments
collection
share

【Redis】浅谈持久化-RDB&AOF

作者站长头像
站长
· 阅读数 18

Hi,大家好,我是抢老婆酸奶的小肥仔。

上一篇我们浅谈了下《浅谈Redis的发布(Push)和订阅(sub)》,详情参见:juejin.cn/post/723317… 

下面我们来看看redis的持久化。

redis的数据一般保存在内存中,如果在操作过程中突然断电或服务死掉,那么其保存的数据将会丢失,因此我们需要将redis中的数据进行持久化,将其保存到硬盘中。

redis实现数据持久化提供了两种方式:RDB和AOF

1、RDB

RDB即Redis DataBase,即在指定的时间间隔内将内存中的数据集快照写入磁盘(Snapshot快照),恢复时是将快照文件直接读到内存中。RDB持久化后生成的文件的扩展名是.rdb,是一种存储二进制的文件。

1.1 持久化流程

持久化流程图:

【Redis】浅谈持久化-RDB&AOF

1、bgsave通知父线程需要进行RDB备份

2、父进程检查当前redis是否存在正在执行的rdb/aof,如果存在则直接返回,不存在则fork子进程进行rdb持久化。

3、不存在正在执行的rdb/aof,父线程fork出一个子线程进行持久化,该子线程会先将数据写入到一个临时文件中,待持久化过程都结束后,再用这个临时文件替换上次就持久化好的文件。

4、子进程将数据写入新的RDB文件中,并将新的RDB文件替换旧的RDB文件

5、子进程完成RDB快照后,通知父进程关闭子进程(自己理解)

1.2 常用RDB配置

RDB所有的配置都存在于redis.conf中。

  1. dbfilename dump.rdb:修改rdb备份文件名称,默认:dump.rdb。
  2. dir ./ :rdb文件保存的文件目录,默认:./表示执行redis-server命令启动redis时所在的目录。
  3. stop-writes-on-bgsave-error:当磁盘满时,是否关闭redis的写操作。默认:yes
  4. rdbcompression:rdb备份是否开启压缩。默认:yes,采用LZF算法进行压缩,会消耗CPU资源
  5. rdbchecksum:是否检查rdb备份文件的完整性,默认:yes,采用CRC64算法进行数据校验

1.3 触发RDB备份

1.3.1 自动备份

RDB提供了自动备份的触发条件,在redis.conf中配置save就可以了。

语法规则:save 秒钟 写操作次数

默认:1分钟内修改了1万次,或5分钟内需修改了10次,或1小时内修改了1次

表达式:save 60 10000 save 300 100 save 3600 1

1.3.2 手动备份

手动备份有两种触发方式:

  1. save:save只管保存,不管其他,会导致全部阻塞(父线程也会),手动保存,不建议使用
  2. bgsave:redis异步进行快照操作,即fork出子线程进行备份,而主线程依然可以响应客户端情况。lastsave命令获取最后一次成功生成快照的时间。

1.3.3 flushall命令

执行flushall命令也会产生dump.rdb文件,但是这个rdb文件是空的,无意义。

1.4 RDB备份和恢复

1.4.1 备份

  1. 通过命令config get dir查找rdb文件的目录
  2. 将rdb文件拷贝到备份文件加下 cp dump.rdb dump2.rdb

1.4.2 恢复

  1. 关闭redis
  2. 先把备份的文件拷贝到工作目录:cp dump2.rdb dump.rdb
  3. 启动redis,备份数据直接加载,数据恢复

1.5 优缺点

1.5.1 优点

  1. 适合大规模数据恢复
  2. 对数据完整性和一致性要求不高更适合使用
  3. 节约磁盘空间,一般10kb的命令转换成rdb可能只有1kb
  4. 恢复速度快,不需要像aof一样一个个去执行写命令。

1.5.2 缺点

  1. fork时,内存数据会被克隆一份,大致2倍
  2. fork时使用写时拷贝技术,数据量庞大时比较耗性能
  3. 在一定间隔时间备份一次,如果redis意外down机,会导致最后一次快照数据丢失

2、AOF

AOF(Append Only File):以日志的形式记录每一次写操作,将redis执行过的所有写指令记录下来,只允许追加文件但不可改写文件。数据恢复时,读取AOF的写命令一行行执行来恢复数据。

2.1 持久化流程

【Redis】浅谈持久化-RDB&AOF

  1. 客户端的请求写命令会被append追加到AOF缓冲区
  2. AOF缓冲区会根据AOF持久化策略【always/everysec/no】将操作sync同步到磁盘的AOF文件
  3. AOF文件大小超过重写策略或手动重写时,会对AOF文件进行重写(rewrite),压缩AOF文件容量
  4. redis服务器重启时,重新load加载AOF文件中的写操作达到数据恢复的目的。

2.2 AOF配置

  • appendony no:是否开启AOF,yes:开启,no:关闭。默认:no
  • appendfilename "appendonly.aof" :aof文件名称,默认:appendonly.aof
  • dir ./ :aof文件所在目录,默认:./,表示执行启动命令时所在的目录,
  • no-appendfsync-on-rewrite:重写时,不会执行appendfsync操作,该参数表示在正在进行AOF重写时不会将AOF缓冲区的数据同步到旧的AOF文件磁盘。

如果为yes:不写入aof文件,只写入缓存,用户请求不会阻塞,如果宕机,那么这段时间内的缓存数据会丢失(降低数据安全性,提高性能)。

如果为no:数据写入磁盘中,遇到重写时,可能会造成阻塞(数据安全,性能降低)

2.3 AOF和RDB同时开启,redis以谁为准?

redis系统默认取AOF的数据,原因:RDB会丢失最后一次备份的数据,导致数据不完整,而AOF不会存在这种问题,即:AOF的数据完整,不会丢失数据。

2.4 数据恢复

  1. 正常恢复

1.1 修改默认配置:appendonly no 为 yes

1.2 将备份数据aof拷贝到对应目录(config get fir)

1.3 重启redis服务

  1. 异常恢复

2.1 修改默认配置:appendonly no 为 yes

2.2 如aof文件损坏:通过/usr/local/bin/redis-check-aof --fix appendonly.aof进行修复

2.2 将备份数据aof拷贝到对应目录(config get fir)

2.3 重启redis服务

2.5 AOF同步频率

redis将写操作追加到aof文件中,多久执行一次追加,redis提供了appendfsync进行设置:

appendfsync always:每次写入立即同步,这样会导致redis的吞吐量大大降低,违背了redis设计初衷,不推荐使用。

appendfsync everysec:每秒同步,每秒记录日志一次,如果宕机,也只会丢失1s的数据,更新的命令会放在AOF的缓冲区,每秒在从缓冲区将命令追加到AOF文件,redis默认采用的同步频率。

appendfsync no:不主动同步,即同步交由操作系统,操作系统同步的周期不固定,最长会有30s间隔,这样出现故障时丢失数据较多。

2.6 AOF文件重写

Redis AOF文件重写是把Redis进程内的数据转化成写命令同步到新AOF文件的过程,重写之后的AOF文件会比旧的AOF文件占更小体积,原因:

  • 进程内已超时的数据不在写入文件
  • 旧的aof文件含有无效命令,而重写后aof文件只保留最终数据的写入命令
  • 多条写命令合并成一条命令,例如: lpush list a、lpush list b、lpush list c可以转化为:lpush list a b c

重写后的aof占用更小的空间,节约了磁盘空间,恢复数据时,aof加载时间更短。

AOF重写分【手动触发】和【自动触发】

2.6.1 重写流程

【Redis】浅谈持久化-RDB&AOF

手动触发:即执行命令:bgrewirteaof

自动触发:在redis.conf修改配置

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

auto-aof-rewrite-percentage:表示当前aof文件空间(aof_current_size)和上一次重写AOF文件空间(aof_base_size)的比值,默认100%。

auto-aof-rewrite-min-size:表示运行AOF重写时AOF文件最小体积,默认:64MB,即AOF文件最小为64MB才有可能触发重写。

流程:

  1. 手动执行bgrewriteaof命令或自动触发重写,判断当前是否有bgfsave或bgrewriteaof在运行,如果有,则等待命令结束后再继续执行。
  2. 主进程fork出子线程进行重写操作,保证主进程不会阻塞
  3. 子进程遍历redis内的数据到临时文件,客户端写请求同时写入aof_buf缓冲区和aof_rewrite_buf重写缓冲区保证原AOF文件完整性以及新AOF文件生成期间的新的数据写操作不会丢失
  4. 子进程写完新的AOF后,向主进程发送信号,父进程更新统计信息
  5. 主进程把aof_rewrite_buf中的数据写入新的AOF文件
  6. 使用新的AOF文件替换旧的AOF文件,完成AOF重写

2.7 优缺点

2.7.1 优点

  • 备份机制更全面,丢失数据概率更低
  • 可读的日志文件,通过操作AOF文件,可以处理误操作

2.7.2 缺点

  • 比RDB占用更多的磁盘空间
  • 恢复速度较慢
  • 每次写操作同步的话,会造成一定性能压力
  • 存在个别bug时,造成不能恢复