本文将先说明持久化、主存复制(及读写分离)、哨兵、以及集群几种技术分别解决了Redis高可用的什么问题;
然后详细介绍Redis的持久化技术,主要是RDB和AOF两种持久化方案;在介绍RDB和AOF方案时,不仅介绍其作用及操作方法,同时介绍持久化实现的一些原理细节及需要注意的问题。
最后,介绍在实际使用中,持久化方案的选择,以及经常遇到的问题等。
在介绍Redis高可用之前,先说明在Redis的语境中高可用的含义。
我们知道,在Web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999% 等等)。但是在Redis语境中,高可用的含义似乎要宽泛一些,除了保证提供正常服务(主存分离、快速容灾技术)还需要考虑数据容量的扩展,数据安全不会丢失等。
在Redis中,实现高可用技术主要包括持久化、主存复制、哨兵和集群,下面分别说明他们的作用以及解决了什么问题。
读写分离
)。缺陷:故障恢复无法自动化;写操作无法负载均衡;存储能力受到单机的限制
。写操作无法负载均衡;存储能力受单机限制
不支持故障恢复以及自动转移
Redis是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据永久丢失,需要定期将Redis中的数据以某种形式(数据/命令)从内存保存到磁盘;当下次Redis重启时,利用持久化文件实现数据恢复。除此之外,为了进行灾难备份,可以将持久化文件拷贝到一个远程位置;
RDB 持久化: 是指在指定的时间间隔内将内存中的数据集快照写入磁盘
,也就是 snapshot内存快照
,它恢复时再将磁盘快照文件(dump.rdb
)直接读回到内存。
实现类似照片记录效果的方式,就是把某一时刻的数据和状态以文件的形式写到磁盘上,也就是快照。这样一来即使故障宕机,快照文件也不会丢失,数据的可靠性也就得到了保证。
这个快照文件就称为RDB文件(dump.rdb
),其中,RDB就是Redis DataBase的缩写。
AOF持久化: 是指以日志的形式来记录每个写操作
,将Redis所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据。
换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次已完成数据的恢复工具。
默认情况下,redis是没有开启AOF(append of file)的。开启AOF功能需要设置配置:
appendonly yes
AOF 保存的是 appendonly.aof
文件
疑问:rdb vs aof 可否共存?如果共存以哪种方式为准?
数据恢复顺序与加载流程:在同时开启 rdb和aof 持久化时,重启时只会加载aof文件,不会加载rdb文件。
同时关闭 RDB+AOF
// 禁用rdb
save ""
// 禁用aof
appendonly no
注意在禁用rdb和aof后仍然可以使用持久化命令生成对应的持久化文件。
save
bgsave
生成rdb文件。bgrewriteaof
生成aof文件。RDB 持久化是指在指定的时间间隔内将内存中的数据快照写入磁盘,实际操作过程是 fork 一个子进程,先将数据写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
第一步: 配置文件说明
redis 6.0.16以下配置
redis 6.2 以及redis 7
第二步: 2) 操作说明
操作主要分为手动触发
和自动触发
两种方式。
方式一:自动触发
Redus 7 版本 按照 redis.conf 里配置的 save
比如 5秒修改2次
第三步:如何恢复
将备份文件(dump.rdb
) 移动到redis安装目录并启动服务器即可。
验证一:备份成功后故意使用flushdb
清空redis,看看是否可以恢复数据。
验证二:物理恢复,服务和备份分机隔离
。
备注:不可以把备份文件dump.rdb和生产redis服务器放在同一台机器,必须分开各自存储,以防生产机物理损坏后备份文件也挂了。
方式二:手动触发
redis 提供了两个命令来支持生成rdb文件,分别是 save
和 bgsave
(1)save 同步阻塞生成rdb文件 主要是在主程序执行,会阻塞当前redis服务器,直到持久化工作完成,执行save命令期间,redis不能处理其它命令,线上禁止使用
。
案例说明:
(2)bgsave 异步生成rdb文件(默认):redis会在后台异步快照操作,不阻塞
快照,同时还可以响应客户端请求,该触发方式会 fork一个子进程,由子进程复制持久化过程。
fork 是什么?
在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,尽量避免膨胀。
案例说明:
lastsave 可以通过lastsave命令获取最后一次成功执行快照的时间。
优势:
劣势:
数据丢失的案例:
kill -9
故意模拟意外宕机方式一:使用命令设置保存rdb规则的方法:redis-cli config set save ""
命令写入 (append)、文件同步(sync)、文件重写(rewrite)、重启加载 (load)。
# 每次有新命令追加到 AOF 文件时就执行一次同步 :非常慢,也非常安全
$ always
# 每秒同步一次:足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据
# 推荐(并且也是默认)的措施为每秒同步一次, 这种策略可以兼顾速度和安全性
$ everysec
# 从不同步:将数据交给操作系统来处理。更快,也更不安全的选择
$ no
策略一:同步写回Always
:每个写命令执行完立刻同步的将命令写回磁盘。
策略二:每秒写回everysec
:每个写命令执行完,只是先把日志写到 AOF文件的内存缓冲区,每隔一秒把缓冲区的内容写入磁盘。
策略三:操作系统控制写回no
:每个写命令执行完,只是先把日志写到AOF文件的内存缓冲区,由操作系统决定何时将缓冲区的内容写入磁盘。
优势:
劣势:
AOF 是存放每条写命令的,所以会不断变大,达到一定的时候,AOF做rewrite操作,会重新生成一个新的AOF文件。
文件越大,占用服务器内存越大以及 AOF 恢复要求时间越长。
为了解决这个问题,Redis新增了重写机制,当AOF文件的大小超过所设定的峰值时,Redis就会自动启动AOF文件的内容压缩,
简单说就是将对一个数据的多个命令的最终结束结果储存到AOF文件中。
重写 rewrite的作用
重写规则
RDB和AOF持久化各有优缺点,RDB会导致一段时间内的数据丢失,AOF文件会越来越大,会影响Redis的启动速度,为了同时兼顾RDB,AOF的优点,Redis在4.0版本之后
提供了混合持久化
方式。
AOF 重写时会把 Redis 的持久化数据,以 RDB 的格式写入到 AOF 文件的开头,之后的数据再以 AOF 的格式化追加的文件的末尾,如下图所示。
优点:混合持久化结合了 RDB 和 AOF 持久化的优点,开头为 RDB 的格式,使得 Redis 可以更快的启动,同时结合 AOF 的优点,有减低了大量数据丢失的风险。
缺点:AOF 文件中添加了 RDB 格式的内容,会使得 AOF 文件的可读性会很差,不容易阅读;
如果开启混合持久化,就必须使用 Redis 4.0 以及之后版本。
使用混合持久化的时候可以根据自身业务选择关闭RDB或者AOF,或者关闭持久化。
二者选择的标准,就是看是否愿意牺牲一些性能,换取更高的缓存一致性(AOF),还是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行 save 的时候,再做备份(RDB)。
注: 未来 Redis 可能会将 AOF 和 RDB 整合成单个持久化模型.