前言
本文将首先阐述上述技术分别为Redis高可用解决了哪些问题;然后详细介绍Redis的持久化技术,主要是RDB和AOF持久化方案;在介绍RDB和AOF解决方案时,不仅会介绍它们的功能和操作方法,还会介绍持久化实现的一些原理细节和需要注意的问题。最后介绍了实际使用中持久化方案的选择,以及经常遇到的问题。
目录
1.Redis高可用概述
2.Redis持久化概述
3.RDB持久化
1. 触发条件
2、执行过程
3.RDB文件
4.启动时加载
5. 常见RDB配置总结
4.AOF持久化
1.开启AOF
2、执行过程
3.启动时加载
4. 常见AOF配置总结
5. 方案选择及常见问题
1、RDB和AOF的优缺点
2. 持久化策略选择
3.fork阻塞:CPU阻塞
4.AOF追加阻塞:硬盘阻塞
5. info命令与持久化
六、总结
1.Redis高可用概述
在介绍Redis高可用之前,我们先来解释一下Redis上下文中高可用的含义。
我们知道,在Web服务器中,高可用是指服务器能够正常访问的时间,衡量标准是能够提供正常服务的时间(99.9%、99.99%、99.999%等)。然而,在Redis的背景下,高可用性的含义似乎更加广泛。除了保证正常的服务提供(如主从分离、快速容灾技术)外,还需要考虑数据容量的扩展、数据安全不丢失等。
在Redis中,实现高可用的技术主要有持久化、复制、哨兵和集群等。下面解释一下它们的功能以及它们解决什么问题。
持久化:持久化是最简单的高可用方法(有时甚至不被归类为高可用方法)。它的主要功能是数据备份,即将数据存储在硬盘上,保证进程退出时数据不会丢失。复制:复制是Redis高可用的基础。 Sentinel和Cluster都是基于复制来实现高可用的。复制主要实现数据的多机备份,以及读操作的负载均衡和简单的故障恢复。缺点:故障恢复无法自动化;写操作无法负载均衡;单台机器的存储容量有限。 Sentinel:Sentinel基于复制,实现故障自动恢复。缺点:写操作无法负载均衡;单台机器的存储容量有限。集群:Redis通过集群,解决了写操作无法负载均衡以及存储容量受单机限制的问题,实现了比较完整的高可用解决方案。 2.Redis持久化概述
持久化功能:Redis是内存数据库,数据存储在内存中。为了避免由于进程退出而导致数据永久丢失,Redis中的数据需要定期以某种形式(数据或命令)从内存保存到硬盘;当Redis下次重启时,使用持久化文件实现数据恢复。此外,可以将持久文件复制到远程位置以进行灾难备份。
Redis持久化分为RDB持久化和AOF持久化**:前者将当前数据保存到硬盘,后者将每次执行的写命令保存到硬盘(类似于MySQL的binlog); **由于 AOF 持久化,实时性能较好,即进程意外退出时丢失的数据较少。因此,AOF是目前主流的持久化方式,但是RDB持久化仍然有一席之地。
下面依次介绍RDB持久化和AOF持久化;由于Redis各个版本之间存在差异,如无特殊说明,均以Redis 3.0为准。
3.RDB持久化
RDB持久化就是将当前进程中的数据生成一个快照,保存到硬盘上(所以也叫快照持久化)。保存的文件后缀为rdb;当Redis重启时,可以读取快照文件来恢复数据。
1. 触发条件
RDB持久化的触发分为手动触发和自动触发两种。
1) 手动触发
save命令和bgsave命令都可以生成RDB文件。
save 命令会阻塞 Redis 服务器进程,直到创建 RDB 文件。当Redis服务器被阻塞时,服务器无法处理任何命令请求。
图像
bgsave命令会创建一个子进程,该子进程将负责创建RDB文件,而父进程(即Redis主进程)将继续处理请求。
图像
此时服务器执行日志如下:
图像
bgsave命令执行过程中,只有fork子进程才会阻塞服务器。至于save命令,整个过程会阻塞服务器。所以,save已经基本被放弃了。在线环境中必须杜绝使用 save。下文仅介绍bgsave命令。 。另外,在自动触发RDB持久化时,Redis也会选择bgsave而不是save进行持久化;下面介绍自动触发RDB持久化的条件。
2) 自动触发
节省百万
自动触发最常见的情况是通过配置文件中的save mn,指定m秒内发生n次变化时触发bgsave。
例如,查看redis的默认配置文件(Linux下redis根目录下的redis.conf),可以看到如下配置信息:
图像
save 900 1的含义是:当时间达到900秒时,如果redis数据至少发生过一次变化,就会执行bgsave; save 300 10 和 save 60 10000 是相同的。当满足三个保存条件中的任何一个时,bgsave将被调用。
save mn的实现原理
Redis的save mn是通过serverCron函数、dirty计数器、lastsave时间戳来实现的。
serverCron是Redis服务器的周期性运行功能。默认情况下每 100 毫秒执行一次。该函数维护服务器的状态。它的任务之一是检查是否满足save mn配置的条件。如果是,则执行 bgsave。
脏计数器是 Redis 服务器维护的状态。它记录了自上次执行bgsave/save命令以来服务器状态被修改了多少次(包括添加、删除和修改)。当save/bgsave执行完成后,dirty会被重置为0。。
例如,如果Redis执行set mykey helloworld,则脏值将+1;如果执行sadd myset v1 v2 v3,脏值将+3;请注意,dirty 记录的是服务器所做的修改次数,而不是客户端执行的次数。有多少命令用于修改数据。
Lastsave 时间戳也是 Redis 服务器维护的状态。它记录了上次成功执行save/bgsave的时间。
save mn的原理如下:每100ms执行一次serverCron函数; serverCron函数中,遍历save mn配置的保存条件,只要满足一个条件,就执行bgsave。对于每个save mn条件,只有同时满足以下两个条件才满足:
(1) 当前保存时间 > m
(2)脏>=n
保存mn执行日志
下图为save mn触发bgsave执行时服务器打印日志:
图像
其他自动触发机制
除了save mn之外,还有一些其他情况会触发bgsave:
图像
2、执行过程
前面介绍了触发bgsave的条件。下面解释一下bgsave命令的执行过程,如下图(图片来源:):
图像
图中5步执行的操作如下:
1)Redis父进程首先判断当前执行的是save还是bgsave/bgrewriteaof的子进程(这个命令后面会详细介绍)。如果正在执行,bgsave命令会直接返回。 bgsave/bgrewriteaof的子进程不能同时执行,主要是出于性能考虑:两个并发子进程同时执行大量磁盘写操作,可能会导致严重的性能问题。
2) 父进程执行fork操作创建子进程。在此过程中,父进程被阻塞,Redis 无法执行客户端的任何命令。
3) 父进程fork后,bgsave命令返回“后台保存开始”消息,不再阻塞父进程,可以响应其他命令。
4) 子进程创建RDB文件,根据父进程的内存快照生成临时快照文件,完成后原子地替换原始文件。
5) 子进程向父进程发送信号表示完成,父进程更新统计信息。
3.RDB文件
RDB 文件是压缩的二进制文件。以下是有关 RDB 文件的一些详细信息。
存储路径
RDB文件的存储路径可以在启动前配置,也可以通过命令动态设置。
配置:dir配置指定目录,dbfilename指定文件名。默认是Redis根目录下的dump.rdb文件。
动态设置:Redis启动后,还可以动态修改RDB存储路径,这在磁盘损坏或者空间不足时非常有用;执行命令为 config set dir {newdir} 和 config set dbfilename {newFileName}。如下图(Windows环境):
图像
RDB 文件格式
RDB文件格式如下图所示(图片来源:《Redis设计与实现》):
图像
各个字段的含义解释如下:
1) REDIS:常量,保存“REDIS”的5个字符。
2) db_version:RDB文件的版本号。注意,这不是Redis的版本号。
3) SELECTDB 0对:代表一个完整的数据库(0号数据库)。同样,SELECTDB 3对代表完整的3号数据库;只有当数据库中有键值对时,RDB文件才会有数据库的信息。 (上图Redis中只有数据库0和3有键值对);如果Redis中所有数据库都没有键值对,则这部分直接省略。其中:SELECTDB是一个常量,表示后面跟的是数据库号; 0和3是数据库编号; pairs 存储特定的键值对信息,包括 key、value 及其数据类型、内部编码、过期时间、压缩信息等。
4) EOF:常量,标记RDB文件体内容的结束。
5) check_sum:之前所有内容的校验和;当Redis加载RBD文件时,会计算之前的校验和并与check_sum值进行比较,以确定文件是否损坏。
压缩
Redis默认使用LZF算法来压缩RDB文件。压缩虽然比较耗时,但是可以大大减小RDB文件的大小,因此默认开启压缩;可以使用以下命令将其关闭:
图像
需要注意的是,RDB文件的压缩不是对整个文件进行压缩,而是对数据库中的字符串进行压缩,并且只有当字符串达到一定长度(20字节)时才会进行压缩。
4.启动时加载
RDB文件的加载是在服务器启动时自动执行的,没有特殊的命令。但由于 AOF 的优先级较高,当 AOF 开启时,Redis 会优先加载 AOF 文件来恢复数据;只有当AOF关闭时,Redis服务器启动时才会检测到RDB文件并自动加载。服务器在加载 RDB 文件时会被阻塞,直到加载完成。
自动加载的执行情况可以在Redis启动日志中看到:
图像
当Redis加载RDB文件时,它会验证RDB文件。如果文件损坏,日志中会打印错误,Redis将无法启动。
5. 常见RDB配置总结
以下是RDB常用的配置项,以及默认值;之前介绍过的这里不再详细介绍。
4.AOF持久化
RDB持久化将进程数据写入文件,而AOF持久化(Append Only File持久化)则将Redis执行的每个写命令记录到一个单独的日志文件中(有点像MySQL的binlog);当Redis重新启动时,再次执行AOF文件中的命令来恢复数据。
与RDB相比,AOF具有更好的实时性能,因此成为主流的持久化方案。
1.开启AOF
Redis服务器默认开启RDB,关闭AOF。要开启AOF,需要在配置文件中进行配置:
仅追加 是
2、执行过程
由于Redis的每条写命令都需要记录,所以不需要触发AOF。下面介绍AOF的执行过程。
AOF的执行流程包括:
1)命令追加(append)
Redis 首先将写入命令追加到缓冲区,而不是直接写入文件。这主要是为了避免每次都直接将写命令写入硬盘,导致硬盘IO成为Redis负载的瓶颈。
命令append的格式是Redis命令请求的协议格式。它是纯文本格式,具有兼容性好、可读性强、易于处理、操作简单、避免二次开销等优点;具体格式不再赘述。 AOF文件中,除了用于指定数据库的select命令(如select 0选择0号数据库)是Redis添加的外,其他都是客户端发送的写入命令。
2)文件写入(write)和文件同步(sync)
Redis为AOF缓存区域提供了多种同步文件策略。该策略涉及操作系统的write函数和fsync函数。描述如下:
为了提高文件写入效率,在现代操作系统中,当用户调用write函数向文件写入数据时,操作系统通常会将数据暂时存储在内存缓冲区中。当缓冲区被填满或超过指定的时间限制后,缓冲区数据才真正写入硬盘。这样的操作虽然提高了效率,但也带来了安全问题:如果计算机关机,内存缓冲区中的数据就会丢失;因此,系统还提供了fsync、fdatasync等同步函数,可以强制操作系统立即保存缓冲区中的数据。将数据写入硬盘,保证数据安全。
AOF缓冲区的同步文件策略由参数appendfsync控制。各个值的含义如下:
3)文件重写(rewrite)
随着时间的推移,Redis服务器执行的写命令越来越多,AOF文件会变得越来越大;过大的AOF文件不仅会影响服务器的正常运行,还会导致数据恢复时间过长。
文件重写是指定期重写AOF文件,以减少AOF文件的大小。需要注意的是,AOF重写是将Redis进程中的数据转换为写入命令并同步到新的AOF文件中;不会对旧的 AOF 文件执行任何读取或写入操作!
关于文件重写还有一点需要注意的是:对于AOF持久化来说,虽然强烈建议进行文件重写,但并不是必须的;即使不重写文件,数据也可以在Redis时间导入中持久化和启动;因此,在一些实现中,会关闭自动文件重写,然后通过定时任务在每天的某个时间定时执行。
文件重写之所以能够压缩AOF文件是因为:
图像
从上面可以看出,由于AOF重写后执行的命令较少,因此文件重写不仅可以减少文件占用的空间,还可以加快恢复速度。
文件重写触发器
文件重写触发分为手动触发和自动触发:
手动触发:直接调用bgrewriteaof命令。这个命令的执行有点类似于bgsave:都是fork子进程来执行特定的工作,并且它们只在fork期间阻塞。
图像
此时服务器执行日志如下:
图像
自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数以及aof_current_size和aof_base_size状态确定触发时间。
本网站每日更新互联网创业教程,一年会员只需98,全站资源免费下载点击查看会员权益