深入浅出消息队列----【Broker 集群】

2024-08-20 18:36

本文主要是介绍深入浅出消息队列----【Broker 集群】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

深入浅出消息队列----【Broker 集群】

  • 单 master
  • 多 master
  • 多 master 多 slave 异步复制
  • 多 master 多 slave 同步复制
  • Dledger

本文仅是文章笔记,整理了原文章中重要的知识点、记录了个人的看法
文章来源:编程导航-鱼皮【yes哥深入浅出消息队列专栏】

请添加图片描述

Broker cluster 可以分为五类:

  1. 单 master
  2. 多 master
  3. 多 master 多 slave 异步复制
  4. 多 master 多 slave 同步复制
  5. Dledger

单 master

如果我们仅部署了一个 Broker 实例,那么就是单 master 模式。

假设这个 master 宕机了,那么生产者发送消息会失败、消费者拉取消息也会失败。

请添加图片描述

此时整个消息队列就不可用了,影响了线上服务的正常执行。

基本上生产环境不会采取单 master 模式,这种一般只会在测试时候使用。

多 master

如果仅部署一个实例风险太大,那么部署两个就能避免 Broker 单点的风险。

此时两个 Broker 会互相瓜分对应的 Topic 下的队列,比如 TopicA 一共分了 8 哥队列,那么 Broker-1 承担其中的 4 哥,Broker-2 承担另外四个。

请添加图片描述

这样一来,生产者给不同队列发送消息,写入消息的压力已经均匀的分配到两个 Broker 身上了,提升了写消息的性能。

如果此时 Broker-1 宕机了,咋办呢?

生产者发送给 Broker-1 的消息会失败,但是还记得之前说过的同步、异步发送消息,如果发送失败,生产者会默认重试的机制吗?

没错,生产者会重试发送消息,而且此时会自动避让上次发送失败的 Broker,因此发给 Broker-1 失败后,会避让 Broker-1,会选择投递到 Broker-2,所以 Broker-1 宕机不会影响消息的发送。

但对于消费者而言,如果想消费队列-1到队列-4的消息,只能从 Broker-1 拉取,此时拉取肯定是失败的,因此**会影响宕机钱已经发送存储至 Broker-1 但还未被消费的消息,**这些消息的实时性无法保证,只能等 Broker-1 恢复。

不会影响新消息的消费,因为新的消息只会被发往 Broker-2。

这时候,只要 Broker-1 重启,那么消费者就能顺利地拉取之前在 Broker-1 的消息了(如果消息已经被刷盘了的话)。

什么叫刷盘呢?消息发送成功了,不代表一定已经被 Broker 持久化了

一般为了性能,消息写入到 Broker 后,还在页缓存中,不会同步刷到磁盘内,也就是消息写到页缓存就返回消息写入成功,此时如果断电了,那么在页缓存内的数据就没了,消息也就丢了。

请添加图片描述

如果想消息一定不丢,只能是同步刷盘,也就是每次消息写入都直接刷盘,这样消息是不会丢的,但是这样性能不好,这就要根据实际场景进行取舍了。

请添加图片描述

这里需要提一下,上述对生产者发送消息没有影响指的是普通消息,如果是顺序消息则会有影响。

因为顺序消息的实现是选择 Topic 下的某一队列进行发送,如果 Broker-1 宕机,本来都需要发送给队列-1 的消息,此时发送到队列-6,那么队列-1 的消息会宕机了还未被消费,队列-6 后来到的消息反而被消费了,此时消息的顺序性就无法保证了。

多 master 多 slave 异步复制

上述多 master 的模式,如果发生一个实例宕机会影响部分消息的实时性,因此就弄了哥 slave 来作为 master 的 backup。

请添加图片描述

每个 master 对应有一个 slave,正常情况下 slave 只会默默同步 master 的消息,不支持消息的直接写入,正常也不会对外提供消费。

只有当 master 繁忙(例如当拉取的消息太久远了或因为消息堆积严重,消息不在 master 内存中,就会返回繁忙,此时消费者就会去 slave 拉取消息,前提是 slaveReadEnable 参数要设置为 true),或者 master 挂了才会被消费者消费。

总而言之,当 master 不太行的时候,消费者可以选择对应的 slave 拉取消息,这样就避免了 master 不行后消息的实时性问题。

所以 slave 就是个备胎,当 master 不好了,消费者才会来找 slave。

那何为异步复制呢?

生产者将消息写到 master 后就返回成功了,然后 slave 回去 master 同步消息,也因此 slave 上的消息相对于 master 会有一定的滞后性,所以当 master 宕机,消费者从 slave 拉取消息的时候,可能会存在个别消息丢失的情况。

看到这可能有同学会有疑惑:为啥 slave 不能被生产者主动写入消息呐?

理论上是可以的,master 和 slave 都支持写入,但这需要实现 master 和 slave 之间数据的双向同步,互相同步消息保证消息的一致性,但这样会比较麻烦,会牵扯一些冲突,比如消息的顺序冲突等等。

多 master 多 slave 同步复制

如果想要保证 slave 的消息不丢失,那么可以采取同步复制的情况。

所谓同步复制其指的是生产者只有在消息存储到 master 以及对应的 slave 中后,才会得到消息写入成功的结果,这样就保证 slave 不会落后于 master。

也因此,在同步复制的情况下,当 master 挂了,消费者从 slave 拉取到的事完整的消息。

请添加图片描述

当然,这样消息是可靠了,但是对性能会有一定的损耗,因为本来生产者仅需等消息写到 master 就直接返回了,现在还得多等一下,等 slave 也写完了才能返回。

不过这种模式还是无法解决消息写入的问题,即 master 宕机后,消息写入的压力无法被 slave 分担到。

Dledger

Dledger 集群算是 RocketMQ 集群的终极版本了。

Dledger 集群指的是一组具有相同名称的 Broker,至少有 3 哥节点,它们组成 RocketMQ-on-Dledger Group,这个集群基于 raft 协议(一致性协议),实现自动的主从切换。

当主节点挂了,那么集群内会自动选举出新的主节点。

按照 raft 协议的术语,主节点就是 leader,想要组成这个集群,至少需要三台机子,也就是至少还得有 2 哥 follower,这样根据投票的规则,当 leader 挂了,才能自动从 follower 中选出新的 leader,此时就自动完成了主从切换,使得消息能正常的写入。

之前的集群模式,当 master 挂了之后,slave 还是 slave,无法自动被提升为 master,而 Dledger 则可以自动完成主从切换,非常顺滑。

请添加图片描述

之所以可以自动从 follower 中投票选取出 leader 是因为 Dledger 会接管 commitlog 的存储,通过 raft 协议,follower 会同步 leader 的 commitlog,保证消息的一致性。

可以简单理解集群中的消息存储都是一致性的,不会出现消息顺序不一致等数据冲突等问题,因此当 leader 没了,可以从 follower 中选一个提升为 leader,反正消息都是对的。

这个模式的缺点就是需要多点机器才能实现 Dledger 集群,等于以前是一个 master 配备一共 slave,现在是一个 leader 至少配备两个 follower。

这篇关于深入浅出消息队列----【Broker 集群】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1090856

相关文章

服务器集群同步时间手记

1.时间服务器配置(必须root用户) (1)检查ntp是否安装 [root@node1 桌面]# rpm -qa|grep ntpntp-4.2.6p5-10.el6.centos.x86_64fontpackages-filesystem-1.41-1.1.el6.noarchntpdate-4.2.6p5-10.el6.centos.x86_64 (2)修改ntp配置文件 [r

HDFS—集群扩容及缩容

白名单:表示在白名单的主机IP地址可以,用来存储数据。 配置白名单步骤如下: 1)在NameNode节点的/opt/module/hadoop-3.1.4/etc/hadoop目录下分别创建whitelist 和blacklist文件 (1)创建白名单 [lytfly@hadoop102 hadoop]$ vim whitelist 在whitelist中添加如下主机名称,假如集群正常工作的节

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

hdu1180(广搜+优先队列)

此题要求最少到达目标点T的最短时间,所以我选择了广度优先搜索,并且要用到优先队列。 另外此题注意点较多,比如说可以在某个点停留,我wa了好多两次,就是因为忽略了这一点,然后参考了大神的思想,然后经过反复修改才AC的 这是我的代码 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<

搭建Kafka+zookeeper集群调度

前言 硬件环境 172.18.0.5        kafkazk1        Kafka+zookeeper                Kafka Broker集群 172.18.0.6        kafkazk2        Kafka+zookeeper                Kafka Broker集群 172.18.0.7        kafkazk3

poj 3190 优先队列+贪心

题意: 有n头牛,分别给他们挤奶的时间。 然后每头牛挤奶的时候都要在一个stall里面,并且每个stall每次只能占用一头牛。 问最少需要多少个stall,并输出每头牛所在的stall。 e.g 样例: INPUT: 51 102 43 65 84 7 OUTPUT: 412324 HINT: Explanation of the s

poj 2431 poj 3253 优先队列的运用

poj 2431: 题意: 一条路起点为0, 终点为l。 卡车初始时在0点,并且有p升油,假设油箱无限大。 给n个加油站,每个加油站距离终点 l 距离为 x[i],可以加的油量为fuel[i]。 问最少加几次油可以到达终点,若不能到达,输出-1。 解析: 《挑战程序设计竞赛》: “在卡车开往终点的途中,只有在加油站才可以加油。但是,如果认为“在到达加油站i时,就获得了一

poj3750约瑟夫环,循环队列

Description 有N个小孩围成一圈,给他们从1开始依次编号,现指定从第W个开始报数,报到第S个时,该小孩出列,然后从下一个小孩开始报数,仍是报到S个出列,如此重复下去,直到所有的小孩都出列(总人数不足S个时将循环报数),求小孩出列的顺序。 Input 第一行输入小孩的人数N(N<=64) 接下来每行输入一个小孩的名字(人名不超过15个字符) 最后一行输入W,S (W < N),用

POJ2010 贪心优先队列

c头牛,需要选n头(奇数);学校总共有f的资金, 每头牛分数score和学费cost,问合法招生方案中,中间分数(即排名第(n+1)/2)最高的是多少。 n头牛按照先score后cost从小到大排序; 枚举中间score的牛,  预处理左边与右边的最小花费和。 预处理直接优先队列贪心 public class Main {public static voi

Java并发编程之——BlockingQueue(队列)

一、什么是BlockingQueue BlockingQueue即阻塞队列,从阻塞这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞。被阻塞的情况主要有如下两种: 1. 当队列满了的时候进行入队列操作2. 当队列空了的时候进行出队列操作123 因此,当一个线程试图对一个已经满了的队列进行入队列操作时,它将会被阻塞,除非有另一个线程做了出队列操作;同样,当一个线程试图对一个空