redis 是如何作持久化的

Redis 是一个键值对数据库服务器。基于内存存储数据,它常被用作缓存数据库,用来替代 memcached。官网:https://redis.io/mysql

什么是持久化?

持久化,指将数据存储到可永久保存的设备中。
例如,将内存中的数据存储到可永久保存的硬盘中。redis

为何须要持久化?

  1. Redis 基于内存存储,内存掉电后数据会丢失
  2. 内存比硬盘贵得多,因此须要将一些不能丢失的数据持久化到硬盘上

甚至,一些特别重要的数据,是须要存到 MySQL 的。
Redis 自己有持久化,为何还要写进 mysql 呢?:https://www.v2ex.com/t/219551sql

如何作持久化?

Redis 提供了四种持久化方式:数据库

  1. RDB(Redis database|Snapshoting)
  2. AOF(Append-Only file)
  3. VM(虚拟内存)被淘汰了
  4. Diskstore 不了解

此次主要说的是 RDB 和 AOF 两种持久化方式。缓存

RDB 持久化

RDB:Redis database 的简称。一看这个,你就应该能猜到,这是 Redis 的默认持久化方式。服务器

RDB 中持久化生成的是一个通过压缩的二进制文件。app

RDB 持久化时机:

  1. 在客户端执行 SAVE 或者 BGSAVE
  2. 根据配置规则自动快照(稍后会讲到)
  3. 执行 FLUSHALL 命令
  4. 执行复制(replication)

RDB 持久化步骤:

  1. fork 复制出一个父进程的副本子进程
  2. 子进程将内存中的数据写入到硬盘中的临时文件
  3. 将临时文件替换旧的 rdb 文件

图片

自动间隔保存(配置规则):

save 900 1     # 每900秒检查一次,若是有1条数据修改了,那么执行 rdb
save 300 10    # 每300秒检查一次,若是有10条数据修改了,那么执行 rdb
save 60 10000  # 每60秒检查一次,若是有10000条数据修改了,那么执行 rdb

RDB 文件还原

服务器启动时,会直接载入 RDB 文件。
可是若是 AOF 文件存在,则会载入 AOF 文件。AOF 文件载入过程会在后文中描述memcached

AOF 持久化

AOF 是 Append Only File 的简称。.net

AOF 经过保存客户端传过来的写命令来记录数据库的状态。
如:设计

$3(后面是 \r\n)
SET
$3
msg
$1
5
$3
SET
$3
msg
$1
3

AOF 持久化的时机

须要在配置文件中加入:

appendonly yes

AOF 持久化的步骤

主进程进行如文章末尾所示的三个步骤:

  1. 命令追加
  2. 文件写入
  3. 文件同步

AOF 重写的时机

  1. 配置:
# 当前 AOF 文件超过上次重写时的 AOF 文件大小的百分之多少时再次进行重写
# 若是以前没有冲写过,则以启动时的 AOF 文件大小为依据。
auto-aof-rewrite-percentage 100
# 容许重写的最小值
auto-aof-rewrite-min-size 64mb
  1. 主动执行 BGREWRITEAOF 命令触发 AOF 重写。

AOF 重写步骤

若是是在客户端直接执行 REWRITEAOF ,会阻塞服务,直到重写完成,将新的 AOF 文件覆盖旧的文件。这种方式通常不会考虑。

BGREWRITEAOF 命令的执行过程如文末图片所示:

  1. 父进程写入 AOF 缓冲区和 AOF 重写缓冲区
  2. 子进程执行 AOF 重写,完成以后发送信号给父进程
  3. 父进程收到信号将 AOF 重写缓冲区的内容写入到新的 AOF 文件中,而且覆盖原有的 AOF 文件

AOF 重写是将多条命令用一条命令代替。
如上面代码所示,存储一个 msg 使用了两条命令。通过 AOF 文件重写以后,就会变成以下所示,大大减小了使用的存储空间:

$3
SET
$3
msg
$1

AOF 文件还原

AOF 文件还原的步骤以下:

  1. 建立一个伪客户端(fake client)
  2. 从 AOF 文件中分析并读取一条写命令
  3. 使用伪客户端执行写命令
  4. 一直重复步骤 2 和 3

AOF 写入与重写过程图:

图片

参考

《Redis入门指南》 《Redis设计与实现》

相关文章
相关标签/搜索