Redis 持久化

目录

1.持久化

2.RDB

2.1 触发机制

2.2 bgsave 命令运行流程

2.3 RDB 文件的处理

2.4 RDB 的优缺点

3.AOF

3.1 使用 AOF

3.2 文件同步

3.3 重写机制

3.4 启动时数据恢复


1.持久化

把数据存储在硬盘上是不持久,把数据存储在内存中就是持久,而 Redis 是一个内存数据库,把数据存储在内存中,由于内存中的数据不持久,因此需要把让 Redis 把数据存储在硬盘上,而 Redis把数据既在内存中存储,也在硬盘上存储

当要插入一个新的数据的时候,就把这个新的数据同时写入内存和硬盘,当需要查询某个数据的时候,直接从内存中读取,硬盘中的数据只是在 Redis 重启的时候,用来恢复内存中的数据;这样既保证了效率,又保证了持久

2.RDB

RDB 持久化是把当前进程数据生成快照保存到硬盘的过程,触发 RDB 持久化过程称为手动触发和自动触发

2.1 触发机制

手动触发分别对应 save 和 bgsave命令:

1)save 命令:阻塞当前 Redis 服务器,直到 RDB 过程完成为止,对于内存比较大的实例造成长时间阻塞(相当于 keys *),基本不采用

2)bgsave 命令:Redis 进程执行 fork 操作创建子进程,RDB 持久化过程由子进程负责,完成后自动结束,阻塞只发生在 fork 阶段,一半时间很短

在 Redis 内部的所有涉及 RDB 的操作都采用类似 bgsave 的方式

2.2 bgsave 命令运行流程

1)执行 bgsave 命令,Redis 父进程判断当前进程是否存在其他正在执行的子进程,如 RDB 子进程,如果存在 bgsave 命名直接返回

2)父进程执行 fork 创建子进程,fork 过程中父进程会阻塞

3)父进程 fork 完成后,bgsave 命令返回"Background saving started"信息并不再阻塞父进程,可以继续响应其他命令

4)子进程创建 RDB 文件,根据父进程内存生成临时快照文件,完成后对原有的文件进行原子替换

5)进程发送信号给父进程表示完成,父进程更新统计信息

RDB 持久化操作是可以触发多次的,当执行 RDB 操作的时候,就会把要生成的快照,先保存到一个临时的文件中,当这个快照生成完毕之后,再删除之前的 RDB 文件,然后把新生成的 RDB 文件名改成刚才的 dump.rdb,RDB 文件始终只有一个bagsave 操作流程是创建子进程,子进程完成持久化操作,持久化会把数据写入到新的文件中,然后使用新的文件替换旧的文件

示例:

此时 Redis 中没有任何数据,RDB文件如下

插入两条数据,手动 bgsave 命令

再次观察 RDB 文件

自动触发,在 Redis 配置文件中,设置一下,让 Redis 每隔多长时间/每产生多少次修改就触发

这里的触发机制有3种

1)在 15 分钟修改 1 次就会触发

2)在 5 分钟修改 10 次就会触发

3)在 1 分钟修改 1w 次就会触发 

手动配置在 1 分钟 修改 2 次触发 RDB持久化

2.3 RDB 文件的处理

保存:RDB 文件保存在 dir 配置指定的目录(默认/var/lib/redis/)下,文件名通过 dbfilename 配置(默认 dump.rdb)指定

压缩:Redis 默认采用 LZF 算法对生成的 RDB 文件做压缩处理,压缩后的文件远远小于内存大小,默认开启

2.4 RDB 的优缺点

1)RDB 是一个紧凑压缩的二进制文件,代表 Redis 在某个时间上点的数据快照,非常适用于备份,全量复制等场景,比如每 6 小时执行 bgsave 备份

2)Redis 加载 RDB 恢复数据远远快于 AOF 的方式(RDB 使用二进制的方式组织数据,直接把数据读取到内存中,按照字节的格式取出来,AOF 使用文本的方式组织从数据,需要进行一系列的字符串分割操作)

3)RDB 方式数据没办法做到实时持久化 / 秒级持久化,因为 bgsave 每次运行都要执行 fork 创建子进程,属于重量级操作,频繁执行成本过高

4)RDB 最大的问题就是不能持久化保存数据,在两次生成快照之间,实时的数据可能会随着重启而丢失

3.AOF

AOF 持久化:以独立日志的方式记录每次写命令,重启时在重新执行 AOF 文件中的命令达到恢复数据的目的,AOF 的主要作用时解决了数据持久化的实时性,每当 Redis 重启的时候,就会读取这个 AOF 文件中的内容,用来恢复数据,AOF目前已经是 Redis 持久化的主流方式

3.1 使用 AOF

开启 AOF 功能需要设置配置:appendonly yes,默认不开启,AOF 文件名通过 appendfilename 配置(默认是 appendonly.aof),保存目录同 RDB 持久化方式一致,通过 dir 配置指定,AOF 的工作流程操作:命令写入(append)、文件同步(sync)、文件重写(rewrite)、重启加载(load)

当开启 AOF 的时候,RDB 就不再生效,启动的时候不再读取 RDB 文件的内容

AOF 工作流程

1)所有写入命令会追加到 aof_buf (缓冲区)中

2)AOF 缓冲区根据对应的策略向硬盘做同步操作

3)所i这 AOF 文件越来越大,需要定期对 AOF 文件进行重写

4)当 Redis服务器启动时,可以加载 AOF 文件进行数据恢复

3.2 文件同步

Redis 提供了多种 AOF 缓冲区同步文件策略,由参数 appendfsync 控制

 AOF 缓冲区同步文件策略

可配置值说明
always命令写⼊ aof_buf 后调用 fsync 同步,完成后返回
everysec命令写⼊a of_buf 后只执行 write 操作,不进行 fsync,每秒由同步线程进行 fsync
no命令写⼊ aof_buf 后只执行 write 操作,由 OS 控制 fsync 频率

always:写入频率最高,数据可靠性最高,性能最低,除非是非常重要的数据,否则不建议配置

everysec:(默认配置)写入频率低一些,数据可靠性也会降低一些,性能提高一些,兼顾了数据安全性和性能,理论上最多丢失1秒的数据

no:写入频率最低,数据可靠性最低,虽然性能最高,但是数据丢失风险大大增加,除非数据的重要程度很低,一般不建议配置

3.3 重写机制

随着命令不断写入 AOF,文件会越来越大,Redis 引入 AOF 重写机制压缩文件体积,AOF 文件重写是把 Redis 进程内的数据转化为写命令同步到新的 AOF 文件

 重写后的 AOF 会变小,是因为:

1)进程内已超时的数据不再写入文件

2)旧的 AOF 中的无效命令,例如 del、hdel、srem 等重写后将会删除,只需要保留数据的最终版本

3)多条写操作会合并成一条,例如 set key 111、set key 222、set key 333变成 set key 333,而lpush list a、lpush list b、lpush list c合并成 lpush list a b c

AOF 重写过程可以手动触发和自动触发

1)手动触发:调用 bgrewriteaof 命令

2)自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机

auto-aof-rewrite-min-size:表示触发重写时 AOF 的最小文件大小,默认为 64 MB

auto-aof-rewrite-percentage:代表当前 AOF 占用大小相比较上次重写时增加的比例

AOF 重写流程

1)执行 AOF 重写请求

如果当前进程正在执行 AOF 重写,请求不执行,如果当前进程正在执行 bgsave 操作,重写命令延迟到 bgsave 完成后执行

2)父进程执行 fork 创建子进程

3)重写

父进程 fork 之后,继续响应其他命令,在父进程 fork 的一瞬间,子进程就继承了当前父进程的内存信息,此时,父进程把 fork 之后的数据放到 aof_rewrite_buf 中,子进程把 aof 数据写完之后,会通知父进程,父进程再把 aof_rewrite_buf 缓冲区中的内容写入到新的 AOF 文件中,此时就可以用新的 AOF 文件替代旧的 AOF 文件了

RDB 对于 fork 之后的数据不再写入,而 AOF 对于 fork 之后的数据采取了 aof_rewrite_buf 缓冲区的方式处理,RDB 的理念是用来定期备份,而 AOF 则是实时备份

3.4 启动时数据恢复

当 Redis 启动时,会根据 RDB 和 AOF 文件的内容进行数据恢复

根据持久化文件进行数据恢复

当 Redis 上同时存在 AOF文件和 RDB 快照的时候,以 AOF 为主,RDB 就直接被忽略

总结:

1)Redis 提供了两种持久化方案:RDB 和 AOF

2)RDB 视为内存快照,产生的内容更为紧凑,占用空间小,恢复时速度更快,但开销大,不适合进行实时持久化,一般用于冷备和主从复制

3)AOF 视为修改命令保存,在恢复时需要重放命令,并且有重写机制来定期压缩 AOF 文件

4)RDB 和 AOF 都是用 fork 创建子进程,子进程拥有父进程内存快照的特点进行持久化

  • 15
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值