Redis学习笔记(十五)Sentinel(哨兵)(中)[亲测有效]

Redis学习笔记(十五)Sentinel(哨兵)(中)[亲测有效]上一篇 我们模拟了单机器下哨兵模式的搭建,那么接下来我们看下哨兵模式的实现与工作。 为什么又分成两篇呢?因为篇幅太长(偷懒),再一个这篇主要说的是Sentinel的初始化以及信息交换,下一篇

Redis学习笔记(十五)Sentinel(哨兵)(中)

上一篇 我们模拟了单机器下哨兵模式的搭建,那么接下来我们看下哨兵模式的实现与工作。

为什么又分成两篇呢?因为篇幅太长(偷懒),再一个这篇主要说的是Sentinel的初始化以及信息交换,下一篇着重说下状态检查、Sentinel头领选举与故障转移 。

启动并初始化Sentinel

当一个Sentinel启动时,需要执行以下步骤:

(1)初始化服务器。

因为Sentinel本事上是一个运行在特殊模式下的Redis服务器,所以启动时的第一步也就是初始化一个普通的Redis服务器。不同点是在初始化的时候不会载入RDB或AOF文件。

(2)将普通的Redis服务器使用的代码替换成Sentinel专用代码。

端口替换Redis服务器使用redis.h/REDIS_SERVERPORT(6379)常量作为服务器端口,而Sentinel则使用sentinel.c/REDIS_SENTINEL_PORT(26379)常量作为服务器端口。

另外Redis服务器使用redisCommandTable服务器作为命令表,而Sentinel则使用sentinelcmds作为服务器的命令表,并且其中的info命令会使用Sentinel模式下专用的sentinelInfoCommand函数,而不是普通redis服务器使用的redis.c/infoCommand函数。

(3)初始化Sentinel状态。

服务器会初始化一个sentinel.c/sentinelState结构(”Sentinel状态”),用于保存服务器中所有和Sentinel功能有关的状态。

struct sentinelState{
//当前纪元,用于实现故障转移
uint64_t current_epoch;
//保存了所有被这个sentinel监视的主服务器
//字典的键是主服务器的名字
//字典中的值是一个指向sentinelRedisInstance结构的指针
dict *masters;
//是否进入TILT模式
int tilt;
//目前正在执行的脚本数量
int running_scripts;
//进图TILT模式的时间
mstime_t tilt_start_time;
//一个FIFO队列,包含了所有需要执行的用户脚本
list *scripts_queue;
} sentinel;

代码100分

(4)根据给定的配置文件,初始化Sentinel的监视主服务器列表。

sentinelRedisInstance结构(实例结构)

代码100分typedef struct sentinelRedisInstance{
//标识值,记录了实例的类型以及该实例的当前状态
int flag;
//实例的名称(主服务器由用户配置,从服务器自动设置ip:port)
char *name;
//实例的运行id
char *runid;
//配置纪元,用户实现故障转移
uint64_t config_epoch;
//实例的地址
//sentinelAddr *addr;
//实例无相应多少毫秒之后才会被判断主观下线
mstime_t down_after_period‘;
//判断这个实例为客观下线所需要支持的投票数量
int quorun;
//在执行故障转移操作时,可以同时对新的主服务器进行同步的从服务器数量
int parallel_syncs;
//刷新故障迁移状态的最大时间限制
mstime_t fallover_timeout;
}  sentinelRedisInstance;

*addr 指向sentinelAddr结构:

typedef struct sentinelAddr{
char *ip;
int port;
} sentinelAddr;

根据用户的配置初始化实例结构:

#名称 ip port

sentinel monitor mymaster 127.0.0.1 6379 2

#实例在相应多少毫秒之后才会被判断主观下线

sentinel down-after-milliseconds mymaster 3000

sentinel failover-timeout mymaster 10000  

#在执行故障转移操作时,可以同时对新的主服务器进行同步的从服务器数量

sentinel parallel-syncs mymaster 1

(5)创建连向主服务器的网络连接。

Sentinel将称为主服务器的客户端,它可以向主服务器发送命令,并从命令回复中获取相关的信息:对于被Sentinel监视的主服务器来说,Sentinel会创建两个连向主服务器的异步网络连接,一个是命令连接这个连接专门用于向主服务器发送命令,并接收命令回复;另一个是订阅连接这个连接专门用于订阅主服务器的_sentinel_:hollo频道。

 

 获取主服务器信息

sentinel默认会以每十秒一次的频率,通过命令连接向被监视的主服务器发送INFO命令,并通过分析INFO命令的回复来获取主服务器的当前信息。

通过分析主服务器返回的INFO命令回复,Sentinel可以获取以下两个方面的信息:

一方面是关于主服务器本身的信息,包括run_id域记录的服务器运行ID以及role域记录的服务器角色;另一方面是关于主服务器属下的所有从服务器信息,每个从服务器由一个“slave”字符串开头的行记录,每行的ip=域记录了从服务器的IP地址,而port=域则记录了从服务器的端口号。根据这些IP地址和端口号,Sentinel无须用户提供从服务器的地址信息,就可以自动发现从服务器。

主服务器 实力结构的flags属性的值为SRI_MASTER,而从服务器实例结构的flags属性的值为SRI_SLAVE。

当Sentinel发现主服务器有新的从服务器出现时,Sentinel除了会为这个新的从服务器创建相应的实例结构外,Sentinel还会创建连接到从服务器的命令连接和订阅连接。

在默认情况下,Sentinel会以每两秒一次的频率,通过命令连接向所有被监视的主服务器和从服务器发送以下格式的命令,PUBLISH _sentinel_:hello “< s_ip > < s_port >< s_runid >< s_epoch > < m_name > < m_ip >< m_ip ><m_epoch>”。

接收来自主服务器和从服务器的频道信息

 当Sentinel与一个主服务器或者从服务器建立起订阅连接之后,Sentinel就会通过订阅连接,向服务器发送以下命令:SUBSCRIBE __semtomel__:hello

Redis学习笔记(十五)Sentinel(哨兵)(中)[亲测有效]

 

当一个Sentinel从__sentinel__:hello频道收到一条信息时,Sentinel会对这条信息进行分析,提取出信息中的Sentinel IP地址,Sentinel端口号,Sentinel运行ID等八个参数,并进行检查:如果信息中记录的Sentinel运行ID和基尔兽信息的Sentinel的运行ID相同,那么说明这条信息时Sentinel自己发送的,Sentinel将丢弃这条信息,不做处理,反之如果记录的Sentinel运行ID和接收消息的Sentinel的运行ID不相同,那么说明这条信息时监视同一个服务器的其他Sentinel发来的,接收信息的Sentinel将根据这些信息中的参数,对相应主服务器的实例结构进行更新。

Sentinel为主服务器创建的实例结构中的sentinels字典中除了保存本身以外,还会保存同样监视这个主服务器的其他Sentinel的资料,其中字典键为 ip:port 值为Sentinel实例结构。

如果目标Sentinel(接收消息的Sentinel)接收到源Sentinel(发送消息的Sentinel)的消息,提取其中的参数检查主服务器实例结构的sentinels字典中源Sentinel实例结构是否存在,如果存在则更新,不存在则创建实例结构并存储到主服务器的sentinels字典中。并且,目标Sentinel还会创建连接向源Sentinel的命令连接,最终监视同一主服务器的多个Sentinel将形成互相连接的网络。

但是Sentinel之间不对创建订阅连接,这是因为Sentinel需要通过接收主服务器或者从服务器发来的频道信息发现未知的新Sentinel,所以才需要建立订阅连接,而相互已知的Sentinel只要使用命令连接来进行通信就足够了。


 

每天学一点,总会有收获。

 

下篇我们看下Redis的Sentinel(哨兵)的状态检查、Sentinel头领选举与故障转移。

说明:尊重作者知识产权,文中内容参考《Redis设计与实现》,仅在此做学习与大家分享。

 


Redis学习笔记(十五)Sentinel(哨兵)(中)[亲测有效]

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/8280.html

(0)
上一篇 2023-03-04
下一篇 2023-03-04

相关推荐

  • 使用PyTorch进行神经网络训练

    使用PyTorch进行神经网络训练PyTorch是一个基于Python的机器学习库,主要用于构建深度神经网络。它实现了动态计算图概念,从而使得模型的构建、训练和优化更加灵活方便。在本文中,我们将介绍如何使用PyTorch进行神经网络训练,以及它的一些基本概念和技巧。

    2024-04-17
    75
  • MySQL-InnoDB为什么采用B+树结构实现索引

    MySQL-InnoDB为什么采用B+树结构实现索引索引的作用是提高查询效率,其实现方式有很多种,常见的索引模型有哈希表、有序列表、搜索树等。 哈希表 一种以key-value键值对的方式存储数据的结构,通过指定的key可以找到对应的value。 哈…

    2023-02-23
    151
  • .NET 5/.NET Core使用EF Core 5连接MySQL数据库写入/读取数据示例教程「建议收藏」

    .NET 5/.NET Core使用EF Core 5连接MySQL数据库写入/读取数据示例教程「建议收藏」本文首发于《.NET 5/.NET Core使用EF Core 5(Entity Framework Core)连接MySQL数据库写入/读取数据示例教程》 前言 在.NET Core/.NET 5的

    2023-04-14
    146
  • Python如何运行代码

    Python如何运行代码Python 是一种互动式、面向对象的解释型高级程序设计语言。Python 语言具有易于上手、易于阅读、代码简洁明了等特点。Python 运行代码的方式也有很多种,本文将从多个角度细致地阐述 Python 如何运行代码。

    2024-04-19
    73
  • Pyhton代码:将列表转换为字符串的方法

    Pyhton代码:将列表转换为字符串的方法在Pyhton中,列表(list)是一种常见的数据类型,其由一系列元素组成,每个元素可以是任意类型,包括字符串、数字、布尔值等等。而有时我们需要将列表变成字符串类型,以便更方便地进行存储、传输或展示。本文将详细介绍在Pyhton中,如何将列表转换为字符串。

    2024-09-04
    25
  • Python中del函数的用法

    Python中del函数的用法Python是一门简单易学、功能全面的编程语言,因其易于开发、读取和维护代码而被广泛应用。而在Python语言中,del操作符(函数)是一个常见并且有用的操作符,在处理数据结构或清理变量时起着至关重要的作用。本文将对Python中del函数的用法进行介绍,并讨论其在不同情况下的应用。

    2024-09-08
    25
  • Ubuntu 彻底卸载 MySQL 数据库[亲测有效]

    Ubuntu 彻底卸载 MySQL 数据库[亲测有效]
    Ubuntu 18.04 彻底卸载MySQL 5.7.31 1. 查看MySQL的依赖项 dpkg –list|grep mysql 2. 卸载 mysq…

    2023-04-07
    148
  • excel如何从字符串中截取指定字符(LEFT、RIGHR、MID三大函数)[亲测有效]

    excel如何从字符串中截取指定字符(LEFT、RIGHR、MID三大函数)[亲测有效]目录1.LEFT函数2.RIGHT函数3.MID函数1.LEFT函数(1)语法:LEFT(text,num_chars)参数:①text:必要参数。包含要提取字符的文本字符串。字符串表达式其中最左边的那些字符将被返回。如果text包含Null,将返回Null。②num_chars:可选参数。数值表达式,指出将返回多少个字符。num_chars必须大于或等于0。如果省略第二参数,则假设其值为1。如果为0,返回零长度字符串(“”)。如果大于或等于.

    2023-03-02
    146

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注