开篇
Redis作为最常用的内存数据库,通常来说数据存储在内存中,为了避免Redis服务器进程退出导致内存中的数据消失。Redis提出了持久化机制,也就是把内存中的数据保存到磁盘中,从而提高数据存储的可靠性。为此主流数据库会提供两类持久化方案,它们是“快照”存储和“日志”存储。相应地Redis提供了RDB持久化和AOF持久化与之对应。其中RDB是以快照的方式存储内存数据到磁盘上,而AOF是以日志追加的方式进行存储。下面就围绕这两种持久化方式展开如下内容:
RDB持久化
RDB是Redis Database 的缩写,其作用是在某一个时间点,将Redis存储在内存中的数据生成快照并存储到磁盘等介质上,存在这个磁盘介质上的文件就是RDB文件。“快照”顾名思义就是好像照相一样保存当时的数据,这里的RDB文件是一个二进制的文件,并且是经过压缩的。因为RDB文件是保存在硬盘中的,即使Redis服务器进程退出,甚至运行Redis服务器的计算机宕机,但只要RDB文件仍然存在,Redis服务器就可以用它来还原数据库状态。如图1 所示,可以想象Redis数据库在时间轴上有位于不同时间点的时候都有一个数据库状态,可以把它们想象成一个个切片。图上标注出两个时间点的两个数据库切片,RDB持久化做的事情就是顺着绿色箭头的方向将数据库状态的“切片”以RDB文件的形式保存到磁盘中。
图1 将数据库状态保存为RDB文件
RDB 文件结构
虽然说RDB是一个压缩过的二进制文件,但是它的文件结构也需要有基本的了解,这样有助于我们理解其发挥的作用。如表格1所示,RDB文件由5个部分组成,按照从左到右的顺序依次是:
REDIS | db_version | databases | EOF | check_sum |
---|
表格1 RDB的文件结构
如表格2所示,其表示一个databases部分为空的RDB文件:文件以"REDIS"开头,表示这是一个RDB文件,之后的"0006"表示数据库版本是第六版。因为databases为空所以这里没有数据库的信息,所以版本号之后直接跟着“EOF”常量,最后的6265312314761934562是文件的校验和。
REDIS | “0006” | EOF | 6265312314761934562 |
---|
表格2 RDB文件例子
RDB 触发机制以及流程
在认识了RDB文件的结构以后,再来看看Redis 如何触发RDB持久化操作,以及其具体流程是如何的。这里包括三部分的内容,分别是save同步方式触发、bgsave 异步方式触发以及自动配置化的方式触发。
save同步方式触发RDB持久化
如图2所示,描述了save 同步方式持久化RDB的过程:
图2 save同步方式触发RDB持久化
bgsave同步方式触发RDB持久化
如图3所示,异步方式过程如下:
图3 bgsave异步方式触发RDB持久化
自动配置化的方式触发
如图4所示,这种方式可以理解为读取配置文件的方式。看下面的三个步骤:
图4 读取配置文件进行RDB持久化
一般而言Redis的配置信息会放到redis.conf配置文件中进行存储,其包含很多内容,这里我们就RDB持久化的部分给大家做简单介绍。redis.conf文件中找到“SNAPSHOTTING”(快照)的部分。看如下几个配置项:
# 900秒内有1次修改、300秒内有10次修改、60秒内有10000次修改
#满足任何以上条件,触发RDB持久化。
save 900 1
save 300 10
save 60 10000
# 当快照操作bgsave出错时,是否停止持久化?yes 表示“是”,no表示“否”。
stop-writes-on-bgsave-error yes
# 是否压缩?yes表示“是”,no表示“否”,默认选择yes。
rdbcompression yes
# 对rdb数据进行校验, 表示写入文件和读取文件时是否开启 RDB 文件检查。
# yes表示“是”,no表示“否”,默认选择yes。
# 选择yes表示在Redis加载RDB需要检查文件是否损坏,如果存在损坏会停止启动。
rdbchecksum yes
# 设置rdb的文件名
dbfilename dump.rdb
# RDB文件的路径,如果不单独指定,默认是redis的启动路径。
dir ./
关于RDB持久化恢复Redis数据方面也比较简单,将RDB持久化文件 (例如:dump.rdb) 移动到 Redis 安装目录并启动Redis服务就可以了。可以通过 Redis 中的“CONFIG GET dir”命令获取Redis的安装目录。
由于RDB是一个压缩的二进制文件,其代表Redis在某一个时间点上的快照。其适合数据库备份和全量复制的场景。比如定期给数据库进行备份,把RDB文件拷贝到其他的服务器上,以及用于灾备。同样是因为压缩的原因,RDB的加载速度比AOF也要快。
AOF持久化
上面介绍了RDB的执行方式和流程,这种方式没有办法做到实时持久化的要求。因为无论是save还是bgsave每次运行都要消耗大量的资源(CPU、内存、磁盘)。随着数据库本身容量的增加每次备份的数据量也随之增加。同时RDB是二进制保存,当Redis版本演进过程中有多个格式的RDB版本,会存在老版本RDB与新版本格式兼容的问题。正式因为RDB的这些问题,Redis提出了AOF的持久化方式。AOF(append only file),是以日志的方式记录每次写入的命令,在Redis Server启动的时候会重新执行AOF文件中的命令,从而达到恢复数据的目的。AOF可以解决数据持久化的实时性问题,也是当前Redis主流的持久化方式。
AOF持久化流程
上面提到了AOF持久化的过程就是日志不断追加的过程,这里通过图5 给大家介绍具体流程:
图5 AOF 处理流程图
AOF缓冲区同步文件策略
上面提到了Redis 会将命令先写入到AOF缓冲区,再写入AOF文件。这里介绍一下AOF缓冲区同步文件的三个策略。
AOF 重写
AOF缓冲区会将Redis Client请求的命令源源不断地同步到AOF文件中,同时AOF文件会不断增大,这里就需要AOF重写。AOF重写就是把Redis进程内的数据转化为写命令同步到新的AOF文件的过程。其目的就是使重写后的AOF文件变得更小:
AOF重写不仅降低了文件的占用空间,同时更小的AOF也可以更快地被Redis加载。
说完了AOF重写的定义以后,下面来看看AOF重写的流程。一般而言有两种方式可以执行重写操作,分别是:bgrewriteaof 命令和AOF重写配置。
bgrewriteaof命令重写
如图6 所示,整个执行过程由三步组成:
图6 AOF重写流程图
AOF配置重写
实际上是通过AOF的配置文件中的配置值来确定重写的时机。配置如下:
通过上面的配置可以得到AOF重写的机制如下:
由于Redis的配置文件中RDB是默认配置。AOF需要手动开启。
需要到Redis的配置文件redis.conf中进行如下设置。
#开启AOF模式 ,yes表示“开启AOF模式”。
appendonly yes
与RDB持久化文件恢复数据一样,只需要将AOF文件 移动到 Redis 安装目录,并启动Redis服务就可以在Redis启动的时候加载AOF文件恢复数据了。
通过上面对AOF的描述可以看出,AOF具有数据完整,安全性高(秒级数据丢失)等优点。同时AOF文件以追加日志文件的形式存在,且写入操作是以Redis协议格式保存的,因此其内容是可读性强,适合误删时的紧急恢复。不过,相对于RDB而言其文件尺寸较大,会占用更多Redis启动加载数据的时间。
RDB和AOF的比较
前面介绍了RDB和AOF两种机制,这里将它们做一个简单对比。
总结
本文从为什么需要数据库持久化作为切入点,谈到Redis中的两类数据库持久化机制:RDB和AOF。其中针对RDB持久化通过介绍RDB文件结构、触发持久化的机制和流程进行了阐述。其包括:save同步方式、bgsave同步方式和自动配置方式。针对AOF持久化,通过AOF持久化流程、缓冲区同步文件策略以及AOF重写机制进行了介绍。其中缓冲区同步策略包括:always策略、everysec策略和no策略。
把本文学习笔记的思维导图分享如下。
END