一、RocketMQ介绍

       

1、相关术语名词

1.  NameSrv:是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。
2.  Broker:分为Master与Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master,BrokerId为0表示Master,Master与Slave的对应关系通过指定相同的BrokerName,不同的BrokerId来定义,BrokerId为0表示Master,非0表示Slave。Master也可以部署多个。每个Broker与Name Server集群中的所有 节点建立长连接,定时注册Topic信息到所有Name Server。
3.  Producer:向MQ发送消息,与Name Server集群中的其中一个节点(随机选择)建立长连接,定期从Name Server取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳,Producer完全无状态,可集群部署。
4.  Consumer:从MQ消费消息,与Name Server集群中的其中一个节点(随机选择)建立长连接,定期从Name Server取Topic路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。Consumer既可以从Master订阅消息,也可以从Slave订阅消息,订阅规则由Broker配置决定。

5. Push Consumer :Consumer 的一种,应用通常向 Consumer 对象注册一个 Listener 接口,一旦收到消息,Consumer 对象立刻回调 Listener 接口方法。

6. Pull Consumer:Consumer 的一种,应用通常主动调用 Consumer 的拉消息方法从 Broker 拉消息,主动权由应用控制。 

7. Producer Group:用来表示一个发送消息应用,一个Producer Group下包含多个Producer实例,可以是多台机器,也可以是一台机器的多个进程,或者一个进程的多个Producer对象。

8. Consumer Group:用来表示一个消费消息应用,一个Consumer Group下包含多个Consumer实例,可以是多台机器,也可以是多个进程,或者是一个进程的多个Consumer对象。一个Consumer Group下的多个Consumer以均摊方式消费消息,如果设置为广播方式,那么这个Consumer Group下的每个实例都消费全量数据。

2、上图是一个典型的消息中间件收发消息的模型,RocketMQ具有以下特点:

1. 是一个队列模型的消息中间件,具有高性能、高可靠、高实时、分布式特点;
2. Producer、Consumer、队列都可以分布式。
3. Producer向一些队列轮流发送消息,队列集合称为Topic,Consumer如果做广播消费,则一个consumer实例消费这个Topic对应的所有队列,如果做集群消费,则多个Consumer实例平均消费这个topic对应的队列集合。
4. 实时的消息订阅机制。
5. 亿级消息堆积能力。

3、三款常用的消息中间件在性能及其它维度的简单对比

对比项
RabbitMQ
RocketMQ
Kafka

高可用模型/扩展性

集群+镜像队列

主从模式

动态集群+备份

性能

万级吞吐量

十万级吞吐量(批量消息)

百万级吞吐量(批量消息)

开发语言/维护难度

开发语言:Erlang

开发语言:Java

开发语言:Scala+Java

客户端支持

基本支持目前大部分语言

官方支持Java,社区有维护部分语言SDK

官方支持Java,开源维护很多语言的SDK

消费模型

Push / Pull

Push / Pull

Pull

优势

使用资料完善

消息类型丰富,方便定制化开发

大数据生态完善

劣势

不容易掌控

资料有待完善

多分区多Topic带来性能下降

二、RocketMQ特性介绍

1、消费模式(集群消费与广播消费)

1.  集群消费时,MQ认为Topic中任意一条消息只需要被消费者组内任意一个消费者处理即可,消息消费进度保存在broker端,如下图:

2.  广播消费时,MQ 会将Topic中每条消息推送给消费组内内所有注册过的消费者客户端,保证消息至少被每个消费者消费一次,客户端本地保存消费进度。

2、消费模型 

1. Push模式(MQPushConsumer

MQPushConsumer 即MQServer主动向消费端推送消息,consumer把轮询过程封装了,并注册MessageListener监听器,取到消息后,唤醒MessageListener的consumeMessage()来消费,对用户而言,感觉消息是被推送过来的。Push和Pull模式都是采用消费端主动拉取的方式,即consumer轮询从broker拉取消息。

代码示例:PushConsumer.java

2.  Pull模式(MQPullConsumer

MQPullConsumer  即消费端在需要时,主动到MQServer拉取,取消息的过程需要用户自己写,首先通过打算消费的Topic拿到MessageQueue的集合,遍历MessageQueue集合,然后针对每个MessageQueue批量取消息,一次取完后,记录该队列下一次要取的开始offset,直到取完了,再换另一个MessageQueue。

代码示例:PullConsumer.java

3、RocketMQ 数据存储结构

如图所示,RocketMQ采取了一种数据与索引分离的存储方法。有效降低文件资源、IO资源,内存资源的损耗。即便是阿里这种海量数据,高并发场景也能够有效降低端到端延迟,并具备较强的横向扩展能力。

4、刷盘策略

RocketMQ 的所有消息都是持久化的,先写入系统 PAGECACHE,然后刷盘,可以保证内存与磁盘都有一份数据,访问时,直接从内存读取。

1.异步刷盘 

在有 RAID 卡,应用服务器三块SSD磁盘测试顺序写文件,速度可以达到 500M/S以上,万一由于此时系统压力过大,可能堆积消息,除了写入 IO,还有读取 IO,万一出现磁盘读取落后情况,
会不会导致系统内存溢出,答案是否定的,原因如下: 
a) 写入消息到 PAGECACHE 时,如果内存不足,则尝试丢弃干净的 PAGE,腾出内存供新消息使用,策略
是 LRU 方式。 
b) 如果干净页不足,此时写入PAGECACHE会被阻塞,系统尝试刷盘部分数据,大约每次尝试32个PAGE,来找出更多干净 PAGE。

2.同步刷盘

同步刷盘与异步刷盘的唯一区别是异步刷盘写完 PAGECACHE 直接返回,而同步刷盘需要等待刷盘完成才返回, 同步刷盘流程如下: 
(1). 写入 PAGECACHE 后,线程等待,通知刷盘线程刷盘。 
(2). 刷盘线程刷盘后,唤醒前端等待线程,可能是一批线程。 
(3). 前端等待线程向用户返回成功。

5、存储目录结构 

存储特点:

(1)RocketMQ消息主体以及元数据都存储在CommitLog当中 ,消息的存储是由consume queue和 commitLog 配合完成的;

(2)Consume Queue定长的结构,每1条记录固定的20个字节,相当于kafka中的partition,是一个逻辑队列,存储了这个Queue在CommiLog中的起始offset,log大小和MessageTag的hashCode;

(3)Consumer消费消息的时候,先读取consumerQueue,然后再通过consumerQueue去commitLog中拿到消息主体。

1. CommitLog文件(物理队列)

CommitLog是用于存储真实的物理消息的结构,保存消息元数据,所有消息到达Broker后都会保存到commitLog文件,这里需要强调的是所有topic的消息都会统一保存在commitLog中。
1)commitlog文件的存储地址:$HOME\store\commitlog\${fileName}
2)一个消息存储单元长度是不定的,顺序写但是随机读
3)每个commitLog文件的默认大小为 1G =1024*1024*1024,满1G之后会自动新建CommitLog文件做保存数据用
4)commitlog的文件名fileName,名字长度为20位,左边补零,剩余为起始偏移量;比如00000000000000000000代表了第一个文件,起始偏移量为0,文件大小为1G=1073741824;当这个文件满了,
第二个文件名字为00000000001073741824,起始偏移量为1073741824,以此类推,第三个文件名字为00000000002147483648,起始偏移量为2147483648消息存储的时候会顺序写入文件,当文件满了,写入下一个文件。

5)CommitLog的清理机制:

按时间清理,rocketmq默认会清理3天前的commitLog文件;

按磁盘水位清理:当磁盘使用量到达磁盘容量75%,开始清理最老的commitLog文件。

2.ConsumeQueue文件组织:

ConsumerQueue相当于CommitLog的索引文件,消费者消费时会先从ConsumerQueue中查找消息的在commitLog中的offset,再去CommitLog中找元数据。如果某个消息只在CommitLog中有数据,没在ConsumerQueue中, 则消费者无法消费,Consumequeue类对应的是每个topic和queuId下面的所有文件,相当于字典的目录用来指定消息在消息的真正的物理文件commitLog上的位置,每条数据的结构如下图所示:消息的起始物理偏移量physical offset(long 8字节)+消息大小size(int 4字节)+tagsCode(long 8字节)。

1)每个topic下的每个queue都有一个对应的consumequeue文件;

2)每个文件由30W条数据组成,每条数据的大小为20个字节,从而每个文件的默认大小为600万个字节(consume queue中存储单元是一个20字节定长的数据)是顺序写顺序读;

3)commitLogOffset是指这条消息在commitLog文件实际偏移量,size就是指消息大小,消息tag的哈希值;

三、RocketMQ实践

1、消息保留时长

fileReservedTime=72  消息留盘时常,默认72小时,取决于broker所在机器磁盘容量大小和业务场景要求,可以通过命令行动态修改,如下:
sh mqadmin updateBrokerConfig -n 'namesrv_adress' -c DefaultCluster -k fileReservedTime -v 24 -n 表示修改集群中master节点上消息保留时常为24小时
sh mqadmin updateBrokerConfig -b 'broker_adress' -c DefaultCluster -k fileReservedTime -v 24 -b 表示修改集群中指定broker节点上消息保留时常为24小时

2、消息主从同步及刷盘策略,默认主从同步,消息异步刷盘

brokerRole=SYNC_MASTER    主从同步

flushDiskType=ASYNC_FLUSH  异步刷盘

方式

同步双写

异步复制

同步刷盘

金融级,吞吐量低

吞吐量低

异步刷盘

默认配置,吞吐量适中

吞吐量最高,单节点宕机会丢失消息

3、生产端实践

1.  局部顺序消息考虑单分片全挂的极端情况,可能存在短时间乱序;
2. 事物消息考虑部署多个slave节点,slave挂掉影响消息发送;
3. 发送使用同步方式并打印发送结果,方便问题排查;
4. 消息发送失败的处理逻辑;
5. 有消息优先级的需求,通过将不同优先级的消息发送到不同队列来实现;
6. 手动创建Topic,避免单点问题,创建步骤

集群名默认,broker_name选集群中所有节点,主题名(Topic)手动输入,默认每个broker上16个队列(MessageQueue),
图中3个broker节点共48个队列,队列数的大小与消费者数量有关,最好是等于消费者数量,这样消费效率最高,
如果业务场景上需要严格的顺序消息,那么读写队列数量为1。

4、消费端实践

1.  同一个消费者组只能订阅相同的Topic
2.  同一个消费者组TAG使用出错导致部分消息未消费,合理使用TAG
3. Topic中数据量比较大,新消费者组加入建议使用LAST_OFFSET
4. 消息去重,RocketMQ只保证消费最少消费一次
5. 消费考虑均衡,避免消费者消费不均匀

5、消息堆积问题解决办法

 
考虑项
堆积性能指标
  消息的堆积容量 依赖磁盘大小
  发消息的吞吐量大小受影响程度 无 SLAVE 情况,会受一定影响 
有 SLAVE 情况,不受影响
  正常消费的 Consumer 是否会受影响 无 SLAVE 情况,会受一定影响 
有 SLAVE 情况,不受影响
  访问堆积在磁盘的消息时,吞吐量有多大 与访问的并发有关,最慢会降到 5000 左右

在有 Slave 情况下,Master 一旦发现 Consumer 访问堆积在磁盘的数据时,会向 Consumer 下达一个重定向指
令,令 Consumer 从 Slave 拉取数据,这样正常的发消息与正常消费的 Consumer 都不会因为消息堆积受影响,因为
系统将堆积场景与非堆积场景分割在了两个不同的节点处理。这里会产生另一个问题,Slave 会不会写性能下降,
答案是否定的。因为 Slave 的消息写入只追求吞吐量,不追求实时性,只要整体的吞吐量高就可以,而 Slave 每次
都是从 Master 拉取一批数据,如 1M,这种批量顺序写入方式即使堆积情况,整体吞吐量影响相对较小,只是写入
RT 会变长。

RocketMQ介绍与实践的更多相关文章

  1. 关于Axure RP软件的介绍——软件工程实践第二次个人作业

    关于Axure RP软件的介绍——软件工程实践第二次个人作业 Axure RP是一个非常专业的快速原型设计的一个工具,客户提出需求,然后根据需求定义和规格.设计功能和界面的专家能够快速创建应用软件或W ...

  2. RabbitMQ系列(三)RabbitMQ交换器Exchange介绍与实践

    RabbitMQ交换器Exchange介绍与实践 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建 深入了解RabbitMQ工作原理及简单使用 RabbitMQ交换器Exchang ...

  3. 转 消息中间件:RocketMQ 介绍(特性、术语、原理、优缺点、消息顺序、消息重复)

    https://blog.csdn.net/jiangyu1013/article/details/81668671 消息中间件的作用 1. 应用解耦 2. 异步处理 比如用户注册场景,注册主流程完成 ...

  4. RocketMQ介绍与云服务器安装

    RocketMQ 介绍与概念 在github上的说法来看: Apache RocketMQ是一个分布式消息传递和流媒体平台,具有低延迟,高性能和可靠性,万亿级容量和灵活的可扩展性.它提供了多种功能: ...

  5. rocketmq学习(一) rocketmq介绍与安装

    1.消息队列介绍 消息队列本质上来说是一个符合先进先出原则的单向队列:一方发送消息并存入消息队列尾部(生产者投递消息),一方从消息队列的头部取出消息(消费者消费消息).但对于一个成熟可靠的消息队列来说 ...

  6. RabbitMQ交换器Exchange介绍与实践

    RabbitMQ交换器Exchange介绍与实践 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建 深入了解RabbitMQ工作原理及简单使用 RabbitMQ交换器Exchang ...

  7. RocketMQ 介绍与安装

    目录 RocketMQ 介绍 MQ 介绍 MQ 作用 MQ 缺点 MQ 常见产品 RocketMQ 简介 RocketMQ 架构 RocketMQ 安装 RocketMQ 介绍 MQ 介绍 定义: M ...

  8. 高并发应用场景下的负载均衡与故障转移实践,AgileEAS.NET SOA 负载均衡介绍与实践

    一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...

  9. SVN 分支及合并的介绍和实践---命令行

    写在前面 一些相关的概念和原理 进行分支开发的最佳实践 合并的分类 在 Eclipse 中进行合并操作 相关资源 写在前面 本文是由演讲整理而来的,介绍了 SVN 分支与合并的概念.流程和一些实际操作 ...

随机推荐

  1. Openstack 使用Centos官方镜像创建实例记录

    Openstack 使用Centos官方镜像创建实例记录 准备centos镜像 官方地址:http://cloud.centos.org/centos/7/images 可以看到有各种版本的镜像,我在 ...

  2. zeroc ice log4net 多进程log文件问题

    使用zeroc ice 中的icebox 的时候多服务会有多个服务实例,每个实例都要写日志文件,所以要配置多个日志文件区分开来, 类似这样  orderservice_1_20160101.log   ...

  3. Python_面试题_更新中

    Python-面试题 线上操作系统 centos py2和py3的区别 每种数据类型,列举你了解的方法 3 or 9 and 8 字符串的反转 is 和 == 的区别? git流程 v = (1) / ...

  4. MRP自动运算设置

    1.执行计划-删除老的调度计划: 2.运算日志-清除冲突: 3.MRP计划运算向导,清除预留: 4.创建MRP凌晨调度任务,名称自己修改: 5.创建完成: 6.设置消息通知:

  5. C - The Battle of Chibi HDU - 5542 (树状数组+离散化)

    Cao Cao made up a big army and was going to invade the whole South China. Yu Zhou was worried about ...

  6. Linux中vim的基本操作

    Vim三种模式之间的相互转换: 1.拷贝当前行 yy,拷贝当前行的向下五行 5yy,粘贴使用p: 2.删除当前行 dd,删除当前行的向下五行 5dd: 3.在文件中查找某个单词[命令行模式下  /关键 ...

  7. c++与c语言的区别部分

    1.new       <malloc> delete    <free> 2.多态: 重载 <函数     操作符>   类似于c中的变化参数 虚函数 3.模板 ...

  8. HTML 标签的 target 属性

    定义和用法 target 属性规定在何处打开 action URL. 属性值 值 描述 _blank 在新窗口中打开. _self 默认.在相同的框架中打开. _parent 在父框架集中打开. _t ...

  9. EmguCV C# 安装入门教程

    EmguCv3的安装. EmguCv3下载网址 http://sourceforge.net/projects/emgucv/files/emgucv/3.0.0/ 推荐下载第一个: 点击direct ...

  10. scala编程(四)——类和对象

     类,字段和方法 在scala里定义一个典型的类,代码如下: class ChecksumAccumulator { private var sum = 0 def add(b: Byte): Uni ...