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
相关文章
|
3月前
|
NoSQL Java Redis
实现基于Redis的分布式锁机制
实现基于Redis的分布式锁机制
|
23天前
|
存储 NoSQL Redis
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
Redis持久化、RDB和AOF方案、Redis主从集群、哨兵、分片集群、散列插槽、自动手动故障转移
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
|
2月前
|
NoSQL 关系型数据库 Redis
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀
这篇文章深入探讨了Redis事务的概念、命令使用、错误处理机制以及乐观锁和悲观锁的应用,并通过WATCH/UNWATCH命令展示了事务中的锁机制。
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀
|
6天前
|
存储 NoSQL Redis
Redis的RDB快照:保障数据持久性的关键机制
Redis的RDB快照:保障数据持久性的关键机制
16 0
|
6天前
|
存储 缓存 NoSQL
深入探究Redis的AOF持久化:保障数据安全与恢复性能的关键机制
深入探究Redis的AOF持久化:保障数据安全与恢复性能的关键机制
15 0
|
2月前
|
运维 监控 NoSQL
【Redis】哨兵(Sentinel)原理与实战全解~炒鸡简单啊
Redis 的哨兵模式(Sentinel)是一种用于实现高可用性的机制。它通过监控主节点和从节点,并在主节点故障时自动进行切换,确保集群持续提供服务。哨兵模式包括主节点、从节点和哨兵实例,具备监控、通知、自动故障转移等功能,能显著提高系统的稳定性和可靠性。本文详细介绍了哨兵模式的组成、功能、工作机制以及其优势和局限性,并提供了单实例的安装和配置步骤,包括系统优化、安装、配置、启停管理和性能监控等。此外,还介绍了如何配置主从复制和哨兵,确保在故障时能够自动切换并恢复服务。
|
2月前
|
存储 缓存 NoSQL
Redis 7.0如何优化缓存命中率?
优化Redis缓存命中率的关键策略包括:合理设计键值结构以节省内存并提高查找效率,如使用哈希表存储共享前缀的键;采用LRU算法淘汰不常用键,保持热门数据;优化查询模式,避免大键与大量小键,使用`SCAN`代替`KEYS`减少负载;为临时数据设置过期时间自动清理;监控性能并适时调整策略;利用不同数据类型的优势;使用Pipeline减少网络延迟;限制键扫描范围;优化Lua脚本执行效率;以及根据应用场景合理配置Redis参数。这些方法有助于提升Redis性能和缓存效率。
|
2月前
|
监控 NoSQL Redis
【Azure Redis】Redis服务负载达到100%后的影响及有何优化方法
【Azure Redis】Redis服务负载达到100%后的影响及有何优化方法
|
2月前
|
缓存 NoSQL Redis
【Azure Redis 缓存】C#程序是否有对应的方式来优化并缩短由于 Redis 维护造成的不可访问的时间
【Azure Redis 缓存】C#程序是否有对应的方式来优化并缩短由于 Redis 维护造成的不可访问的时间
下一篇
无影云桌面