redis 是如何做持久化的
程序员文章站
2022-03-16 17:27:28
Redis 是一个键值对数据库服务器。基于内存存储数据,它常被用做缓存数据库,用来替代 memcached。官网: "https://redis.io/" 什么是持久化? 持久化,指将数据存储到可永久保存的设备中。 例如,将内存中的数据存储到可永久保存的硬盘中。 为什么需要持久化? 1. Redis ......
redis 是一个键值对数据库服务器。基于内存存储数据,它常被用做缓存数据库,用来替代 memcached。官网:
什么是持久化?
持久化,指将数据存储到可永久保存的设备中。
例如,将内存中的数据存储到可永久保存的硬盘中。
为什么需要持久化?
- redis 基于内存存储,内存掉电后数据会丢失
- 内存比硬盘贵得多,所以需要将一些不能丢失的数据持久化到硬盘上
甚至,一些特别重要的数据,是需要存到 mysql 的。
redis 本身有持久化,为什么还要写进 mysql 呢?:
如何做持久化?
redis 提供了四种持久化方式:
- rdb(redis database|snapshoting)
- aof(append-only file)
vm(虚拟内存)被淘汰了diskstore 不了解
这次主要说的是 rdb 和 aof 两种持久化方式。
rdb 持久化
rdb:redis database 的简称。一看这个,你就应该能猜到,这是 redis 的默认持久化方式。
rdb 中持久化生成的是一个经过压缩的二进制文件。
rdb 持久化时机:
- 在客户端执行 save 或者 bgsave
- 根据配置规则自动快照(稍后会讲到)
- 执行 flushall 命令
- 执行复制(replication)
rdb 持久化步骤:
- fork 复制出一个父进程的副本子进程
- 子进程将内存中的数据写入到硬盘中的临时文件
- 将临时文件替换旧的 rdb 文件
自动间隔保存(配置规则):
save 900 1 # 每900秒检查一次,如果有1条数据修改了,那么执行 rdb save 300 10 # 每300秒检查一次,如果有10条数据修改了,那么执行 rdb save 60 10000 # 每60秒检查一次,如果有10000条数据修改了,那么执行 rdb
rdb 文件还原
服务器启动时,会直接载入 rdb 文件。
但是如果 aof 文件存在,则会载入 aof 文件。aof 文件载入过程会在后文中描述
aof 持久化
aof 是 append only file 的简称。
aof 通过保存客户端传过来的写命令来记录数据库的状态。
如:
$3(后面是 \r\n) set $3 msg $1 5 $3 set $3 msg $1 3
aof 持久化的时机
需要在配置文件中加入:
appendonly yes
aof 持久化的步骤
主进程进行如文章末尾所示的三个步骤:
- 命令追加
- 文件写入
- 文件同步
aof 重写的时机
- 配置:
# 当前 aof 文件超过上次重写时的 aof 文件大小的百分之多少时再次进行重写 # 如果之前没有冲写过,则以启动时的 aof 文件大小为依据。 auto-aof-rewrite-percentage 100 # 允许重写的最小值 auto-aof-rewrite-min-size 64mb
- 主动执行 bgrewriteaof 命令触发 aof 重写。
aof 重写步骤
如果是在客户端直接执行 rewriteaof ,会阻塞服务,直到重写完成,将新的 aof 文件覆盖旧的文件。这种方式一般不会考虑。
bgrewriteaof 命令的执行过程如文末图片所示:
- 父进程写入 aof 缓冲区和 aof 重写缓冲区
- 子进程执行 aof 重写,完成之后发送信号给父进程
- 父进程收到信号将 aof 重写缓冲区的内容写入到新的 aof 文件中,并且覆盖原有的 aof 文件
aof 重写是将多条命令用一条命令代替。
如上面代码所示,存储一个 msg 使用了两条命令。经过 aof 文件重写之后,就会变成如下所示,大大减少了使用的存储空间:
$3 set $3 msg $1
aof 文件还原
aof 文件还原的步骤如下:
- 创建一个伪客户端(fake client)
- 从 aof 文件中分析并读取一条写命令
- 使用伪客户端执行写命令
- 一直重复步骤 2 和 3
aof 写入与重写过程图: