小伙伴,对于RocketMQ三——系统架构和RecoketMQ的架构原理和使用方式,很多人可能不是很了解。因此,今天我将和大家分享一些关于RocketMQ三——系统架构和RecoketMQ的架构原理和使用方式的知识,希望能够帮助大家更好地理解这个话题。

本文目录一览

RocketMQ(三)——系统架构

RocketMQ架构上主要分为四部分构成:

消息生产者,负责生产消息。Producer通过MQ的负载均衡模块选择相应的Broker集群队列进行消息投递,投递的过程支持快速失败并且低延迟

RocketMQ中的消息生产者都是以生产者组(ProducerGroup)的形式出现的。生产者组是同一类生产者的,这类Producer发送相同Topic类型的消息。一个生产者组可以同时发送多个主题的消息。

消息消费者,负责消费消息。一个消息消费者会从Broker服务器中获取到消息,并对消息进行相关业务处理

RocketMQ中的消息消费者都是以消费者组(ConsumerGroup)的形式出现的。消费者组是统一类消费者的,这类Consumer消费的是同一个Topic类型的消息。消费者组使得在消息消费方法,实现负载均衡(讲一个Topic中不同的Queue平均分配给同一个ConsumerGroup的不同Consumer,并不是负载均衡)和容错(一个Consumer挂了,该ConsumerGroup中的其他Consumer可以接着消费元Consumer消费的Queue)的目标变得非常容易

消费者组中Consumer的数量应小于等于Topic的Queue数量。如果超出Queue数量,则多出的Consumer将不能消费消息。

不过一个Topic类型的消息可以被多个消费者组同时消费。

NameServer是一个Broker与Topic路由的注册中心,支持Broker的动态注册与发现。
RocketMQ的思想来自于Kafuka,而Kafka是以来了Zookeeper的。所以,在RocketMQ的早期版本也依赖Zookeeper。从3.0开始去掉了Zookeeper的依赖,使用了自己的NameServer。

NameServer通常也是以集群的方式部署,不过,NameServer是无状态的,即NameServer集群中的各个节点之间是无差异的,各个节点相互不进行信息通讯。那各个节点中的数据是如何进行数据同步的呢?在Broker节点启动时,轮询NameServer列表,与每个NameServer节点建立长连接,发起注册请求。在NameServer内部维护者一个Broker列表,用来动态存储Broker信息

Broker节点为了证明自己是活着的,为了维护与NameServer间的长连接,会将最新的信息以心跳包的方式上报给NameServer,每30秒发送一次心跳。心跳包中包含BrokerId、Broker地址(IP+Port)、Broker名称、Broker所属集群名称等等。NameServer在接收到心跳包后,会更新心跳时间戳,记录这个Broker的最新存活时间。

由于Broker关机、宕机或网络抖动等原因,NameServer没有收到Broker的心跳,NameServer可能会将其从Broker列表中剔除
NameServer中有一个定时任务,每隔10秒就会扫描一次Broker表,查看每一个Broker的最新心跳时间戳距离当前时间是否超过120秒,如果超过,则会判定Broekr失效,然后将其从Broker列表中剔除。

RocketMQ的路由发现采用的是Pull模型。当Topic路由信息出现变化时,NameServer不会主动推送给客户端,而是客户端定时拉取最新的路由。默认每30秒拉取一次最新的路由

客户端再配置时必须要写上NameServer集群的地址,那么客户端道理连接在哪个NameServer节点呢?客户端首先会生产一个随机数,然后再与NameServer节点数取模,此时得到的就是要连接的节点索引,然后就会进行连接。如果连接失败,则会采用round-robin策略,逐个尝试去连接其他节点。
首先采用的是随机策略进行选择,失败后采用的是轮询策略。

Broker充当着消息中转角色,负责存储消息、转发消息。Broker在RocketMQ系统中负责接收并存储从生产者发送来的消息,同时为消费者的拉取请求作准备。Broker同时也存储着消息相关的元数据,包括消费者组、消费进度偏移offset、主题、队列等

RemotingModule:整个Broker的实体,负责处理来自clients端的请求。而这个Broker实体则由以下模块构成。
ClientManager:客户端管理器。负责接收、解析客户端(Producer/Consumer)请求,管理客户端。
StoreService:存储服务。提供方便简单的API接口,处理消息存储到物理硬盘和消息查询功能。
HAService:高可用服务,提供MasterBroker和SlaveBroker之间的数据同步功能。
IndexService:索引服务。根据特定的MessageKey,对投递到Broker的消息进行索引服务,同时也提供根据MessageKey对消息进行快速查询的功能

为了增强Broker性能与吞吐量,Broker一般都是以集群形式出现的。各集群节点中可能存放着相同Topic的不同Queue。
如果某Broker节点宕机,如何保证数据不丢失呢?
其解决方案是,将每个Broekr集群节点进行横向扩展,即将Broker节点再建为一个HA集群,解决单点问题。
Broker节点集群是一个主从集群,即有Master和Slave两种角色。Master负责处理读写操作请求,Slave负责对Master中的数据进行备份。当Master挂掉了,Slaver会自动切换为Master去工作。所以这个Broker集群式主备集群。Master与Slave的对应关系是通过指定相同的BrokerName、不同的BrokerId来确定的。BrokerId为0表示Master,非0表示Slave。每个Broker与NameServer集群中的所有节点建立长连接,定时注册Topic信息到所有NameServer。

①启动NameServer,NameServer启动后开始监听端口,等待Broker、Producer、Consumer连接
②启动Broker时,Broker会与所有的NameServer保持长连接,每30秒向NameServer定时发送心跳包
③发送消息前,可以先创建Topic,创建Topic时需要指定该Topic要存储在哪些Broker上,当然,在创建Topic时也会将Topic与Broker的关系写入到NameServer中。也可以在发送消息时自动创建Topic。
④Producer发送消息,启动时先跟NameServer集群中的其中一台建立长连接,并从NameServer中获取路由信息,即当前发送Topic的Queue与Broker地址的映射关系。然后根据算法策略从队选择一个Queue,与队列所在的Broker建立长连接从而向Broker发送消息。
⑤Consumer与Producer类似,跟其中一台NameServer建立长连接,获取其所订阅Topic的路由信息,然后根据算法策略从路由信息中获取到其要消费的Queue,然后与Broker建立长连接,消费其中的消息。Consumer会向Broker发送心跳,以确保Broker的存活状态

手动创建Topic时,有两种模式:

自动创建Topic时,默认采用的是Broker模式,会为每个Broker默认创建四个Queue

从物理上讲,读/写队列是同一个队列。所以,不存在读/写队列数据同步问题。读/写队列是逻辑上进行区分的概念。一般来说,读/写队列数量是相同的。

读/写队列数量不同是有问题的。
但这样可以方便缩容
perm用于设置对当前创建Topic的操作权限:2表示只写,4表示只读,6表示读写

返回目录

RecoketMQ的架构原理和使用方式

我们想要知道的关于RocketMQ的东西有哪些。比如:
RocketMQ是如何集群化部署来承载高并发访问的?
如果RocketMQ中要存储海量消息,如何实现分布式存储架构?
有大量的系统都要往RocketMQ里高并发的写入消息,可能达到每秒有几十万请求,这个时候怎么办呢?
没关系,RocketMQ是可以集群化部署的,可以部署在多台机器上,假设每台机器都能抗10万并发,然后你只要让几十万请求分散到多台机器上就可以了,让每台机器承受的QPS不超过10万不就行了。

这其实就是RocketMQ集群化部署抗下高并发的主要原理,当然,具体怎么做才能让系统的流量分散在RocketMQ部署的多台机器上,这个以后再找机会做一个比较详细的分享,今天主要先讲大体上的一个架构原理。
MQ如果要存储海量消息应该怎么做?
现在来说第二个问题,MQ会收到大量的消息,这些消息并不是立马就会被所有的消费方获取过去消费的,所以一般MQ都得把消息在自己本地磁盘存储起来,然后等待消费方获取消息去处理。
既然如此,MQ就得存储大量的消息,可能是几百万条,可能几亿条,甚至万亿条,这么多的消息在一台机器上肯定是没法存储的,RocketMQ是如何分布式存储海量消息的呢?
延续上面的图,其实发送消息到MQ的系统会把消息分散发送给多台不同的机器,假设一共有1万条消息,分散发送给10台机器,可能每台机器就是接收到1000条消息,如下图:

其次,每台机器上部署的RocketMQ进程一般称之为Broker,每个Broker都会收到不同的消息,然后就会把这批消息存储在自己本地的磁盘文件里。
这样的话,假设你有1亿条消息,然后有10台机器部署了RocketMQ的Broker,理论上不就可以让每台机器存储1000万条消息了吗?

所以本质上RocketMQ存储海量消息的机制就是分布式的存储
所谓分布式存储,就是把数据分散在多台机器上来存储,每台机器存储一部分消息,这样多台机器加起来就可以存储海量消息了!
高可用保障:万一Broker宕机了怎么办?
要是任何一台Broker突然宕机了怎么办?那不就会导致RocketMQ里一部分的消息就没了吗?这就会导致MQ的不可靠和不可用,这个问题怎么解决?
RocketMQ的解决思路是Broker主从架构以及多副本策略。
简单来说,Broker是有Master和Slave两种角色的

MasterBroker收到消息之后会同步给SlaveBroker,这样SlaveBroker上就能有一模一样的一份副本数据!这样同一条消息在RocketMQ整个集群里不就有两个副本了,一个在MasterBroker里,一个在SlaveBroker里!
这个时候如果任何一个MasterBroker出现故障,还有一个SlaveBroker上有一份数据副本,可以保证数据不丢失,还能继续对外提供服务,保证了MQ的可靠性和高可用性。
数据路由:怎么知道访问哪个Broker?
现在又有一个问题了,对于系统来说,要发送消息到MQ里去,还要从MQ里消费消息,那么大家怎么知道有哪些Broker?怎么知道要连接到哪一台Broker上去发送和接收消息?这是一个大问题!
所以RocketMQ为了解决这个问题,有一个NameServer的概念,他也是独立部署在几台机器上的,然后所有的Broker都会把自己注册到NameServer上去,NameServer不就知道集群里有哪些Broker了?

然后对于我们的系统而言,如果他要发送消息到Broker,会找NameServer去获取路由信息,就是集群里有哪些Broker等信息
如果系统要从Broker获取消息,也会找NameServer获取路由信息,去找到对应的Broker获取消息。

问题点:
1.发送消息的时候面对N多台机器,到底应该向哪一台上面的Broker发送过去?
2.RocketMQ的数据模型是什么,我们发送消息过去的时候,是发送到什么里面去,队列还是什么?
3.RocketMQ接收到数据之后是直接写磁盘吗,那性能会不会太差了?
4.主从同步方式以及延迟问题

返回目录

总结:以上就是本站针对你的问题搜集整理的答案,希望对你有所帮助。