redis 优化系列(四)哨兵机制

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis Sentinel(哨兵) 是一个分布式集群架构,其中包含若干个 Sentinel 节点和 Redis 数据节点,每个 Sentinel 节点会对数据节点和其余 Sentinel 节点进行监控,当它发现节点不可达时,会对节点做下线标识。

一、redis主从复制的问题:

Redis 复制有一个缺点,当主机 Master 宕机以后,我们需要人工操作来解决切换,比如使用 slaveof no one 。实际上主从复制并没有实现,高可用, 高可用侧重备份机器, 利用集群中系统的冗余,当系统中某台机器发生损坏的时候,其他后备的机器可以迅速的接替它来启动服务。

如下图所示:

网络异常,图片无法展示
|

一旦主节点宕机,写服务无法使用,就需要手动去切换,重新选取主节点,手动设置主从关系。

那么如何解决呢?如果我们有一个监控程序能够监控各个机器的状态及时作出调整,将手动的操作变成自动的。redis的Sentinel(哨兵)的出现就是为了解决这个问题。

二、哨兵机制的原理及实现

Redis Sentinel(哨兵) 是一个分布式集群架构,其中包含若干个 Sentinel 节点和 Redis 数据节点,每个 Sentinel 节点会对数据节点和其余 Sentinel 节点进行监控,当它发现节点不可达时,会对节点做下线标识。如果被标识的是主节点,它还会和其他 Sentinel 节点进行“协商”,当大多数 Sentinel 节点都认为主节点不可达时,它们会选举出一个 Sentinel 节点来完成自动故障转移的工作,同时会将这个变化实时通知给 Redis 应用方。整个过程完全是自动的,不需要人工来介入,所以这套方案很有效地解决了 Redis 的高可用问题。

注:哨兵(Sentinel) 其实也是一个redis只不过它不是用来存储数据的,而哨兵不止一台,会有多台(最好或者必须 部署多台哨兵)。哨兵是一个独立进程,作为进程,它会独立运行。

一句话解释:哨兵是用来监控redis master主节点的状态的工具,并做出相应反映。比如说 当前redis的主节点挂掉了,哨兵会自动从redis 从节点中选举出一台继续作为主节点,来继续提供redis主从集群服务。

如下图所示:

网络异常,图片无法展示
|

注意:由上图可知,client客户端并不是直接连接的redis主机,而是连接的哨兵(哨兵是一个集群,有多台哨兵),然后哨兵监控主节点的redis状态(不是实时监控,而是定时监控),然后哨兵会返回主机的相关服务信息

****

2.1 基本的故障转移流程:

1)主节点出现故障,此时两个从节点与主节点失去连接,主从复制失败。

网络异常,图片无法展示
|

2)每个 Sentinel 节点通过定期监控发现主节点出现了故障

网络异常,图片无法展示
|

3)多个 Sentinel 节点对主节点的故障达成一致会选举出其中一个节点作为领导者负责故障转移。

网络异常,图片无法展示
|

4)Sentinel 领导者节点执行了故障转移,整个过程基本是跟我们手动调整一致的,只不过是自动化完成的。

网络异常,图片无法展示
|

5)故障转移后整个 Redis Sentinel 的结构,重新选举了新的redis master 主节点。

网络异常,图片无法展示
|

****

2.2 Redis Sentinel 具有以下几个功能:

①、监控:Sentinel 节点会定期检测 Redis 数据节点、其余 Sentinel 节点是否可达。(一个哨兵可以监控多套主从结构,主节点)****

②、通知:Sentinel 节点会将故障转移的结果通知给应用方。

③、主节点故障转移:实现从节点晋升为主节点并维护后续正确的主从关系。

④、配置提供者:在 Redis Sentinel 结构中,客户端在初始化的时候连接的是 Sentinel 节点集合,从中获取主节点信息。

同时Redis Sentinel 包含了若个 Sentinel 节点(一般起步至少是3台),这样做也带来了两个好处:

①、对于节点的故障判断是由多个 Sentinel 节点共同完成,这样可以有效地防止误判。

②、Sentinel 节点集合是由若干个 Sentinel 节点组成的,这样即使个别 Sentinel 节点不可用,整个 Sentinel 节点集合依然是健壮的。

但是 Sentinel 节点本身就是独立的 Redis 节点,只不过它们有一些特殊,它们不存储数据,只支持部分命令。

三、案例:配置哨兵

环境:

1台master主节点 redis-master(ip:172.10.0.2)

2台slave从节点   redis-slave(ip:172.10.0.3)、redis-slave2(ip:172.10.0.4)

3台哨兵服务节点  redis-sentinel1(ip:172.10.0.9)、redis-sentinel2(ip:172.10.0.10)、redis-sentinel3(ip:172.10.0.11)

架构环境列表如下:

容器名称         容器IP地址      映射端口号       服务运行模式

redis-sentinel1    172.10.0.9      22530->26379      sentinel

redis-sentinel2    172.10.0.10     22531->26379      sentinel

redis-sentinel3    172.10.0.11     22532->26379      sentinel

redis-master      172.10.0.2      6380->6379        Master

redis-slave       172.10.0.3      6381->6379        Slave

redis-slave2      172.10.0.4      6382->6379        Slave

3.1 由于前面几篇博文我们已经创建了一主一从,所以这里在创建一台redis从节点,变成1主2从的架构

#创建一台redis从节点``docker run -itd --name redis-slave2 --net mynetwork -p 6382:6379 --ip 172.10.0.4 redis` `#进入该容器并修改redis配置文件,指定主节点配置``docker ``exec` `-it redis-slave2 ``bash` `#修改配置文件(这里就不演示了。。可看该系列博文的第一篇)

3.2 创建三台哨兵服务节点,并分别进入三台哨兵服务节点容器里面

#创建三台哨兵服务节点``docker run -itd --name redis-sentinel1 --net mynetwork -p 22530:26379 --ip 172.10.0.9 redis``docker run -itd --name redis-sentinel2 --net mynetwork -p 22531:26379 --ip 172.10.0.10 redis``docker run -itd --name redis-sentinel3 --net mynetwork -p 22532:26379 --ip 172.10.0.11 redis` `#分别进入三台哨兵服务节点容器里面``docker ``exec` `-it redis-sentinel1 ``bash``docker ``exec` `-it redis-sentinel2 ``bash``docker ``exec` `-it redis-sentinel3 ``bash

3.3 分别修改三台哨兵配置文件(redis-sentinel.conf)

vi` `/etc/redis-sentinel``.conf` `#1、为了省事方便。。我们做如下这2项修改。。``将 ``# bind 127.0.0.1 192.168.1.1 修改为 bind 0.0.0.0``将 ``# protected-mode no 修改为 protected-mode no 也就是取消前面的#号` `#2、修改哨兵服务要监控的主节点redis的ip地址``将 sentinel monitor mymaster 127.0.0.1 6379 2 修改为 sentinel monitor mymaster 172.10.0.2 6379 2` `#3、保存修改后的文件``#4、redis-sentinel2和redis-sentinel3容器里面的哨兵配置文件redis-sentinel.conf的修改也是这样修改。。

网络异常,图片无法展示
|

网络异常,图片无法展示
|

3.4 分别进入三台哨兵服务节点容器里面启动三台哨兵服务

#redis-sentinel1容器里面执行以下命令``redis-sentinel ``/etc/redis-sentinel``.conf &` `#redis-sentinel2容器里面执行以下命令``redis-sentinel ``/etc/redis-sentinel``.conf &` `#redis-sentinel3容器里面执行以下命令``redis-sentinel ``/etc/redis-sentinel``.conf &

3.5 为了验证是否配置成功,可以查看哨兵日志(查看任意一台哨兵里面的日志即可,因为3台哨兵服务节点配置都是一模一样的)

vi` `/var/log/redis/sentinel``.log

网络异常,图片无法展示
|

3.6 进入redis主节点这台服务容器里面,并kill掉这台服务的进程,使之挂掉。让哨兵服务自动从N台从redis服务节点中选取其中一台从服务节点成为新的主(master)节点

①、进入主节点服务容器里面

docker ``exec` `-it redis-master ``bash

②、查看redis端口占用详情

netstat` `-apn |``grep` `6379

网络异常,图片无法展示
|

③、kill掉该进程,然后再次查看端口占用情况,如果结果中没有相关端口对应的相关进程则kill成功,具体看以下截图

kill` `31` `netstat` `-apn |``grep` `6379

网络异常,图片无法展示
|

至此。。我们就把主节点的redis给kill掉了,然后稍等几秒钟(或几十秒钟,具体看配置文件中的配置),查看一下哨兵在这几台从redis节点中选取了那一台从节点使之变成了主节点

3.7 再次查看哨兵日志,看一下哨兵选取了那台从节点变成了主节点

vi` `/var/log/redis/sentinel``.log

网络异常,图片无法展示
|

从以上图片中可以看到哨兵选举了172.10.0.3这台ip地址的从节点作为redis主从架构中的主节点,也就是使这台没有挂掉的从节点从slave晋升成为了master。ps:172.10.0.3这台ip地址对应的容器名字:redis-slave

3.8 进入redis-slave这台服务容器查看redis相关服务信息验证一下是否已成为主节点

网络异常,图片无法展示
|

ok。。从以上截图中可以看到该节点确实已经成为了主节点,并且 offset 偏移量也不是从0开始的。。也就是意味着主从复制数据并不是从头开始的。。至此哨兵搭建使用成功。。

四、Sentinel 的核心配置

①、sentinel monitor mymaster 127.0.0.1 7000 2

监控的主节点的名字、IP 和端口,最后一个2的意思是有几台 Sentinel 发现有问题,就会发生故障转移,例如 配置为2,代表至少有2台 Sentinel 节点认为主节点不可达,那么这个不可达的判定才是客观的。对于设置的越小,那么达到下线的条件越宽松,反之越严格。一般建议将其设置为 Sentinel 节点的一半加1

②、sentinel down-after-millseconds 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常用命令

sentinel支持的合法命令如下:

①、sentinel masters 显示被监控的所有master以及它们的状态

②、sentinel master <master name> 显示指定master的信息和状态

③、sentinel slaves <master name> 显示指定master的所有slave以及它们的状态

④、sentinel get-master-addr-by-name <master name> 返回指定master的ip和端口,如果正在进行failover或者failover已经完成,将会显示被提升为master的slave的ip和端口

⑤、sentinel failover <master name> 强制sentinel执行failover,并且不需要得到其他sentinel的同意。但是failover后会将最新的配置发送给其他sentinel

⑥、sentinel failover-timeout mymaster 10000 这个参数设置集群 从 判断节点挂掉,到执行failover操作(即重新选举master节点)的时间

⑦、sentinel remove <name> 命令sentinel放弃对某个master的监听

六、应用端调用

Master可能会因为某些情况宕机了,如果在客户端是固定一个地址去访问,肯定是不合理的,所以客户端请求是请求哨兵,从哨兵获取主机地址的信息,或者是从机的信息。可以简单实现一个例子

1、随机选择一个哨兵连接,获取主机、从机信息

2、模拟客户端定时访问,实现简单轮训效果,轮询从节点

3、连接失败重试访问

代码简单模拟实现(php代码举例)

class` `Round``{``  ``static` `$lastIndex` `=0;` `  ``public` `function` `select(``$list``)``  ``{``    ``$currentIndex` `= self::``$lastIndex``; ``//当前的index``    ``$value`    `=``$list``[``$currentIndex``];``    ` `    ``if``(``$currentIndex` `+1 > ``count``(``$list``) -1)``    ``{``      ``self::``$lastIndex` `=0;``    ``}``    ``else``    ``{``      ``self::``$lastIndex``++;``    ``}``    ` `    ``return` `$value``;``  ``}``}` `/********华丽的分割线*********/` `$sentinelConf` `= [``  ``[``'ip'``=>``'47.98.147.49'``,``'port'``=>22530],``  ``[``'ip'``=>``'47.98.147.49'``,``'port'``=>22531],``  ``[``'ip'``=>``'47.98.147.49'``,``'port'``=>22532]``];` `//随机访问``$sentinelInfo` `=``$sentinelConf``[``array_rand``(``$sentinelConf``)];` `$redis` `=``new` `Redis();``$redis``->connect(``$sentinelInfo``[``'ip'``], ``$sentinelInfo``[``'port'``]);``$slavesInfo` `=``$redis``->rawCommand(``'SENTINEL'``, ``'slaves'``, ``'mymaster'``);` `$slaves` `= [];` `foreach` `(``$slavesInfo` `as` `$val``)``{``  ``$slaves``[] = [``'ip'``=>``$val``[3], ``'port'``=>``$val``[5]];``}` `//加载到缓存当中,可以记录这次访问的时间跟上次的访问时间` `//模拟客户端访问(这里用了swoole的定时操作)``swoole_timer_tick(600,``function` `() ``use``(``$slaves``) {``  ` `  ``//轮询``  ``$slave``=(``new` `Round``())->select(``$slaves``);``  ``try``  ``{``    ``$redis` `=``new` `Redis();``    ``$redis``->connect(``$slave``[``'ip'``], ``$slave``[``'port'``]);``    ``var_dump(``$slave``, ``$redis``->get(``'wzyl'``));``  ``}``  ``catch` `(\RedisException ``$e``)``  ``{` `  ``}` `});` `//阻塞在这里

总结redis主从、哨兵、集群的概念:

【redis主从】:

是备份关系, 我们操作主库,数据也会同步到从库。 如果主库机器坏了,从库可以上。就好比你 D盘的片丢了,但是你移动硬盘里边备份有。

【redis哨兵】:

哨兵保证的是HA(高可用),保证特殊情况故障自动切换,哨兵盯着你的“redis主从集群”,如果主库死了,它会告诉你新的老大是谁。

哨兵:主要针对redis主从中的某一个单节点故障后,无法自动恢复的解决方案。(哨兵 保证redis主从的高可用)

【redis集群】:

集群保证的是高并发,因为多了一些兄弟帮忙一起扛。同时集群会导致数据的分散,整个redis集群会分成一堆数据槽,即不同的key会放到不不同的槽中。

集群主要针对单节点容量、高并发问题、线性可扩展性的解决方案。

集群:是为了解决redis主从复制中 单机内存上限和并发问题,假如你现在的服务器内存为256GB,当达到这个内存时redis就没办法再提供服务,同时数据量能达到这个地步写数据量也会很大,容易造成缓冲区溢出,造成从节点无限的进行全量复制导致主从无法正常工作。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
21天前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:百万级数据统计优化实践
【10月更文挑战第21天】 在处理大规模数据集时,传统的单体数据库解决方案往往力不从心。MySQL和Redis的组合提供了一种高效的解决方案,通过将数据库操作与高速缓存相结合,可以显著提升数据处理的性能。本文将分享一次实际的优化案例,探讨如何利用MySQL和Redis共同实现百万级数据统计的优化。
54 9
|
1月前
|
存储 缓存 NoSQL
大数据-45 Redis 持久化概念 RDB AOF机制 持久化原因和对比
大数据-45 Redis 持久化概念 RDB AOF机制 持久化原因和对比
38 2
大数据-45 Redis 持久化概念 RDB AOF机制 持久化原因和对比
|
21天前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:优化百万数据查询的实战经验
【10月更文挑战第13天】 在处理大规模数据集时,传统的关系型数据库如MySQL可能会遇到性能瓶颈。为了提升数据处理的效率,我们可以结合使用MySQL和Redis,利用两者的优势来优化数据查询。本文将分享一次实战经验,探讨如何通过MySQL与Redis的协同工作来优化百万级数据统计。
48 5
|
29天前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:百万数据量的优化实录
【10月更文挑战第6天】 在现代互联网应用中,随着用户量的增加和业务逻辑的复杂化,数据量级迅速增长,这对后端数据库系统提出了严峻的挑战。尤其是当数据量达到百万级别时,传统的数据库解决方案往往会遇到性能瓶颈。本文将分享一次使用MySQL与Redis协同优化大规模数据统计的实战经验。
109 3
|
29天前
|
NoSQL 关系型数据库 BI
记录一次MySQL+Redis实现优化百万数据统计的方式
【10月更文挑战第13天】 在处理百万级数据的统计时,传统的单体数据库往往力不从心,这时结合使用MySQL和Redis可以显著提升性能。以下是一次实际优化案例的详细记录。
101 1
|
1月前
|
监控 NoSQL 算法
Redis Sentinel(哨兵)详解
Redis Sentinel(哨兵)详解
|
1月前
|
设计模式 NoSQL 网络协议
大数据-48 Redis 通信协议原理RESP 事件处理机制原理 文件事件 时间事件 Reactor多路复用
大数据-48 Redis 通信协议原理RESP 事件处理机制原理 文件事件 时间事件 Reactor多路复用
36 2
|
2月前
|
存储 NoSQL Redis
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
Redis持久化、RDB和AOF方案、Redis主从集群、哨兵、分片集群、散列插槽、自动手动故障转移
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
|
3月前
|
NoSQL 关系型数据库 Redis
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀
这篇文章深入探讨了Redis事务的概念、命令使用、错误处理机制以及乐观锁和悲观锁的应用,并通过WATCH/UNWATCH命令展示了事务中的锁机制。
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀