我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Redis学习笔记(十五)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;

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

sentinelRedisInstance结构(实例结构)

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 >"。

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

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

 

当一个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设计与实现》,仅在此做学习与大家分享。

 


 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

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

上一篇 我们模拟了单机器下哨兵模式的搭建,那么接下来我们看下哨兵模式的实现与工作。为什么又分成两篇呢?因为篇幅太长(偷懒),再一个这篇主要说的是Sentinel的初始化以及信息交换,下一篇着重说下状态检查、Sentinel头领选举与故障转移 。启动并初始化Se
Redis学习笔记(十五)Sentinel(哨兵)(中)
2020-07-22

Redis学习笔记(十六) Sentinel(哨兵)(下)

消失了一段时间,我又回来啦。不多说,继续把哨兵看完。 检测主观下线状态默认情况下,Sentinel会以每秒一次的频率向所有与他创建了命令连接的实例(主从服务器以及其他Sentinel)发送PING命令,并通过实例返回的PING命令回复来判断实例是否在线。实例对
Redis学习笔记(十六) Sentinel(哨兵)(下)
2019-07-27

Redis学习笔记(十四)Sentinel(哨兵)(上)

最近谈到Redis就会听到哨兵模式,工作期间同事也分享过关于哨兵模式的知识,但由于工作忙(给自己找个借口)没有没认真看,现在恶补下,老样子还是分上篇应用,下篇看实现过程,下面我们来看下哨兵到底是啥?哨兵模式(Sentinel)是Redis的高可用解决方案。由一
Redis学习笔记(十四)Sentinel(哨兵)(上)
2019-07-22

学习笔记-小甲鱼Python3学习第十五

字符串格式化符号含义符号说明%c格式化字符及其 ASCII 码%s格式化字符串%d格式化整数%o格式化无符号八进制数%x格式化无符号十六进制数%X格式化无符号十六进制数(大写)%f格式化浮点数字,可指定小数点后的精度%e用科学计数法格式化浮
2023-01-31

Redis学习笔记(十) 客户端

Redis服务器是典型的一对多服务器程序:一个服务器可以与多个客户端建立网络连接,每个客户端可以向服务器发送命令请求,而服务器则接收并处理客户端发送的命令请求,并向客户端返回命令回复。通过使用由I/O多路复用技术实现的文件事件处理器,Redis服务器使用单线程
Redis学习笔记(十) 客户端
2022-04-06

Redis学习笔记(十三) 复制(下)

上一篇写了Redis复制功能的简单应用,下面我们看下Redis复制功能的实现过程。下面基本上是理论部分,枯燥乏味,但希望大家能看看,毕竟知识不都是感兴趣的.耐得住寂寞,经得起诱惑,方能守得住繁华 ~.~旧版复制功能的实现Redis的复制功能分为同步和命令传播两
Redis学习笔记(十三) 复制(下)
2022-04-20

Redis学习笔记(五) 压缩列表

压缩列表是列表键与哈希键的底层实现之一。当一个列表键只包含少量的列表项,并且每个列表项要么就是小整数值,要么就是长度较短的字符串,那么Redis就会使用压缩列表来做列表键的底层实现。压缩列表是为了节约内存而开发的,是由一系列特殊编码的连续内存块组成的顺序型数据
Redis学习笔记(五) 压缩列表
2016-06-12

Redis学习笔记(十二) 复制(上)

偷个懒,晚上工作忙的太晚,整个复制功能的内容还没有写完,这里先说一下复制功能的简单应用。在Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制另一个服务器,我们称呼被复制的服务器为主服务器(master),而对主服务器
Redis学习笔记(十二) 复制(上)
2017-05-07

Redis学习笔记(二十一) 事务

文章开始啰嗦两句,写到这里共21篇关于redis的琐碎知识,没有过多的写编程过程中redis的应用,着重写的是redis命令、客户端、服务器以及生产环境搭建用到的主从、哨兵、集群实现原理,如果你真的能看的进去,相信对你在以后用到redis时会有一定的帮助。写到
Redis学习笔记(二十一) 事务
2017-07-23

Redis学习笔记(十八) 集群(下)

复制和故障转移Redis集群中的节点分为主节点(master)和从节点(slave),其中主节点用于处理槽,而从节点则用于复制某个主节点,并在被复制 的主节点下线时,代替下线主节点继续处理命令请求。设置从节点:CLUSTER REPLICATE 可以让接收命令
Redis学习笔记(十八) 集群(下)
2017-08-15

Redis学习笔记(十一) 服务器

Redis服务器负责与多个客户端建立网络通信,处理客户端发送的命令请求,在数据库中保存客户端执行命令所产生的数据,并通过资源管理来维持服务器自身的运转。 命令请求过程(以set命令为例) 1、客户端向服务器发送命令请求 SET KEY VALUE。 Redis
Redis学习笔记(十一) 服务器
2014-11-11

Redis学习笔记(十七) 集群(上)

Redis集群是Redis提供的分布式数据库方案,集群通过分片来进行数据共享,并提供复制和故障转移操作。一个Redis集群通常由多个节点组成,在刚开始的时候每个节点都是相互独立的,他们处于一个只包含自己的集群当中,我们通过使用CLUSTER MEET命令将节点
Redis学习笔记(十七) 集群(上)
2015-09-17

Python学习笔记整理(十五)类的编写

类代码编写细节一、class语句一般形式class    (superclass,...):    data=value    def mothod(self,...):        self.member=value在cla
2023-01-31

Redis学习笔记(二十) 发布订阅(下)

当一个客户端执行SUBSCRIBE命令订阅某个或某些频道时,这个客户端与被订阅频道之间就建立起了一种订阅关系。Redis将所有频道的订阅关系保存在服务器状态的pubsub_channels字典里面,这个字典的键是某个被订阅的频道,而键的值是一个链表,链表里面记
Redis学习笔记(二十) 发布订阅(下)
2022-03-29

Redis学习笔记(十九) 发布订阅(上)

Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息,它的发布与订阅功能由PUBLISH、SUBSCRIBE、PSUBSCRIBE等命令组成。通过执行SUBSCRIBE命令,客户端可以订阅一个或多个频道,
Redis学习笔记(十九) 发布订阅(上)
2016-04-03

Redis学习笔记:Redis在C#中的使用

1、新建一个WinForm窗体,命名为Main:    2、在NuGet中安装StackExchange.Redis。    3、添加一个类,命名为RedisHelper。 public static class RedisHelper {
Redis学习笔记:Redis在C#中的使用
2017-01-15

Redis学习笔记:C#中的使用

1、新建一个WinForm窗体,命名为Main:    2、在NuGet中安装StackExchange.Redis。    3、添加一个类,命名为RedisHelper。 public static class RedisHelper {
Redis学习笔记:C#中的使用
2016-08-05

编程热搜

目录