前言

本文将首先阐述上述技术分别为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),可以看到如下配置信息:

重启redis缓存会清掉吗_redis重启_重启redis集群

图像

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命令的执行过程,如下图(图片来源:):

重启redis集群_redis重启_重启redis缓存会清掉吗

图像

图中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期间阻塞。

图像

此时服务器执行日志如下:

重启redis缓存会清掉吗_redis重启_重启redis集群

图像

自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数以及aof_current_size和aof_base_size状态确定触发时间。

本网站每日更新互联网创业教程,一年会员只需98,全站资源免费下载点击查看会员权益

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注