内容来源为六星教育,这里仅作为学习笔记
redis哨兵初识
redis的主从复制模式下,一旦主节点由于故障不能提供服务,需要人工讲从节点晋升为主节点,同时还要通知应用方更新主节点地址,那这就会存在着问题;哨兵就是来处理这个问题的
基础概念
名称 | 逻辑 |
---|---|
主节点 | redis主服务器 |
从节点 | redis从服务器 |
redis数据节点 | 主节点和从节点 |
哨兵节点 | 监控redis数据节点 |
哨兵节点集合 | 若干哨兵节点的抽象组合 |
redis 哨兵 | redis高可用实现方案 |
应用方 | 第三方客户端如PHP |
主从复制的问题
“高可用性”(High Availability)通常来描述一个系统经过专门的设计,从而减少停工时间,而保持其服务的高度可用性
Redis 复制的主要内容中提到,Redis 复制有一个问题,当主机 Master 宕机以后,我们需要人工解决切换,比如使用 slaveof no one 。实际上主从复制并没有实现高可用。
- 主节点发生故障后,客户端连接主节点失败,两个从节点与主节点连接失败造成复制中断
- 如果主节点无法正常确定,需要选出一个从节点升级为主节点,对它执行 slaveof no one 命令
- 原来的从节点成为新的主节点后,更细应用方的主节点信息,重新启动应用方
- 客户端命令另外一个从节点去复制新的主节点
- 待原来的主节点恢复后,让它去复制新的主节点。
redis 哨兵的高可用性
Redis Sentinel 一个分布式架构,其中包含若干个 Sentinel 节点和 Redis 数据节点,每个 Sentinel 节点会对数据节点和其余Sentinel节点进行监控,当它发现节点不可达时,会对节点做下线标识
如果被标识的是主节点,它还会和其他 Sentinel 节点进行“协商”,当大多数 Sentinel 节点都认为主节点不可达时,它们会选举出一个 Sentinel 节点来完成自动故障转移的工作,同时会将这个变化实时通知给 Redis 应用方。
整个过程完全是自动的,不需要人工来介入,所以这套方案很有效地解决了 Redis 的高可用问题。
注意:哨兵并没有影响到正常的主从结构,以及做什么特殊处理
从逻辑上解释,哨兵节点集合会定期对所有节点进行监控,特别是对主节点的故障实现自动转移。
基本的故障转移流程
- 主节点出现故障,此时两个从节点与主节点失去连接,主从复制失败。
- 每个 Sentinel 节点通过定期监控发现主节点出现了故障
- 多个 Sentinel 节点对主节点的故障达成一致会选举出其中一个节点作为领导者负责故障转移
- Sentinel 领导者节点执行了故障转移,整个过程基本是跟我们手动调整一致的,只不过是自动化完成的。
- 故障转移后整个 Redis Sentinel 的结构,重新选举了新的主节点
总结一下哨兵的功能
- 监控:Sentinel 节点会定期检测 Redis 数据节点、其余 Sentinel 节点是否可达
- 通知:Sentinel 节点会将故障转移的结果通知给应用方
- 主节点故障转移: 实现从节点晋升为主节点并维护后续正确的主从关系
- 配置提供者: 在 Redis Sentinel 结构中,客户端在初始化的时候连接的是 Sentinel 节点集合 ,从中获取主节点信息。
同时Redis Sentinel 包含了若个 Sentinel 节点,这样做也带来了两个好处:
- 对于节点的故障判断是由多个 Sentinel 节点共同完成,这样可以有效地防止误判。
- Sentinel 节点集合是由若干个 Sentinel 节点组成的,这样即使个别 Sentinel 节点不可用,整个 Sentinel 节点集合依然是健壮的。
但是 Sentinel 节点本身就是独立的 Redis 节点,只不过它们有一些特殊,它们不存储数据, 只支持部分命令
哨兵配置最优个数
哨兵的配置个数是3个并且最好是奇数;
如果1个则不能保证高可用因为本身自己也会出现问题;如果2个那么就会出现同时执行切换操作肯定也不行,烧饼之间必须要先约定好由谁来执行次切换操作,此时就设计了哨兵之间选leader的操作。
redis哨兵安装和部署
部署结构
3个哨兵、1个主节点、2个从节点
对应的配置事项说明;网络段为 192.160.1.0/24
角色 | ip | port主->port容 |
---|---|---|
master | 192.160.1.79 | 6379->6379 |
slave-1 | 192.160.1.80 | 6380->6379 |
slave-2 | 192.160.1.81 | 6381->6379 |
sentinel_79 | 192.160.1.179 | 26379->26379 |
sentinel_80 | 192.160.1.180 | 26380->26379 |
sentinel_81 | 192.160.1.181 | 26381->26379 |
准备工作清空
docker stop $(docker ps -a -q) | xargs docker rm {}
配置文件内容及文件目录结构
目录结构
09_sentinel
- data
- master-79
- conf
- redis.conf
- log
- redis.log
- data
- slave-80
- ..
- slave-81
- ..
- sentinel
- sentinel-179
- conf
- sentinel.conf
- log
- sentinel.log
- data
- sentinel-180
- ..
- sentinel-181
- ..
部署主从:
如下为配置
# 主节点配置
bind 0.0.0.0
protected-mode no
port 6379
daemonize no
dir "/redis/data"
logfile "/redis/log/redis.log"
# 从节点配置
bind 0.0.0.0
protected-mode no
port 6379
daemonize no
replicaof 192.160.1.79 6379
dir "/redis/data"
logfile "/redis/log/redis.log"
然后通过docker-compose的命令创建redis容器并且确认关系
[root@localhost data]# docker-compose up -d
[root@localhost data]# docker exec -it redis5_m_79 sh
/ # redis-cli
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.160.1.80,port=6379,state=online,offset=98,lag=1
slave1:ip=192.160.1.81,port=6379,state=online,offset=98,lag=0
...
127.0.0.1:6379> exit
/ # exit
哨兵部署
bind 0.0.0.0
protected-mode no
port 26379
daemonize no
logfile "/redis/log/sentinel.log
sentinel monitor mymaster 192.160.1.79 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
参数介绍:
sentinel monitor mymaster 192.160.1.79 6379 2
监控的主节点的名字、IP 和端口,最后一个2的意思是有几台 Sentinel 发现有问题,就会发生故障转移,例如 配置为2,代表至少有2个 Sentinel 节点认为主节点 不可达,那么这个不可达的判定才是客观的。对于设置的越小,那么达到下线的条件越宽松,反之越严格。一般建议将其设置为 Sentinel 节点的一半加1
sentinel down-after-milliseconds mymaster 30000
这个是超时的时间(单位为毫秒)。打个比方,当你去 ping 一个机器的时候,多长时间后仍 ping 不通,那么就认为它是有问题
sentinel parallel-syncs mymaster 1
当 Sentinel 节点集合对主节点故障判定达成一致时, Sentinel 领导者节点会做故障转移操作,选出新的主节点,原来的从节点会向新的主节点发起复制操 作, parallel-syncs 就是用来限制在一次故障转移之后,每次向新的主节点发起复制操作的从节点个数,指出 Sentinel 属于并发还是串行。1代表每次只能 复制一个,可以减轻 Master 的压力
sentinel auth-pass <master-name> <password>
如果 Sentinel 监控的主节点配置了密码,sentinel auth-pass 配置通过添加主节点的密码,防止 Sentinel 节点对主节点无法监控。
sentinel failover-timeout mymaster 180000
表示故障转移的时间
启动sentinel节点:
# 方法一
redis-sentinel /redis/conf/sentinel.conf
# 方法二
redis-server /redis/conf/sentinel.conf --sentinel
对于的docker-compose文件内容
# 编排php,redis,nginx容器
version: "3.6" # 确定docker-composer文件的版本
services: # 代表就是一组服务 - 简单来说一组容器
sentinel_179: # 这个表示服务的名称,课自定义; 注意不是容器名称
image: redis5asm # 指定容器的镜像文件
networks: ## 引入外部预先定义的网段
redis5sm:
ipv4_address: 192.160.1.179 #设置ip地址
container_name: redis5_sent_179 # 这是容器的名称
ports: # 配置容器与宿主机的端口
- "26379:26379"
volumes: # 配置数据挂载
- /redis_2004/09_sentinel/sentinel/sentinel_179:/redis
# command: top
command: /usr/local/bin/redis-sentinel /redis/conf/sentinel.conf
sentinel_180: # 这个表示服务的名称,课自定义; 注意不是容器名称
image: redis5asm # 指定容器的镜像文件
networks: ## 引入外部预先定义的网段
redis5sm:
ipv4_address: 192.160.1.180 #设置ip地址
container_name: redis5_sent_180 # 这是容器的名称
ports: # 配置容器与宿主机的端口
- "26380:26379"
volumes: # 配置数据挂载
- /redis_2004/09_sentinel/sentinel/sentinel_180:/redis
# command: top
command: /usr/local/bin/redis-sentinel /redis/conf/sentinel.conf
sentinel_181: # 这个表示服务的名称,课自定义; 注意不是容器名称
image: redis5asm # 指定容器的镜像文件
networks: ## 引入外部预先定义的网段
redis5sm:
ipv4_address: 192.160.1.181 #设置ip地址
container_name: redis5_sent_181 # 这是容器的名称
ports: # 配置容器与宿主机的端口
- "26381:26379"
volumes: # 配置数据挂载
- /redis_2004/09_sentinel/sentinel/sentinel_180:/redis
# command: top
command: /usr/local/bin/redis-sentinel /redis/conf/sentinel.conf
# 网段设置
networks:
#引用外部预先定义好的网段
redis5sm:
external:
name: redis5sm
最后创建的结果
然后我们可以进入容器通过info查看信息
一个哨兵可以监听多个节点