做网站寄生虫需要哪些东西,大连开发区论坛网,好看的企业网站,鹿邑建设局官方网站Redis#xff1a;分布式 - 哨兵 概念哨兵 Docker 搭建哨兵分布式选举流程 概念
Redis 的主从复制模式下#xff0c;一旦主节点由于故障不能提供服务#xff0c;需要人工进行主从切换#xff0c;同时大量的客户端需要被通知切换到新的主节点上#xff0c;对于上了一定规模… Redis分布式 - 哨兵 概念哨兵 Docker 搭建哨兵分布式选举流程 概念
Redis 的主从复制模式下一旦主节点由于故障不能提供服务需要人工进行主从切换同时大量的客户端需要被通知切换到新的主节点上对于上了一定规模的应用来说这种方案是无法接受的于是 Redis 2.8 开始提供了 Redis Sentinel(哨兵)来解决这个问题。
由于对 Redis 的许多概念都有不同的名词解释所以在介绍 Redis Sentinel之前先对几个名词概念进行必要的说明如表所示。
名词逻辑结构物理结构主节点Redis主服务一个独立的redis-server进程从节点Redis从服务一个独立的redis-server进程Redis数据节点主从节点主节点和从节点的进程哨兵节点监控Redis数据节点的节点一个独立的redis-sentinel进程哨兵节点集合若干哨兵节点的抽象组合若干redis-sentinel进程Redis哨兵(Sentinel)Redis提供的高可用方案哨兵节点集合和Redis主从节点应用方泛指一个多多个客户端一个或多个连接Redis的进程
Redis 的主从复制模式可以将主节点的数据改变同步给从节点这样从节点就可以起到两个作用
作为主节点的一个备份一旦主节点出了故障不可达的情况从节点可以作为后备并且保证数据尽量不丢失(主从复制表现为最终一致性)。从节点可以分担主节点上的读压力让主节点只承担写请求的处理将所有的读请求负载均衡到各个从节点上。
但是主从复制模式并不是万能的它同样遗留下以下几个问题
主节点发生故障时进行主备切换的过程是复杂的需要完全的人工参与导致故障恢复时间无法保障。主节点可以将读压力分散出去但写压力/存储压力是无法被分担的还是受到单机的限制。
其中第一个问题是高可用问题即 Redis 哨兵主要解决的问题。第二个问题是属于存储分布式的问题留给 Redis 集群去解决博客集中讨论第一个问题。 哨兵
当主节点出现故障时Redis Sentinel能自动完成故障发现和故障转移并通知应用方从而实现真正的高可用。
Redis Sentinel是一个分布式架构其中包含若干个 Sentinel 节点和 Redis 数据节点每个Sentinel节点会对数据节点和其余 Sentinel节点进行监控当它发现节点不可达时会对节点做下线表示。
如果下线的是主节点它还会和其他的 Sentinel 节点进行协商当大多数 Sentinel 节点对主节点不可达这个结论达成共识之后它们会在内部选举出一个领导节点来完成自动故障转移的工作同时将这个变化实时通知给 Redis 应用方。整个过程是完全自动的不需要人工介入。
整体的架构如图所示 Redis Sentinel相比于主从复制模式多了若干Sentinel节点用于实现监控数据节点。哨兵节点会定期监控所有节点(包含数据节点和其他哨兵节点)。
此处有多个哨兵节点是因为如果只使用一个哨兵进行监控的话如果哨兵本身就崩溃了那么整个监控服务都崩溃了。另外的在网络条件较差的情况下哨兵很可能会误判主节点的存活情况。
针对主节点故障的情况故障转移流程大致如下
主节点故障从节点同步连接中断主从复制停止。哨兵节点通过定期监控发现主节点出现故障。
哨兵节点与其他哨兵节点进行协商达成多数认同主节点故障的共识。这步主要是防止出故障的不是主节点而是发现故障的哨兵节点该情况经常发生于哨兵节点的网络被孤立的场景下。
哨兵节点之间使用 Raft 算法选举出一个领导角色由该节点负责后续的故障转移工作。哨兵领导者开始执行故障转移 从节点中选择一个作为新主节点执行slave no one让其他从节点同步新主节执行slaveof通知应用层转移到新主节点 Docker 搭建哨兵分布式
为了演示一个完整的Redis分布式架构总共要创建三个数据节点三个哨兵节点。由于大部分人都只有一台主机所以此时的最佳解决方案是使用docker接下来使用docker在一台主机上模拟一个分布式系统。
拉取redis:5.0.9版本的镜像
docker pull redis:5.0.9当前目录结构如下 redis-data用于存放数据节点redis-sentinel用于存放哨兵节点。每个目录下都有docker-compose.yml用于进行容器编排。
编排 redis-data/docker-compose.yml
services:master:image: redis:5.0.9container_name: redis-masterrestart: alwayscommand: redis-server --appendonly yesports:- 6379:6379slave1:image: redis:5.0.9container_name: redis-slave1restart: alwayscommand: redis-server --appendonly yes --slaveof redis-master 6379ports:- 6380:6379slave2:image: redis:5.0.9container_name: redis-slave2restart: alwayscommand: redis-server --appendonly yes --slaveof redis-master 6379ports:- 6381:6379该代码完成了三个数据节点的创建通过命令完成主从关系的配置。执行之前记得把主机上的redis停止把6379、6380、6381三个端口空出来给docker启动的redis。
在目录redis-data中执行
docker compose up -d这样就创建好了三个redis服务端可以通过redis-cli -p 6379、redis-cli -p 6380、redis-cli -p 6381来验证是否启动成功。
编排redis-sentinel/docker-compose.yml
services:sentinel1:image: redis:5.0.9container_name: redis-sentinel-1restart: alwayscommand: redis-sentinel /root/redis/sentinel/redis-sentinel/sentinel1.confvolumes:- ./sentinel1.conf:/root/redis/sentinel/redis-sentinel/sentinel1.confports:- 26379:26379sentinel2:image: redis:5.0.9container_name: redis-sentinel-2restart: alwayscommand: redis-sentinel /root/redis/sentinel/redis-sentinel/sentinel2.confvolumes:- ./sentinel2.conf:/root/redis/sentinel/redis-sentinel/sentinel2.confports:- 26380:26379sentinel3:image: redis:5.0.9container_name: redis-sentinel-3restart: alwayscommand: redis-sentinel /root/redis/sentinel/redis-sentinel/sentinel3.confvolumes:- ./sentinel3.conf:/root/redis/sentinel/redis-sentinel/sentinel3.confports:- 26381:26379networks:default:external:name: redis-data_default此处创建了三个redis-sentinel哨兵并且规定它们的配置文件分别为./sentinel1.conf、./sentinel2.conf、./sentinel3.conf。
但是docker存储卷要用绝对路径所以你要根据自己的主机情况填入绝对路径。
配置文件内容如下
bind 0.0.0.0
port 26379
sentinel monitor redis-master redis-master 6379 2
sentinel down-after-milliseconds redis-master 1000此处要简单解释一下配置文件
sentinel monitor 主节点名 主节点ip 主节点端⼝ 法定票数主节点名
这个是哨兵内部自己起的名字
主节点 ip
部署 redis-master的设备ip此处由于是使用 docker可以直接写 docker的容器名会被自动 DNS 成对应的容器ip主节点端口。
法定票数
哨兵需要判定主节点是否挂了但是有的时候可能因为特殊情况比如主节点仍然工作正常但是哨兵节点自己网络出问题了无法访问到主节点了。此时就可能会使该哨兵节点认为主节点下线出现误判。使用投票的方式来确定主节点是否真的挂了是更稳妥的做法需要多个哨兵都认为主节点挂了票数 法定票数 之后才会真的认为主节点是挂了。
sentinel down-after-milliseconds
该参数用于设置心跳包的超时时间主节点和哨兵之间通过心跳包来进行沟通如果心跳包在指定的时间内还没回来就视为是节点出现故障。
既然多个配置文件内容相同为啥要创建多份配置文件redis-sentinel在运行中可能会对配置进行重写修改文件内容如果用一份文件就可能出现修改混乱的情况。
最后执行命令启动容器
docker compose up -d启动后打开刚刚写的配置文件
bind 0.0.0.0
port 26379
sentinel myid 15d2602413f32eb3ed797d804a728a59d65e43f1
sentinel deny-scripts-reconfig yes
# Generated by CONFIG REWRITE
dir /data
sentinel monitor redis-master 172.18.0.2 6379 2
sentinel down-after-milliseconds redis-master 1000
sentinel config-epoch redis-master 0
sentinel leader-epoch redis-master 0
sentinel known-replica redis-master 172.18.0.4 6379
sentinel known-replica redis-master 172.18.0.3 6379
sentinel known-sentinel redis-master 172.18.0.7 26379 475769f5605edb0016ad007ee06351e058589d4a
sentinel known-sentinel redis-master 172.18.0.5 26379 6ddca4a48f3ec926f8d8408794b261803aa6a5ad
sentinel current-epoch 0可以看到除了最开始写入的内容哨兵启动后又增加了很多新内容。 选举
现在通过docker关掉master的容器来模拟主节点崩溃
docker stop redis-master此时哨兵节点就已经在后台工作了查看哨兵的日志
docker compose logs输出 这是第二个哨兵的日志
sdown master这代表哨兵节点发现了master节点掉线sdown表示主观认为也就是说哨兵还不能保证master一定掉线odown master经过与其它哨兵交流多个哨兵都认为master节点掉线odown表示客观认为#quorum 3/2表示法定票数为2票目前有三个哨兵都投票认为master掉线switch-master切换主节点此时已经有新的节点变成主节点了
进入6380端口的数据节点输入info replication 可以看到role:master6380成为了新的主节点当然也有可能是6381。
尝试重启redis-master 这个redis-master重启后就变成了从节点不再是主节点了。 流程
看完选举的现象后接下来讲解一下选举的具体流程。
主观下线 sdown
当主节点宕机此时主节点和哨兵之间的心跳包就没有了响应站在三个哨兵的角度来看主节点出现严重故障因此三个哨兵均会把主节点判定为主观下线
客观下线 odown
此时哨兵均会对主节点故障这件事情进行投票当故障得票数 法定票数之后这意味着主节点故障这个事情被做实了触发客观下线
选取哨兵leader
接下来需要哨兵把剩余的slave 中挑选出一个新的master 这个工作不需要所有的哨兵都参与只需要选出个代表 (称为 leader)由leader负责进行 slave 升级到 master 的提拔过程这个选举的过程涉及到 Raft 算法
每个哨兵节点都给其他所有哨兵节点发起一个拉票请求收到拉票请求的节点会回复一个投票响应当哨兵节点收到多个拉票请求只对第一个节点投票后续节点都不投票一轮投票完成之后发现得票超过半数的节点自动成为 leader 如果出现平票的情况就重新再投一次即可。
因此建议哨兵节点设置成奇数如果是偶数个则增大了平票的概率带来不必要的开销。
最终leader 节点负责挑选一个 slave 成为新的 master 当其他的 sentenal发现新的 master 出现了就说明选举结束了。
简而言之Raft 算法的核心就是先下手为强谁率先发出了拉票请求谁就有更大的概率成为 leader这里的决定因素成了网络延时。 在日志中vote-for-leader就是在投票选举leader哨兵。
leader哨兵节点选出一个 slave 成为新的 master
挑选规则
比较优先级优先级高(数值小的)的优先上位优先级是配置文件中的配置项中的 slave-priority 或者replica-priority)如果优先级相同比较 replication 和 offset 谁复制的数据多高的优先上位如果replication 和 offset也相同比较 run id 小的优先上位,
当某个数据节点被选为master后
leader哨兵指定该节点执行slave no one成为masterleader哨兵指定剩余节点执行slave of成为该节点的从节点
总结一下
主观下线 sdown单个哨兵节点认为主节点掉线客观下线 odown投票后客观认为主节点掉线选取哨兵leader依据网络情况选出一个哨兵成为leader由leader完成选举master选举master由leader依据优先级数据同步进度run id来选出一个节点成为master重构主从关系由leader哨兵指定数据节点执行指令重构主从关系
注意事项
哨兵节点不能只有一个否则哨兵节点挂了也会影响系统可用性哨兵节点最好是奇数个方便选举 leader得票更容易超过半数哨兵节点不负责存储数据仍然是 redis 主从节点负责存储.哨兵主从复制解决的问题是提高可用性不能解决数据极端情况下写丢失的问题哨兵主从复制不能提高数据的存储容量