深入拆解消息队列 47 讲
许文强
前腾讯云 Kafka 技术负责人
5385 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 50 讲
深入拆解消息队列 47 讲
15
15
1.0x
00:00/00:00
登录|注册

15|集群:如何构建分布式的消息队列集群?(上)

etcd
ZooKeeper
Kafka KRaft
Elasticsearch
ZooKeeper
etcd
ZooKeeper
Kafka KRaft
单机或分布式数据库
etcd
ZooKeeper
Nginx
客户端寻址
服务端转发
Nginx
更新元数据
通知节点切换Leader
触发Leader切换
监听节点存活状态
保存元数据
通知节点创建分区
计算新分区所在节点
Controller接收扩容指令
删除元数据
Controller通知节点删除分区和副本
客户端发送删除指令
Broker创建Topic和分区
元数据保存
Controller计算分区和副本
客户端调用Controller
元数据更新
节点心跳
主节点选举
节点注册
Broker
Controller
Metadata Service
依赖第三方组件争抢注册
相互选举
定时探测
主动上报
集中式组件
类广播机制
配置文件
集群内部自实现存储
第三方存储引擎
HTTP Web服务
消息队列
HTTP Web服务
集群构建的流程和操作
主节点选举的实现方式
节点探活的实现方式
节点发现的实现方式
元数据存储的选型和实现
有状态服务和无状态服务的区别
Leader切换
扩容分区
删除Topic
创建Topic
集群启动
集群架构
主节点选举
节点探活
节点发现
元数据存储
无状态服务
有状态服务
总结
集群构建流程拆解
集群构建思路
有状态服务和无状态服务
集群构建

该思维导图由 AI 生成,仅供参考

你好,我是文强。
上节课我们讲到集群的主要功能就是用来提高性能和数据可靠性。从技术上看,设计实现集群化的消息队列主要包含节点发现节点探活元数据存储集群管理四个方面。接下来我们将围绕着这四个方面,用两节课来讲一下具体是怎么思考、怎么实现集群的。

有状态服务和无状态服务

在此之前,我们先来了解一下什么是有状态服务和无状态服务,后面会用到。
在日常开发中,我们经常听到有状态服务和无状态服务这两个词。二者之间最重要的一个区别在于:是否需要在本地存储持久化数据。需要在本地存储持久化数据的就是有状态服务,反之就是无状态服务。
其实我这里想说明的是,有状态服务和无状态服务构建集群的思路是完全不一样的。HTTP Web 服务就是典型的无状态服务。在搭建 HTTP Web 集群的时候,我们经常会使用 Nginx 或者在其他网关后面挂一批 HTTP 节点,此时后端的这批 HTTP 服务节点就是一套集群。
如上图所示,因为 HTTP Web 是无状态的服务,不同的节点不需要知道其他节点的存在。Nginx 认为后端所有的节点的功能是一样的,所以请求经过 Nginx 后,只需要根据一定转发策略,如轮询、加权轮询、按 Key Hash 等将请求转发给后端的 Web 服务节点即可。然后在节点增减的时候,Nginx 会感知到节点的增减,执行转发或者不转发就行了。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了构建分布式消息队列集群的关键技术和流程。首先介绍了有状态服务和无状态服务的区别,以及消息队列集群设计思路中的元数据存储、节点发现和节点探活等关键方面。在设计集群时,需要考虑元数据的可靠存储,节点的发现和探活机制,以及主节点的选举。元数据存储可以选择第三方存储引擎或集群内部自实现存储,而节点发现则可以通过配置文件、类广播机制或集中式组件来完成。节点探活则需要一个角色来对集群内所有节点进行探活或保活。文章还提到了主节点的选举机制,以及不同消息队列使用的实现方式。总的来说,构建分布式消息队列集群需要考虑多个方面,包括元数据存储、节点发现、节点探活和主节点选举等关键技术。 在集群构建流程拆解部分,文章详细介绍了集群启动、创建Topic、Leader切换等动作的流程。集群启动包括节点注册、主节点选举、节点心跳和元数据信息更新等步骤。创建Topic涉及客户端指定分区和副本数量,Controller计算分布并调用各个Broker节点创建Topic、分区、副本。而Leader切换则包括Controller监听节点状态、触发Leader切换操作、通知存活的Broker节点进行Leader切换等步骤。 最后,文章总结了集群构建的思路,包括有状态服务和无状态服务的构建思路,元数据存储、节点发现、节点探活、主节点选举等关键技术。同时,还提出了思考题,引发读者对于集群构建的进一步思考。 总的来说,本文详细介绍了构建分布式消息队列集群的关键技术和流程,对于想要深入了解消息队列集群构建的读者具有很高的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入拆解消息队列 47 讲》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(8)

  • 最新
  • 精选
  • 张申傲
    【思考题——实现分区扩缩容时的注意事项】 1. 新增分区/下线分区的路由信息需要同步到元数据服务 2. 需要考虑分区-消费者之间的Rebalance,期间可能会阻塞消费 3. 扩/缩容后,分区在Broker集群间是否均匀分布,是否会出现数据倾斜的情况 4. 扩/缩容后,新的元数据是否需要同步至客户端,客户端是否有刷新策略或本地缓存过期策略

    作者回复: 回答的很好,很齐全。我补充一点我的看法:除了主流程,我认为需要再考虑一下分区缩容时会出现的数据删除的情况。因为缩容分区肯定会出现删除数据的情况,此时需要和业务方确认是否可以接受删除数据,可以接受删除那些数据。然后再根据业务方的反馈来决定使用哪些手段缩容分区。

    2023-07-24归属地:北京
    1
  • smilekaka
    配置文件一定需要重启?

    作者回复: 从具体实现来看,配置分为动态配置和静态配置两类。 有一部分配置可以是动态配置,这部分配置是允许热变更的,比如某些IO 处理线程数。有一部分配置必须是静态配置,这部分配置的修改需要重启才能生效,比如某些预分配的内存大小。

    2023-11-15归属地:江苏
  • 开发很忙
    老师,您好!节点发现机制中,我的理解是DNS并不属于类广播机制的一种,DNS应该是属于集中式组件,通过集中式的NameServer来进行节点注册以及剔除。而类广播机制则是集群中的每个节点都会向其他的节点广播自己的信息,从而实现节点相互发现和连接,比如Gossip协议。

    作者回复: 你好啊,我感觉这个分类确实不太严谨。我尝试说一下我写的时候的理解: 在节点发现机制中,如果是基于DNS来发现节点。有一种流程是:先解析域名的DNS,通过DNS就可以拿到这个DNS下的所有IP。这些IP就是集群中的所有节点,此时就发现了集群中所有节点。然后再通过选举机制从这些IP中选举出一个Leader进行后续的操作。 在这个流程中,每台节点的IP是通过DNS暴露出去让其他节点发现的。所以有点像每台节点把自己的IP广播暴露出去给其他节点发现。所以我把它放在了类广播机制里面。 其实写的时候也有你这个想法,因为DNS确实不属于广播机制,所以我加了一个“类”字。

    2023-10-12归属地:美国
  • jackfan
    集群启动有一个问题,有一个步骤是broker先在controller上注册,然后再选举出controller,刚开始controller是未知的,怎么在controller上注册?如果是在metadata service上注册,但是最终选取的方案是broker的元数据信息存储在controller上,metadata存储的注册信息是否就是冗余的?

    作者回复: 这里需要稍微更正一下,Broker 一般是往 Meta service 中注册,而不是直接往Controller注册的。下面将问题分为两个问题回答: 1. controller 注册问题:从实现上来看,会先有一个 meta service 服务。此时有一种方案是,通过某种策略在 meta service 中选择出一个节点来当做 controller。另一种方案是,依靠 meta service 在 Broker 中选择出一个 controller。controler 的作用是负责监听 meta service 的信息变更,然后对集群做相关操作,比如修改配置等。 2. 继承上面的逻辑,meta serivce 一般用来持久化存储元数据信息,controller 一般只是缓存数据,不持久化存储。Controller启动时,数据会从Meta Service 读取一份最新的数据。从具体实现来看,如果在 meta service 中选择一个节点当做 controller,那么controller 就不需要再重复缓存,因为每台 meta service 节点都会缓存这部分信息。 最后说一点每台 Broker 也会缓存元数据信息,以避免每次读元信息都从远程读取,导致性能问题。所以说,缓存不应该算冗余。

    2023-10-07归属地:上海
  • shan
    消息队列集群设计总结 一般是基于主从架构设计的,Master节点处理集群相关工作。 1. 元数据存储 集群元数据指的是集群中Topic、分区、权限等信息,需要保证可靠高效的存储。 (1)依赖第三方存储 通过第三方组件完成元数据的存储,比如ZooKeeper、etcd等,优点是无需额外研发,稳定性高,缺点是增加部署维成本。 (2)集群内部实现存储 在消息队列应用内部实现自定义元数据存储服务,优点是部署架构简单轻量,缺点是开发成本高。 2. 节点发送 (1)配置文件方式:通过在配置文件配置所有节点IP,节点启动后根据配置信息找到所有的节点完成节点发现,优点是实现简单,缺点是集群扩容需要修改配置文件重启,ZooKeeper和Kafka KRaft采用的此方案; (2)类广播机制:通过广播、DNS等机制,自动发现集群中所有节点,优点是可以自动发现新节点,自动扩容集群,缺点是开发成本高,RabiitMQ和Elasticsearch采用此方案; (3)集中式组件:所有节点向集中式组件去注册/删除自身节点信息,通过这个组件可以获取所有到节点的信息,完成完成节点发现,优点是可以动态感知节点变更,水平扩容方便,Kafka基于ZooKeeper版本、RocketMQ和Pulsar采用的此方案; 3. 节点探活 分为主动上报(每个节点主动向中心组件定时发送心跳包)和定时探测(中心组件定时向其他所有节点发起探测请求)两种,一般推荐主动上报,因为由中心组件发起探测,节点较多可能会哟性能瓶颈。 4. 主节点选举 (1)通过选举算法,节点之间相互投票,选举Leader,Elasticsearch、Kafka KRaft版本、RocketMQ采用的此方案; (2)引入一个第三方组件来辅助完成节点选举,比如可以在ZooKeeper、etcd上的某个位置写入数据,哪个节点先写入成功就是Leader节点;
    2023-09-24归属地:河南
    1
  • takumi
    关于节点发现中有一段具有歧义,在节点发现中集中式组件基于Zookeeper Kafka RocketMQ Pulsar,查了一下RocketMQ并没有使用Zookeeper。
    2023-09-19归属地:上海
    1
  • 张三
    分区的扩容和缩容从技术上是可以实现的 但是在实际的生产环境中,还不如直接创建一个新的TOPIC更安全,更快捷
    2023-09-13归属地:浙江
  • 新增分区时需要把存活的历史数据,根据新的分区数全部均衡一遍吗?如果不均衡,在需要保证分区消费顺序时,可能会导致一个key的数据分布在两个分区中,两个分区的消费者并行消费导致无法保证顺序。
    2023-08-07归属地:广东
    1
收起评论
显示
设置
留言
8
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部