前言
Redis作为高性能的内存数据存储,其核心数据驻留于易失性内存中。为了在保障卓越性能的同时,满足实际生产环境对数据可靠性和服务高可用性的严苛要求,Redis提供了相辅相成的三大核心机制:持久化、主从复制和哨兵模式。
这三者构成了Redis从单点数据存储迈向健壮、可靠分布式系统的基石:
持久化解决了数据的持久存储问题。它通过将内存数据定期或实时保存至磁盘(RDB快照与AOF日志),确保在Redis进程重启后数据得以恢复,是数据安全的最后防线。
主从复制解决了数据的多副本备份与读写分离问题。它允许将一台主节点(Master)的数据异步复制到多个从节点(Slave),实现了数据冗余、负载分流,并为故障转移提供了数据基础。
哨兵模式解决了服务的高可用性与自动故障转移问题。哨兵是一个独立的分布式监控系统,它能自动监测主从节点的健康状态,并在主节点故障时,通过投票机制自动选举并提升一个从节点为新的主节点,通知客户端连接新的主节点,从而实现服务不间断。
简而言之,三者协同工作,构建了一个稳固的Redis服务体系:持久化保障数据不丢,主从复制保障数据多备并扩展读能力,哨兵模式则保障服务在故障时能自动切换、永不中断。理解这三者的原理与配置,是设计和运维一个可用于生产环境的Redis集群的关键前提。
持久化
什么是持久化
持久化是最简单的高可用方法,主要作用是数据备份,即将数据存
储在硬盘,保证数据不会因进程退出而丢失。
rdb持久化
rdb快照
定期把数据快照保存到磁盘
优点:文件小,恢复快。
缺点:可能丢几分钟数据。
触发条件
手动触发:(使用bgsave)
在redis交互页面输入:bgsave或者save即可触发快照,生成rdb文件
save命令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在Redis服务器阻塞期间,服务器不能处理任何命令请求。
而bgsave命令会创建一个子进程,由子进程来负责创建RDB文件,父进程(即Redis主进程)则继续处理请求。
总结:因此save已基本被废弃,线上环境要杜绝save的使用。
自动触发:
vim /etc/redis/6379.conf
save m n --219行--以下三个save条件满足任意一个时,都会引起bgsave的调用 save 900 1 :当时间到900秒时,如果redis数据发生了至少1次变化,则执行bgsave save 300 10 :当时间到300秒时,如果redis数据发生了至少10次变化,则执行bgsave save 60 10000 :当时间到60秒时,如果redis数据发生了至少10000次变化,则执行bgsave --254行--指定RDB文件名 dbfilename dump.rdb --264行--指定RDB文件和AOF文件所在目录 dir /var/lib/redis/6379 --242行--是否开启RDB文件压缩 rdbcompression yes自动触发最常见的情况是在配置文件中通过save m n,指定当m秒内发生n次变化时,会触发bgsave。
其他触发快照的场景:
shutdown # redis服务优雅退出,会触发快照 stop # redis被关闭,可能会触发快照,不稳定 exit # 退出redis-cli,服务没关闭 quit # 退出redis-cli,服务没关闭bgsave流程原理
- Redis父进程首先判断:当前是否在执行save,或bgsave/bgrewriteaof的子进程,如果在执行则bgsave命令直接返回。 bgsave/bgrewriteaof的子进程不能同时执行,主要是基于性能方面的考虑:两个并发的子进程同时执行大量的磁盘写操作,可能引起严重的性能问题。
- 父进程执行fork操作创建子进程,这个过程中父进程是阻塞的,Redis不能执行来自客户端的任何命令
- 父进程fork后,bgsave命令返回”Background saving started”信息并不再阻塞父进程,并可以响应其他命令
- 子进程创建RDB文件,根据父进程内存快照生成临时快照文件,完成后对原有文件进行原子替换
- 子进程发送信号给父进程表示完成,父进程更新统计信息
2.4、rdb文件加载
RDB文件的载入工作是在服务器启动时自动执行的,并没有专门的命令。但是由于AOF的优先级更高,因此当AOF开启时,Redis会优先载入 AOF文件来恢复数据;只有当AOF关闭时,才会在Redis服务器启动时检测RDB文件,并自动载入。服务器载入RDB文件期间处于阻塞状态,直到载入完成为止。
Redis载入RDB文件时,会对RDB文件进行校验,如果文件损坏,则日志中会打印错误,Redis启动失败。
AOF持久化
aof介绍
RDB持久化是将进程数据写入文件,而AOF持久化,则是将Redis执行的每次写、删除命令记录到单独的日志文件中,查询操作不会记录; 当Redis重启时再次执行AOF文件中的命令来恢复数据。 与RDB相比,AOF的实时性更好,因此已成为主流的持久化方案。
开启AOF
# Redis服务器默认开启RDB,关闭AOF;要开启AOF,需要在配置文件中配置 vim /etc/redis/6379.conf --700行--修改,开启AOF appendonly yes --704行--指定AOF文件名称 appendfilename "appendonly.aof" --796行--是否忽略最后一条可能存在问题的指令 aof-load-truncated yes /etc/init.d/redis_6379 restartbgrewriteaof工作原理
AOF的执行流程包括:
命令追加(append):将Redis的写命令追加到缓冲区aof_buf;
文件写入(write)和文件同步(sync):根据不同的同步策略将aof_buf中的内容同步到硬盘;
文件重写(rewrite):定期重写AOF文件,达到压缩的目的。
文件重写流程
文件重写流程
(1)Redis父进程首先判断当前是否存在正在执行bgsave/bgrewriteaof的子进程,如果存在则 bgrewriteaof命令直接返回,如果存在 bgsave命令则等bgsave执行完成后再执行。 (2)父进程执行fork操作创建子进程,这个过程中父进程是阻塞的。 (3.1)父进程fork后,bgrewriteaof命令返回”Background append only file rewrite started”信息并不再阻塞父进程, 并可以响应其他命令。Redis的所有写命令依然写入AOF缓冲区,并根据 appendfsync策略同步到硬盘,保证原有AOF机制的正确。 (3.2)由于fork操作使用写时复制技术,子进程只能共享fork操作时的内存数据。由于父进程依然在响应命 令,因此Redis使用AOF重写缓冲区(aof_rewrite_buf)保存这部分数据,防止新AOF文件生成期间丢失这 部分数据。也就是说,bgrewriteaof执行期间,Redis的写命令同时追加到aof_buf和aof_rewirte_buf 两个缓冲区。 (4)子进程根据内存快照,按照命令合并规则写入到新的AOF文件。 (5.1)子进程写完新的AOF文件后,向父进程发信号,父进程更新统计信息,具体可以通过info persistence查看。 (5.2)父进程把AOF重写缓冲区的数据写入到新的AOF文件,这样就保证了新AOF文件所保存的数据库状态和 服务器当前状态一致。 (5.3)使用新的AOF文件替换老文件,完成AOF重写aof文件加载
当AOF开启时,Redis启动时会优先载入AOF文件来恢复数据;只有当AOF关闭时,才会载入RDB文件恢复数据。
当AOF开启,但AOF文件不存在时,即使RDB文件存在也不会加载。
Redis载入AOF文件时,会对AOF文件进行校验,如果文件损坏,则日志中会打印错误,Redis启动失败。但如果是AOF文件结尾不完整(机器突然宕机等容易导致文件尾部不完整),且aof-load-truncated参数开启,则日志中会输出警告,Redis忽略掉AOF文件的尾部,启动成功。aof-load-truncated参数默认是开启的。
rdb和aof的比较
rdb:(类似完全备份)
优点:RDB文件紧凑,体积小,网络传输快,适合全量复制;恢复速度比AOF快很多。当然,与AOF相比,RDB最重要的优点之一是对性能的影响相对较小。 缺点:RDB文件的致命缺点在于其数据快照的持久化方式决定了必然做不到实时持久化,而在数据越来越重要的今天,数据的大量丢失很多时候是无法接受的,因此AOF持久化成为主流。此外,RDB文件需要满足特定格式,兼容性差(如老版本的Redis不兼容新版本的RDB文件)。 对于RDB持久化,一方面是bgsave在进行fork操作时Redis主进程会阻塞,另一方面,子进程向硬盘写数据也会带来IO压力aof:
与RDB持久化相对应,AOF的优点在于支持秒级持久化、兼容性好,缺点是文件大、恢复速度慢、对性能影响大。 对于AOF持久化,向硬盘写数据的频率大大提高(everysec策略下为秒级),IO压力更大,甚至可能造成AOF追加阻塞问题。 AOF文件的重写与RDB的bgsave类似,会有fork时的阻塞和子进程的IO压力问题。相对来说,由于AOF向硬盘中写数据的频率更高,因此对 Redis主进程性能的影响会更大。主从复制
介绍
一主多从,主写从读。
主从复制是高可用Redis的基础,哨兵和集群都是在主从复制基础上实现高可用的。
主从复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复。
缺陷:故障恢复无法自动化;写操作无法负载均衡;存储能力受到单机的限制。
作用
- 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务 (即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
- 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。
流程(重点)
1)若启动一个Slave机器进程,则它会向Master机器发送一个“sync command”命令,请求同步连 接。 (2)无论是第一次连接还是重新连接,Master机器都会启动一个后台进程,将数据快照保存到数据文 件中(执行rdb操作),同时Master还会记录修改数据的所有命令并缓存在数据文件中。 (3)后台进程完成缓存操作之后,Master机器就会向Slave机器发送数据文件,Slave端机器将数据文 件保存到硬盘上,然后将其加载到内存中,接着Master机器就会将修改数据的所有操作一并发送给 Slave端机器。若Slave出现故障导致宕机,则恢复正常后会自动重新连接。 (4)Master机器收到Slave端机器的连接后,将其完整的数据文件发送给Slave端机器,如果Mater同时 收到多个Slave发来的同步请求,则Master会在后台启动一个进程以保存数据文件,然后将其发送给所 有的Slave端机器,确保所有的Slave端机器都正常。哨兵模式
介绍
主机宕机,自动切换到从机。
原理
哨兵(sentinel):是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的 Master并将所有slave连接到新的 Master。所以整个运行哨兵的集群的数量不得少于3个节点。
作用
哨兵结构由两部分组成,哨兵节点和数据节点:节点,不存储数据。
- 监控:哨兵会不断地检查主节点和从节点是否运作正常。
- 自动故障转移:当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其它从节点改为复制新的主节点。
- 通知(提醒):哨兵可以将故障转移的结果发送给客户端。
- 哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的redis
- 数据节点:主节点和从节点都是数据节点。
故障转移机制
- 由哨兵节点定期监控发现主节点是否出现了故障每个哨兵节点每隔1秒会向主节点、从节点及其它哨兵节点发送一次ping命令做一次心跳检测。如果主节点在一定时间范围内不回复或者是回复一个错误消息,那么这个哨兵就会认为这个主节点主观下线了(单方面的)。当超过半数哨兵节点认为该主节点主观下线了,这样就客观下线了。
- 当主节点出现故障,此时哨兵节点会通过Raft算法(选举算法)实现选举机制共同选举出一个哨兵节点为leader,来负责处理主节点的故障转移和通知。所以整个运行哨兵的集群的数量不得少于3个节点。
- 由leader哨兵节点执行故障转移,过程如下:
- 将某一个从节点升级为新的主节点,让其它从节点指向新的主节点;
- 若原主节点恢复也变成从节点,并指向新的主节点;
- 通知客户端主节点已经更换。
需要特别注意的是,客观下线是主节点才有的概念;如果从节点和哨兵节点发生故障,被哨兵主观下线后,不会再有后续的客观下线和故障转移操作。
主节点的选举
- 过滤掉不健康的(已下线的),没有回复哨兵 ping 响应的从节点。
- 选择配置文件中从节点优先级配置最高的。(replica-priority,默认值为100)
- 选择复制偏移量最大,也就是复制最完整的从节点。
哨兵的启动依赖于主从模式,所以须把主从模式安装好的情况下再去做哨兵模式
总结
Redis数据可靠性与高可用性三大支柱
为实现生产环境所需的健壮性,Redis的核心架构围绕三大支柱构建,它们环环相扣,层层递进:
- 持久化:数据的“保险箱
- 核心目的:将内存中的数据保存到磁盘,防止进程重启导致数据完全丢失。
- 实现方式:RDB(定时快照,恢复快)与`AOF`(记录每步操作,数据更安全),通常结合使用。
- 主从复制:服务的“后备军
- 核心目的:创建数据的多个实时副本,实现数据冗余、读写分离和读扩展。
- 实现方式:一主多从,数据从主节点异步复制到所有从节点,为高可用奠定基础。
- 哨兵模式:系统的“监护人与调度员”
- 核心目的:提供自动故障转移,实现服务高可用。
- 实现方式:独立的哨兵集群监控所有节点,主节点故障时,能自动选举新主并通知客户端,实现服务不间断。
三者关系精炼:
- 持久化为数据存底,是基础。
- 主从复制利用副本扩展服务能力与可靠性,是骨架。
- 哨兵模式在上述骨架之上,实现了自动化的故障恢复,是保障持续服务的大脑。
最终目标:三者协同,将Redis从一个高性能的内存缓存,转变为一个具备数据持久化、负载分担和自动容灾能力的生产级数据存储服务。
这个总结突出了每个组件的核心角色和它们如何协同工作,便于快速理解和记忆。