当前位置: 首页 > 科技观察

RocketMQ的基本概念和架构——RocketMQ知识体系(一)

时间:2023-03-12 03:50:28 科技观察

前面几篇分享了Kafka相关的实现逻辑。Kafka在大吞吐量方面有不错的表现,但是有时候我们需要实现更复杂的业务逻辑,对吞吐量要求不高。这时候我们可以选择RocketMQ。有了Kafka,为什么还需要RocketMQ?我们知道Kafka的性能非常好,吞吐量也非常大。Kafka的单机写入TPS号称每秒百万条记录;如果追求性能,Kafka的单机性能更高。这也依赖于它的顺序写入、内存映射文件技术和消费者端的零拷贝。(kafka基于sendfile实现了ZeroCopy,直接从内核空间(DMA)到内核空间(Socket),然后发送网卡。)但是对于日常工作和业务中对数据可靠性要求严格的各种复杂应用场景我我有点不知所措。我们从以下几个方面来分析:【数据可靠性】RocketMQ支持的同步方式提高了数据可靠性。RocketMQ支持异步/同步刷机;异步/同步复制;Kafka使用异步刷写和异步复制。【消息排序】Kafka在某些配置下支持消息排序,但是当某个Broker宕机时,消息会乱序;RocketMQ支持严格的消息顺序。在顺序消息场景下,一个Broker宕机后,发送消息会失败,但不会乱序;【关于定时/延时消息】Kafka不支持定时消息;RocketMQ支持定时消息;【关于分布式事务消息】Kafka不支持分布式事务消息;RocketMQ支持分布式事务Message【关于消息查询机制】Kafka不支持消息查询。RocketMQ支持根据MessageId查询消息,也支持根据消息内容查询消息【关于Broker设计】当broker中topic分区过多时,Kafka的性能不如rocketMQ。kafka和rocketMq都是使用文件存储,但是kafka是一个分区,一个文件。当主题过多时,分区总数也会增加。kafka文件太多。当消息被刷新时,会出现文件对磁盘的竞争,出现性能下降。一个分区(partition)一个文件,顺序读写。一个partition只能被一个consumergroup中的一个consumerthread消费,所以可以同时消费的consumer较少。rocketMq的所有队列都存储在一个文件中,每个队列存储的消息量比较少,所以topic的增加对rocketMq的性能影响不大。RocketMq可以有很多topic,可以适应更复杂的业务。RocketMQ架构设计RocketMq技术架构RocketMQ架构主要分为四个部分,如上图所示:Producer:消息发布的角色,支持分布式集群部署。Producer通过MQ负载均衡模块选择对应的Broker集群队列进行消息传递。交付过程支持快速失败和低延迟。Consumer:消息消费的角色,支持分布式集群部署。它支持推送和拉取两种模式来消费消息。同时还支持集群模式和广播模式消费。它提供了实时的消息订阅机制,可以满足大多数用户的需求。NameServer:NameServer是一个非常简单的主题路由注册中心,其作用类似于Dubbo中的zookeeper,支持Broker的动态注册和发现。主要包括两个功能:Broker管理,NameServer接受Broker集群的注册信息,并保存为路由信息的基础数据。然后提供心跳检测机制,检查Broker是否还活着;路由信息管理,每个NameServer都会保存Broker集群的整个路由信息和队列信息,供客户端查询。然后Producer和Conumser可以通过NameServer知道整个Broker集群的路由信息??,从而进行消息的传递和消费。NameServer通常也部署在集群中,实例之间不通信。Broker向每个NameServer注册自己的路由信息??,因此每个NameServer实例都保存了一个完整的路由信息??。当一个NameServer由于某种原因下线时,Broker仍然可以将自己的路由信息??同步给其他NameServer,Producer和Consumer仍然可以动态感知Broker的路由信息??。但是NameServer不像ZKBrokerServer那样提供选举功能:Broker主要负责消息的存储、传递和查询,以及服务的高可用保证。为了实现这些功能,Broker包含了以下几个重要的子模块。RemotingModule:整个Broker实体负责处理来自客户端的请求。ClientManager:负责管理客户端(Producer/Consumer),维护Consumer的Topic订阅信息。StoreService:提供方便简单的API接口来处理消息到物理硬盘的存储和查询功能。HAService:高可用服务,提供MasterBroker和SlaveBroker之间的数据同步功能。IndexService:根据特定的Messagekey,对传递给Broker的消息进行索引,提供消息的快速查询。RocketMq架构部署RocketMQ网络部署特点NameServer是一个几乎无状态的节点,可以部署在集群中,节点之间不需要任何信息同步。Broker部署相对复杂。Broker分为Master和Slave。一个Master可以对应多个Slave,但一个Slave只能对应一个Master。通过指定相同的BrokerName和不同的BrokerId来定义Master和Slave的对应关系。BrokerId为0表示Master,非0表示Slave。Master也可以部署多个。每个Broker与NameServer集群中的所有节点建立持久连接,并定期向所有NameServers注册Topic信息。注意:目前RocketMQ版本在部署架构上支持一Master多Slave,但只有BrokerId=1的Slave服务器才会参与消息读取负载。Producer与NameServer集群中的其中一个节点(随机选择)建立长连接,定时从NameServer获取Topic路由信息,与提供Topic服务的Master建立长连接,并定时向Master发送心跳。Producer是完全无状态的,可以集群部署。Consumer与NameServer集群中的其中一个节点(随机选择)建立长期连接,定时从NameServer获取Topic路由信息,与提供Topic服务的Master和Slave建立长期连接,并向Master和Slave发送心跳定期奴隶。消费者可以订阅来自Master或来自Slave的消息。消费者从Master拉取消息时,Master服务器会根据拉取offset与最大offsetI/O的距离判断是否读取旧消息),服务器是否可读等因素建议是否从Master拉取或下次奴隶。结合部署架构图,描述一下集群工作流程:启动NameServer,NameServer起床后监听端口,等待Broker、Producer、Consumer连接起来,相当于一个路由控制中心。Broker启动,与所有NameServers保持长连接,定时发送心跳包。心跳包中包含当前的Broker信息(IP+端口等),存储了所有的Topic信息。注册成功后,在NameServer集群中就有了Topic和Broker的映射关系。在发送和接收消息之前,先创建一个主题。创建主题时,您需要指定主题将存储在哪些代理上。您还可以在发送消息时自动创建主题。生产者发送消息。启动时,首先与其中一个NameServer集群建立长连接,并从NameServer中获取当前发送的Topic存在于哪个Brokers上,从队列列表中轮询选择一个队列,然后与所在的Broker建立队列队列位于。长连接向Broker发送消息。消费者类似于生产者。与其中一台NameServer建立长连接,获取当前订阅的Topic存在于哪些Broker上,然后直接与Broker建立连接通道开始消费消息。模块间数据流转生产消费模型生产消费流程