Redis作为一款高性能的键值对存储系统,在缓存、数据库等场景中被广泛应用。然而,在传统的主从复制架构中,仍然存在一些问题,特别是在主节点故障时的处理上。为了解决这些问题,Redis引入了哨兵机制,本文将详细介绍Redis哨兵机制的概念、工作原理以及如何搭建一个哨兵系统。
1. 哨兵机制的由来
在传统的Redis主从复制架构中,主要存在两个问题:
- 主节点故障时,需要手动进行主备切换,这个过程复杂且需要人工参与,无法保证故障恢复的时效性。
- 虽然主节点可以将读压力分散到从节点,但写压力和存储压力仍然集中在主节点,受到单机性能的限制。
哨兵机制主要解决了第一个问题,即高可用性问题。它能够在主节点故障时自动完成故障发现和故障转移,并通知应用程序,从而实现真正的高可用。
2. 哨兵机制概述
Redis的哨兵机制是一个分布式系统,包含多个哨兵节点和Redis数据节点。每个哨兵节点会监控数据节点和其他哨兵节点。当发现节点不可达时,哨兵会对该节点进行下线标识。如果下线的是主节点,哨兵们会进行"协商",当大多数哨兵对主节点不可达达成共识后,它们会选举出一个领导者来完成自动故障转移,并实时通知Redis客户端。整个过程是完全自动的,无需人工干预。
3. 搭建哨兵系统
接下来,我们将使用Docker来搭建一个Redis哨兵环境,包括3个数据节点(1主2从)和3个哨兵节点。
3.1 搭建数据节点
首先,我们需要创建一个docker-compose.yml
文件来定义数据节点:
version: '3.7'
services:
master:
image: 'redis:5.0.9'
container_name: redis-master
restart: always
command: redis-server --appendonly yes
ports:
- 6379:6379
slave1:
image: 'redis:5.0.9'
container_name: redis-slave1
restart: always
command: redis-server --appendonly yes --slaveof redis-master 6379
ports:
- 6380:6379
slave2:
image: 'redis:5.0.9'
container_name: redis-slave2
restart: always
command: redis-server --appendonly yes --slaveof redis-master 6379
ports:
- 6381:6379
这个配置文件定义了三个服务:一个主节点和两个从节点。每个节点都使用Redis 5.0.9镜像,并启用了AOF持久化。从节点通过--slaveof
参数指定了主节点的地址和端口。
使用以下命令启动数据节点:
sudo docker-compose up -d
3.2 搭建哨兵节点
接下来,我们需要为哨兵节点创建配置文件。在redis-sentinel
目录中创建三个相同内容的配置文件(sentinel1.conf
, sentinel2.conf
, sentinel3.conf
):
bind 0.0.0.0
port 26379
sentinel monitor redis-master redis-master 6379 2
sentinel down-after-milliseconds redis-master 1000
这个配置指定了哨兵监听的主节点信息,以及判断主节点失效的条件。
然后,创建另一个docker-compose.yml
文件来定义哨兵节点:
version: '3.7'
services:
sentinel1:
image: 'redis:5.0.9'
container_name: redis-sentinel-1
restart: always
command: redis-sentinel /etc/redis/sentinel.conf
volumes:
- ./sentinel1.conf:/etc/redis/sentinel.conf
ports:
- 26379:26379
sentinel2:
image: 'redis:5.0.9'
container_name: redis-sentinel-2
restart: always
command: redis-sentinel /etc/redis/sentinel.conf
volumes:
- ./sentinel2.conf:/etc/redis/sentinel.conf
ports:
- 26380:26379
sentinel3:
image: 'redis:5.0.9'
container_name: redis-sentinel-3
restart: always
command: redis-sentinel /etc/redis/sentinel.conf
volumes:
- ./sentinel3.conf:/etc/redis/sentinel.conf
ports:
- 26381:26379
networks:
default:
external:
name: redis-data_default
使用以下命令启动哨兵节点:
sudo docker-compose up -d
4. 哨兵机制的工作原理
哨兵机制的工作流程主要包括以下几个步骤:
4.1 主观下线
当主节点宕机时,与主节点和哨兵之间的心跳包通信中断。此时,每个哨兵节点会将主节点标记为主观下线(Subjective Down, SDown),并投票表示故障。
4.2 客观下线
当故障得票数达到或超过配置的法定票数时,主节点被认定为客观下线(Objective Down, ODown)。
4.3 选举哨兵leader
为了协调选举新主节点的工作,哨兵节点们需要先选出一个leader。这个过程使用了Raft算法:
- 每个哨兵节点向其他所有哨兵节点发起"拉票请求"。
- 收到请求的节点会回复"投票响应",可能投票或不投票。
- 如果某个哨兵获得超过半数的票,它就成为leader。
4.4 选举新主节点
leader哨兵负责从从节点中选择一个作为新的主节点。选择标准如下:
- 优先级高(配置项slave-priority或replica-priority值小)的优先。
- 复制偏移量(replication offset)大的优先。
- 运行ID(run id)小的优先。
4.5 故障转移
选出新主节点后,leader哨兵会执行以下操作:
- 向选中的从节点发送
SLAVEOF NO ONE
命令,使其成为新主节点。 - 向其他从节点发送
SLAVEOF
命令,使它们连接到新主节点。 - 更新客户端配置,将写操作转向新主节点。
5. 哨兵机制的注意事项
- 哨兵节点不应只有一个,否则哨兵节点故障会影响整个系统的可用性。
- 哨兵节点数量最好是奇数,便于leader选举。
- 哨兵节点不存储数据,数据存储仍由Redis主从节点负责。
- 哨兵机制解决了高可用性问题,但不能解决数据丢失或存储容量受限的问题。
- 当数据量接近或超过机器物理内存时,可能需要考虑使用Redis集群来扩展存储容量。
6. 结论
Redis哨兵机制是一个强大的工具,能够大大提高Redis系统的可用性。通过自动故障检测和故障转移,它降低了系统维护的复杂度,减少了人工干预的需求。然而,在使用哨兵机制时,我们也需要注意它的局限性,并根据实际需求选择合适的Redis架构方案。
参考文献
- [Redis]哨兵机制-CSDN博客. https://blog.csdn.net/a_zhee1/article/details/140165865