Kylin Server V10 下 RocketMQ 主备自动切换模式部署

news2024/12/23 14:47:28
一、NameServer简介

        NameServer 是一个注册中心,提供服务注册和服务发现的功能。NameServer 可以集群部署,集群中每个节点都是对等的关系,节点之间互不通信。

服务注册

        Broker 启动的时候会向所有的 NameServer 节点进行注册,注意这里是向集群中所有的 NameServer 节点注册,而不是只向其中的某些节点注册,因为 NameServer 每个节点都是对等的,所以 Broker 需要向每一个节点进行注册,这样每一个节点都会有一份 Broker 的注册信息。

服务发现

        Broker 向 NameServer 注册以后,生产者 Producer 和消费者 Consumer 就可以从 NameServer 中获取所有注册的 Broker 信息,不过由于 NameServer 每个节点是对等的,所以生产者和消费者需要感知所有的 NameServer, 之后选取一个 NameServer 从中获取 Topic 的路由信息,再向对应的 Broker 进行消息的发送和消费。

        以生产者为例,在 NameServer 集群部署模式下,生产者会从多个 NameServer 中随机选取一个进行通信,从中拉取所有 Broker 的注册信息,并将拉取到的信息进行缓存,生产者知道了 Broker 的信息后,就可以得知 Topic 的分布情况,然后选取一个消息队列,与其所在的 Broker 通信进行消息的发送。如果通信的 NameServer 宕机,消费者会轮询选择下一个 NameServer。

为什么需要 NameServer ?

        在使用 RocketMQ 的时候,为了提升性能以及应对高并发的情况,一般都会使用多个 Broker 进行集群部署,假设没有注册中心,对于 Broker 来说,如果想获取到集群中所有的 Broker 信息(生产者和消费者需要通过某个 Broker 获取整个集群的信息,从而得到Topic 的分布情况),每个 Broker 都需要与其他 Broker 通信来交换信息,以此来得到集群内所有 Broker 的信息,在 Broker 数量比较大的情况下,会造成非常大的通信压力。

Broker 注册

        Broker 启动后开启定时向 NameServer 进行注册(发送心跳包)的任务,发送心跳包的时间间隔可以在配置文件中进行设置,但是最长不能超过10s ,也就是说 Broker 最长10秒钟会向 NameServer 发送一次心跳包。

        NameServer 收到 Broker 的注册请求(心跳包)后,会判断 Broker 之前是否已经注册过,如果未注册过将其加入到注册的 Broker 集合 brokerAddrTable 中,同时也会记录收到注册请求的时间,将其加入到 brokerLiveTable 中,里面记录了 NameServer 收到每个 Broker 发送心跳包的时间,在进行心跳检测的时候根据这个时间戳来判断是否在规定时间内未收到该 Broker 发送的心跳包。

读写锁

        由于 NameServer 可能同时收到多个 Broker 的注册以及生产者或者消费者的拉取请求,为了保证数据的一致性(因为有读写请求同时发生或者写与写请求同时发生),在处理相关请求的时候需要加锁,为了提高性能,使用了 ReadWriteLock 读写锁,处理注册请求时会先添加写锁,外理拉取请求时添加读锁,这样如果某一时刻都是读的请求可以同时进行,互不影响,如果有写请求,其他请求就需要等锁释放才可以进行往下进行。如果不使用读写锁,直接对所有的请求加锁,会影响性能,实际上读与读之间并不需要加锁。

心跳检测

        NameServer 在启动的时候会开启一个用于心跳检测的定时任务(每10s执行一次),定时扫描处于不活跃状态的 Broker, 如果在规定时间内未收到某个 Broker 的心跳包,会认为此 Broker 不可用,需要将其进行剔除。

        brokerLiveTable 保存了当前 NameServer 收到的心跳数据,里面记录了每一个 Broker 最近进行注册/发送心跳的时间戳,所以只需遍历 brokerLiveTable, 获取每一个 Broker 最近一次发送心跳的时间进行判断,如果上一次发送心跳的时间 + 过期时间(120s)小于当前时间,也就是超过 120s 没有收到某个 Broker 的心跳包,则认为此 Broker 已下线,将 Broker 移除。

Broker 下线

正常下线

        当 Broker 下线的时候会向 NameServer 发起取消注册的请求,NameServer 收到请求后会将 Broker 剔除。

异常下线

        如果 Broker 异常宕机,或者发送给 NameServer 的取消注册请求由于某些原因并未发送成功,NameServer 可能并未感知到 Broker 的下线,由于心跳机制定时检测的功能,会在一段时间后发现未收到 Broker 的心跳请求,主动将 Broker 剔除。

生产者和消费者

        生产者和消费者都会定时从 NameServer 中更新 Broker 的注册信息,默认是30s 进行一次更新。

二、Controller 模式简介

        在RocketMQ 5.0 以前,有两种集群部署模式,分别为主从模式(Master-Slave模式)和 Dledger 模式。

主从模式

        主从模式中分为 Master 和 Slave 两个角色,集群中可以有多个 Master 节点,一个 Master 节点可以有多个 Slave 节点。Master 节点负责接收生产者发送的写入请求,将消息写入 CommitLog 文件,Slave 节点会与 Master 节点建立连接,从 Master 节点同步消息数据(有同步复制和异步复制两种方式)。

        消费者可以从 Master 节点拉取消息,也可以从 Slave 节点拉取消息。

在 RocketMQ 4.5 版本之前,如果 Master 宕机,不支持将 Slave 切换为 Master, 需要人工介入。

Dledger 模式

        为了解决主从架构下 Slave 不能自动切换为 Master 的问题,4.5 版本之后提供了 DLedger 模式,使用 Raft 算法,如果 Master 节点出现故障,可以自动从 Slave 节点中选举出新的 Master 进行切换。

存在问题

(1)根据 Raft 算法的多数原则,集群至少有三个节点以上,在消息写入时,也需要大多数的 Follower 节点响应成功才能认为消息写入成功;

(2)Dledger 模式下,进行消息写入的时候,使用的是 openmessaging 包中提供的接口,无法利用 RocketMQ 原生的存储和复制能力(比如非 Dledger 模式下使用暂存池方式写入);

(3)存在两套日志复制流程(主从模式下一套,Dledger 模式一套),不统一;

Controller 模式

        为了解决如上问题,RocketMQ 5.0 以后推出了 Controller 模式,它的特点如下:

(1)在主从部署模式下具备自动切换 Master 的能力;

(2)可以利用 RocketMQ 原生存储复制能力,并统一 RocketMQ 的存储和复制能力;

        RocketMQ 5.0 对Broker 选主相关的功能进行了抽离,放在 Controller 中,实现了在主从部署模式下就可以自动切换 Master, Controller 可以独立部署也可以嵌入在 NameServer 中部署。

独立部署下的 Controller如下所示:

嵌入 NameServer 中的部署图如下所示:

Controller

        也称为 Controller 控制器,一般集群中部署多个 Controller, 使用 Raft 算法选举出一个 Active DLedger Controller 作为主控制器,它主要用来管理一个 SyncStateSet集合,这个集合中存储的是一组跟上 Master 进度的 Broker 节点集合,如果 Controller 发现某个 Master Broker 下线时,会从集合中选出新的 Master Broker 并切换,Controller 可以单独部署也可以嵌在 NameServer 中部署。

SyncStateSet

        SyncStateSet 中维护了一个 Broker 副本组集合,包含当前 Master Broker 和它的 Slave Broker, 需要注意在集合内的节点都是跟上 Master 进度的节点,在节点变更时,由 Master Broker 向 Controller 控制器发起变更请求,更新 Controller 中的 SyncStateSet 数据,在选举 Master 的时候,Controller 只需从这个列表中选出一个节点成为新的 Master 即可。

        节点变更分为 Shrink 操作和 Expand 操作,需要 Master Broker 发起,它会通过定时任务以及在数据同步过程中判断是否需要进行 Shrink 或 Expand。

Shrink

        Shrink 指的是将 SyncStateSet 副本集合中与 Master 节点差距过大的副本移除,差距的判断条件如下:

1.  节点是否与 Master Broker 的连接已断,如果断开需要将该节点从 SyncStateSet 移除;

2.节点的复制进度是否过大,新增了 haMaxTimeSlaveNotCatchup 参数,Master Broker 会通过定时任务扫描每一个 Slave 节点的复制信息,里面有每个节点上一次跟上 Master 进度的时间戳 lastCaughtUpTimeMs, 如果当前时间减去这个 lastCaughtUpTimeMs 超过了 haMaxTimeSlaveNotCatchup 的值,会认为该 Slave 节点的复制进度过后;

haMaxTimeSlaveNotCatchup:表示Slave没有跟上 Master 的最大时间间隔,若在 SyncStateSet 中的 slave 超过该时间间隔会将其从 SyncStateSet 移除。默认为 15000(15s)。

Expand

        如果 Master Broker 发现某个 Slave 节点赶上了 Master 节点的进度,需要将其重新加入到 SyncStateSet 。

        需要注意以上两个操作,都需要 Master Broker 向 Controller 节点发送通知,请求更新 SyncStateSet 中的数据。

选举 Master

        不管是 Controller 独立部署,还是嵌入到 NameServer 中部署,Controller 都会监听每个 Broker 的连接,Broker 会定期向 Controller 发送心跳包,Controller 会定时扫描,如果某个 Broker 心跳包发送超时,会认为这个 Broker 已经失效,此时会判断 Broker 是否是 Master 角色,如果是 Master 角色就需要从该组的 SyncStateSet 中重新选出一个节点作为 Master。

        选举 Master 的方式比较简单,从该组的 SyncStateSet 中,挑选一个心跳包发送正常的 Slave 成为新的 Master 节点即可,并将结果通知到该组所有的 Broker, 每个Broker 也会定时向 Controller 发送请求获取主备信息。

Broker 端设计

        主从架构部署模式下,需要配置 brokerRole 和 brokerId,也就是手动分配 Master 和 Slave,在 Controller 模式下,这两个参数会失效,不需要再进行配置,角色和 ID 由 Controller 来分配。

        Controller 模式下增加了 controllerAddr 参数,Broker 在启动时,需要配置这个参数,设置每个controller 的地址:

controllerAddr:controller的地址,多个controller中间用分号隔开。例如controllerAddr = 127.0.0.1:9877;127.0.0.1:9878;127.0.0.1:9879

Broker 上线

        Broker 配置了每个 Controller 的地址,Broker 启动时,会先向 Controller 注册,并获取角色关系和 brokerId, 通过角色关系可以知道自己是 Master 还是 Slave,之后再向 NameServer 注册。

        Broker 可以通过任意一个 Controller 获取 Active Controller 节点的 IP,后台也会有一个定时任务,定时更新 Active Controller 节点的 IP。

主备关系确定

        初始化时,第一个 Broker 在向 Controller 注册的时候,此时并没有该 Broker 组的 SyncStateSet, 所以 Active Controller 会将第一个向其发送请求共识的 Broker 设置为 Master , 之后该组的其他节点会设置为 Slave, Master 节点的 brokerId 为 0,Slave 节点从1 开始编写,往后递增。

        由于 Controller 控制每个节点的角色,所以每个 Broker 也会定时向 Controller 发送请求获取主备信息,以便在角色发生变化的时候可以及时更新。

日志复制

  1. MasterEpoch (Epoch): Master 的任期号,与 Term 类似,每一任 Master 都会有一个对应的 MasterEpoch 任期号,这个任期号的值由 controller

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2252377.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ESP32+VSCODE开发过程无法使用Debug调试问题解决

1.点击Debug按钮报错 Error: libusb_open() failed with LIBUSB_ERROR_ACCESS Error: esp_usb_jtag: could not find or open device! 2.解决办法 1.找见espidf的安装目录下的如下文件(如下自己的安装目录) home\fjq\esp-idf\espidfv5.3.1\tools\tool…

【CSS】一篇掌握CSS

不是因为有了希望才去坚持,而是坚持了才有了希望 目录 一.导入方式 1.行内样式 2.内部样式 3.外部样式(常用) 二.选择器 1.基本选择器(常用) 1.1标签选择器 1.2类选择器 1.3id选择器 2.层次选择器 2.1后代选择器 2.2子选择器 2.3相邻兄弟选择器 2.4通用兄弟选择器…

MySQL底层概述—6.索引原理

大纲 1.索引原理 2.二叉查找树 3.平衡二叉树(AVL树) 4.红黑树 5.B-Tree 6.BTree 7.Hash索引 8.聚簇索引与非聚簇索引 1.索引原理 索引会在数据文件中(ibd文件),通过数据页(Page)进行存储。索引可以加快检索速度,但也会降低增删改速度&#xff0…

C语言学习笔记:循环结构

循环结构 什么是循环 代码的重复执行,就叫做循环。 循环的分类 无限循环:程序设计中尽量避免无限循环,其实就是死循环。程序中的无限循环必须是可控的。有限循环:循环限定循环次数或者循环的条件。 循环的构成: …

stable diffusion实践操作-大模型介绍:SD的发展历史,SD1.5和SDXL之间的差别

大家有没有这样的困惑:在找模型时,老是会出现一些奇怪的标签,像 sd1.5、sdxl 之类的模型后缀,真让人摸不着头脑,一会儿 1.0,一会儿 1.5,一会儿 XL,完全搞不清楚状况。今天就来给大家…

AI高中数学教学视频生成技术:利用通义千问、MathGPT、视频多模态大模型,语音大模型,将4个模型融合 ,生成高中数学教学视频,并给出实施方案。

大家好,我是微学AI,今天给大家介绍一下AI高中数学教学视频生成技术:利用通义千问、MathGPT、视频多模态大模型,语音大模型,将4个模型融合 ,生成高中数学教学视频,并给出实施方案。本文利用专家模…

PyCharm中Python项目打包并运行到服务器的简明指南

目录 一、准备工作 二、创建并设置Python项目 创建新项目 配置项目依赖 安装PyInstaller 三、打包项目 打包为可执行文件 另一种打包方式(使用setup.py) 四、配置服务器环境 五、上传可执行文件到服务器 六、在服务器上运行项目 配置SSH解释器 配置部署 上传代…

git clone超大仓库时报错:fatal: early EOF

环境版本: 系统:Ubuntu git版本:version 2.43.0 在执行git clone命令时报错,信息如下: 系统:Win10 git版本:version 2.47.0 解决办法1: 1、关闭压缩: git conf…

C++基础:list的基本使用

文章目录 1.基本构造和插入删除基本构造和尾插数据迭代器的分类内置排序sort任意位置插入删除 2.链表的合并,去重和剪切链表的合并链表去重链表的剪切 list的本质就是带头双向循环列表 1.基本构造和插入删除 基本构造和尾插数据 与之前vector的方法相同直接调用即可 迭代器的分…

C++ explicit关键字的作用

C explicit关键字的作用 explicit的作用 这个关键字只能用于类的构造函数,被修饰的构造函数不能发生相应的隐式类型转换,只能以显式的方式进行类型转换。 另外,这个关键字只能用于单个参数(这里的单个参数包括多参但是具有默认…

Leecode刷题C语言之N皇后②

执行结果:通过 执行用时和内存消耗如下: struct hashTable {int key;UT_hash_handle hh; };struct hashTable* find(struct hashTable** hashtable, int ikey) {struct hashTable* tmp NULL;HASH_FIND_INT(*hashtable, &ikey, tmp);return tmp; }void insert(…

全场景——(八)低成本 Modbus 传感器的实现

文章目录 一、硬件资源介绍与接线二、创建与体验第 1 个工程2.1 创建工程2.2 配置调试器2.3 配置 GPIO 操作 LED 三、UART 编程3.1 使用 STM32CubeMX 进行配置3.1.1 UART13.1.2 配置 RS485方向引脚 3.2 封装 UART3.3 上机实验3.3.1 硬件连接3.3.2 STM32H5 程序改造3.3.3 STM32F…

如何实现一套键盘鼠标控制两台计算机(罗技Options+ Flow功能快速实现演示)

需求背景 之前我写过一篇文章如何实现一套键盘鼠标控制两台计算机(Mouse Without Borders快速上手教程)_一套键鼠控制两台电脑-CSDN博客 当我们在局域网内有两台计算机,想使用一套键鼠操控时,可以安装Mouse Without Borders软件…

MacOS 配置github密钥

MacOS 配置github密钥 1. 生成GitHub的SSH密钥对 ssh-keygen -t ed25519 -C "xxxxxxx.com" -f ~/.ssh/id_ed25519_github 其中 xxxxxxxxxxx.com 是注册github、gitee和gitlab的绑定账号的邮箱 -t ed25519:生成密钥的算法为ed25519(ed25519比rsa速度快&…

嵌入式Linux之wifi配网脚本分析

嵌入式Linux系统,一般都支持wifi联网,可以通过sh脚本或其它语言代码编程来实现wifi联网。 本篇来介绍一种通过sh脚本来配置wifi的脚本执行原理。 1 sh脚本wifi联网介绍 这里以飞凌开发板中的wifi启动脚本为例来介绍。 在飞凌开发板的串口中,执行如下命令(调用fltest_wif…

Cursor安装与使用,5分钟完成需求

Cursor简单介绍 Cursor是一款基于AI的代码编辑器,旨在帮助开发者更高效地编写和管理代码。它提供了智能代码补全、AI对话和跨文件编辑等创新功能。 一、安装下载 1、下载cursor:https://www.cursor.com/ 2、注册账号,直接拿自己的邮箱登录…

Ubuntu 20.04 Server版连接Wifi

前言 有时候没有网线口插网线或者摆放电脑位置不够时,需要用Wifi联网。以下记录Wifi联网过程。 环境:Ubuntu 20.04 Server版,无UI界面 以下操作均为root用户,如果是普通用户,请切换到root用户,或者在需要权…

IDEA 2024 配置Maven

Step 1:确定下载Apache Maven版本 在IDEA 2024中,随便新建一个Maven项目; 在File下拉菜单栏中,找到Setings; 在Build,Execution,Deployment中找到Maven 确定下载的Apache Maven版本应略低于或等于IDEA绑…

困扰解决:mfc140u.dll丢失的解决方法,多种有效解决方法全解析

当电脑提示“mfc140u.dll丢失”时,这可能会导致某些程序无法正常运行,给用户带来不便。不过,有多种方法可以尝试解决这个问题。这篇文章将以“mfc140u.dll丢失的解决方法”为主题,教大家有效解决mfc140u.dll丢失。 判断是否是“mf…

《只狼》运行时提示“mfc140u.dll文件缺失”是什么原因?“找不到mfc140u.dll文件”要怎么解决?教你几招轻松搞定

《只狼》运行时提示“mfc140u.dll文件缺失”的科普与解决方案 作为一名软件开发从业者,在游戏开发和维护过程中,我们经常会遇到各种运行时错误和系统报错。今天,我们就来探讨一下《只狼》这款游戏在运行时提示“mfc140u.dll文件缺失”的原因…