RocketMQ的原理分析

rocketMQ集群的工作流程

RocketMQ集群部署结构图:
在这里插入图片描述

  1. 启动Nameserver, NameServer启动后开始监听端口,等待Broker 和 Producer以及Consumer连上来,Nameserver的角色相当于一个注册中心。
  2. Broker启动,跟所有的Nameserver保持长连接,定时发送心跳包。心跳包中包含当前Broker信息(Ip端口以及存储的所有的topic信息)。在Broker注册成功后,Nameserver集群中就有Topic与Broker的映射关系。
  3. 接收和发送消息前,如果没有topic会先创建topic(虽然能够自动创建但是要消耗一定的时间,在生产环境不建议使用),创建topic时需要指定该topic要存储在哪些Broker上。
  4. Producer启动,启动时先与Nameserver集群中的其中一台简历长连接,并从nameserver中获取当前发送的topic存在在哪些Broker上,然后跟对应的Broker建立长连接,直接向Broker发送消息。
  5. Consumer启动与Producer类似,也会与其中一台Nameserver建立长连接,获取当前订阅Topic存储在哪些Broker上,然后直接跟Broker建立长连接,开始消费消息。

每个模块的功能职责

  • NameServer
    NameServer相当于一个注册中心,存储了集群中的所有的Broker与topic的对应关系。
    1. NameServer用于存储Topic, Broker关系信息,功能简单,稳定性高。多个NameServer之间相互没有通信,单台Nameserver宕机不影响其他的nameserver与集群;即使整个nameserver集群宕机,对于已经正常工作的Producer,Consumer,Broker仍然能够正常工作,但新启动的producer,consumer,Broker无法工作,因为没有缓存到nameserver的数据。
    2. NameServer压力不会太大,平时主要开销实在维持心跳和提供Topic以及Broker的映射关系数据上。但是又一点需要注意,Broker向NameServer发送心跳时,会带上当前子集所负责的所有的topic信息,若果topic个数太多(万级别),会导致一次心跳中topic的数据会有几十M,如果网络比较差导致传输失败的话,nameserver没有在规定实现内收到心跳包,误认为Broker没有发送心跳,导致连接断开。
  • Broker
    Broker是集群中最核心的模块,主要负责topic的消息存储,管理和分发等功能。
  1. 高并发读写服务
    Broker的高并发读写主要是依靠两点:
    - 顺序写消息,所有topic数据同时智慧写一个文件,一个文件满1G,再写新的文件,真正的顺序写盘,使得发消息TPS大幅度提升。
    - 随机读取消息,RocketMQ尽可能让读命中系统pagecache,因为操作系统访问pagecache时即使只访问1k的消息,系统也会提前预读取出更多的数据,再下次读取时就可能命中pagecache,减少IO操作。
  2. 负载均衡与动态伸缩
    - 负载均衡:Broker上存topic信息,topic由多个队列组成,队列会平均分散再多个Broker上,而Producer的发送机制保证消息尽量平均分布到所有的队列中,最终效果就是所有消息都会平均的落在每个Broker上面。
    - 动态伸缩能力:Broker的伸缩性体现再两个维度,topic和broker.
    -topic维度:加入一个topic的消息量很大,但是集群压力还是很低,就可以扩大该topic的队列数量,topic的队列数与发送、消费速度成正比。
    -broker维度:如果集群的水位很高的话,如果扩容,那直接加机器部署Broker就可以了。Broker启动后向nameserver注册,Producer consumer通过nameserver发现的新的Broker,立即跟该Broker直连,收发消息。
    1. 高可用
      -高可用:集群部署时一般为竹北,备机实时从主机同步消息,如果其中一个主机宕机,备机提供消息服务,但不提供写服务。
      -高可靠:所有发往broker的消息,有同步刷盘和异步刷盘机制;同步刷盘时,消息写入物理文件才会返回成功,异步刷盘时只有机器宕机,才会产生消息丢失,broker挂掉可能会发送,但是机器宕机或者崩溃的事件很少发生,除非突然断电。
    2. Broker与NameServer的心跳机制
      单个broker与所有nameserver保持长连接,心跳时间间隔为30s,心跳请求包括当前Broker所有的Topic信息,nameserver会反查broker对的心跳信息,如果某个broker在2分钟之内没有心跳,则认为该broker下线,调整topic与broker的映射关系,但是此时nameserver不会主动通知Producer以及Consumer有Broker宕机。
  • Consumer
    消费者启动时需要指定nameserver地址,与其中一个nameserver建立长连接,消费者每隔30s从nameserver获取所有的topic的最新队列情况,这意味着某个broker如果宕机,客户端最多30s能够感知到。连接建立后,从nameserver中获取当前消费topic所涉及的Broker,直接连接Broker.
    Consumer与Broker是长连接,会每隔30s发送心跳报文到broker,broker每10s检查一次当前存活的consumer,若发现某个consumer在2min内没有收到心跳包,就断开与该consumer的连接,并且向该消费组的其他实例发送通知,出发该消费者集群的负载均衡。
    -Consumer的负载均衡:消费者有两种模式消费:集群消费和广播消费。
    1. 集群消费: 一个topic可以由同一个ID下所有消费者分担消费,例如,topicA有6个队列,某个消费者ID起了2个消费者实例,那么每个消费者负责消费3个队列,如果再增加一个消费者ID相同的消费者实例,即当前共有3个消费者同时消费6个队列,那么每个消费者负责消费2个队列。
    2. 广播消费:每个消费者消费topic下的所有队列。
    3. 负载均衡:是在集群消费模式下,如果同一个ID的所有消费者实例平均消费该topic的所有队列,如上面的例子所示。
  • Producer
    Producer启动时,也需要指定Namesrver的地址,从Namesrv集群中选一台建立长连接。如果该Namesrv宕机,会自动连其他Namesrv。直到有可用的Namesrv为止。
    生产者每30秒从Namesrver获取Topic跟Broker的映射关系,更新到本地内存中。再与Topic涉及的所有Broker建立长连接,每隔30秒发一次心跳。在Broker端也会每10秒扫描一次当前注册的Producer,如果发现某个Producer超过2分钟都没有发心跳,则断开连接。
    -生产者端的负载均衡:生产者发送时,会自动轮询当前所有可发送的broker,一条消息发送成功,下次换另外一个broker发送,以达到消息平均落到所有的broker上。这里需要注意一点:假如某个Broker宕机,意味生产者最长需要30s能感知到,在这期间会向宕机的Broker发送消息,当一条消息发送到某个Broker失败后,会往该broker自动再重发2次,假如还是发送失败,则抛出发送失败异常。业务捕获异常,重新发送即可。客户端里会自动轮询另外一个Broker重新发送,这个对于用户是透明的。
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值