RocketMQ——角色与术语详解
原文地址:http://jaskey.github.io/blog/2016/12/15/rocketmq-concept/
RocketMQ——角色与术语详解
2016-12-15 THU 15:48
RocketMQ中有很多概念,其中包括一些术语和角色。
理清楚基本的概念能有效的帮助理解RocketMQ的原理以及排查问题。
角色:
Producer
生产者。发送消息的客户端角色。发送消息的时候需要指定Topic。
Consumer
消费者。消费消息的客户端角色。通常是后台处理异步消费的系统。 RocketMQ中Consumer有两种实现:PushConsumer和PullConsumer。
PushConsumer
推送模式(虽然RocketMQ使用的是长轮询)的消费者。消息的能及时被消费。使用非常简单,内部已处理如线程池消费、流控、负载均衡、异常处理等等的各种场景。
PullConsumer
拉取模式的消费者。应用主动控制拉取的时机,怎么拉取,怎么消费等。主动权更高。但要自己处理各种场景。
概念术语
Producer Group
标识发送同一类消息的Producer,通常发送逻辑一致。发送普通消息的时候,仅标识使用,并无特别用处。若事务消息,如果某条发送某条消息的producer-A宕机,使得事务消息一直处于PREPARED状态并超时,则broker会回查同一个group的其 他producer,确认这条消息应该commit还是rollback。但开源版本并不支持事务消息。
Consumer Group
标识一类Consumer的集合名称,这类Consumer通常消费一类消息,且消费逻辑一致。同一个Consumer Group下的各个实例将共同消费topic的消息,起到负载均衡的作用。
消费进度以Consumer Group为粒度管理,不同Consumer Group之间消费进度彼此不受影响,即消息A被Consumer Group1消费过,也会再给Consumer Group2消费。
注: RocketMQ要求同一个Consumer Group的消费者必须要拥有相同的注册信息,即必须要听一样的topic(并且tag也一样)。
Topic
标识一类消息的逻辑名字,消息的逻辑管理单位。无论消息生产还是消费,都需要指定Topic。
Tag
RocketMQ支持给在发送的时候给topic打tag,同一个topic的消息虽然逻辑管理是一样的。但是消费topic1的时候,如果你订阅的时候指定的是tagA,那么tagB的消息将不会投递。
Message Queue
简称Queue或Q。消息物理管理单位。一个Topic将有若干个Q。若Topic同时创建在不通的Broker,则不同的broker上都有若干Q,消息将物理地存储落在不同Broker结点上,具有水平扩展的能力。
无论生产者还是消费者,实际的生产和消费都是针对Q级别。例如Producer发送消息的时候,会预先选择(默认轮询)好该Topic下面的某一条Q地发送;Consumer消费的时候也会负载均衡地分配若干个Q,只拉取对应Q的消息。
每一条message queue均对应一个文件,这个文件存储了实际消息的索引信息。并且即使文件被删除,也能通过实际纯粹的消息文件(commit log)恢复回来。
Offset
RocketMQ中,有很多offset的概念。但通常我们只关心暴露到客户端的offset。一般我们不特指的话,就是指逻辑Message Queue下面的offset。
注: 逻辑offset的概念在RocketMQ中字面意思实际上和真正的意思有一定差别,这点在设计上显得有点混乱。祥见下面的解释。
可以认为一条逻辑的message queue是无限长的数组。一条消息进来下标就会涨1,而这个数组的下标就是offset。
max offset
字面上可以理解为这是标识message queue中的max offset表示消息的最大offset。但是从源码上看,这个offset实际上是最新消息的offset+1,即:下一条消息的offset。
min offset:
标识现存在的最小offset。而由于消息存储一段时间后,消费会被物理地从磁盘删除,message queue的min offset也就对应增长。这意味着比min offset要小的那些消息已经不在broker上了,无法被消费。
consumer offset
字面上,可以理解为标记Consumer Group在一条逻辑Message Queue上,消息消费到哪里即消费进度。但从源码上看,这个数值是消费过的最新消费的消息offset+1,即实际上表示的是下次拉取的offset位置。
消费者拉取消息的时候需要指定offset,broker不主动推送消息, offset的消息返回给客户端。
consumer刚启动的时候会获取持久化的consumer offset,用以决定从哪里开始消费,consumer以此发起第一次请求。
每次消息消费成功后,这个offset在会先更新到内存,而后定时持久化。在集群消费模式下,会同步持久化到broker,而在广播模式下,则会持久化到本地文件。
集群消费
消费者的一种消费模式。一个Consumer Group中的各个Consumer实例分摊去消费消息,即一条消息只会投递到一个Consumer Group下面的一个实例。
实际上,每个Consumer是平均分摊Message Queue的去做拉取消费。例如某个Topic有3条Q,其中一个Consumer Group 有 3 个实例(可能是 3 个进程,或者 3 台机器),那么每个实例只消费其中的1条Q。
而由Producer发送消息的时候是轮询所有的Q,所以消息会平均散落在不同的Q上,可以认为Q上的消息是平均的。那么实例也就平均地消费消息了。
这种模式下,消费进度的存储会持久化到Broker。
广播消费
消费者的一种消费模式。消息将对一个Consumer Group下的各个Consumer实例都投递一遍。即即使这些 Consumer 属于同一个Consumer Group,消息也会被Consumer Group 中的每个Consumer都消费一次。
实际上,是一个消费组下的每个消费者实例都获取到了topic下面的每个Message Queue去拉取消费。所以消息会投递到每个消费者实例。
这种模式下,消费进度会存储持久化到实例本地。
顺序消息
消费消息的顺序要同发送消息的顺序一致。由于Consumer消费消息的时候是针对Message Queue顺序拉取并开始消费,且一条Message Queue只会给一个消费者(集群模式下),所以能够保证同一个消费者实例对于Q上消息的消费是顺序地开始消费(不一定顺序消费完成,因为消费可能并行)。
在RocketMQ中,顺序消费主要指的是都是Queue级别的局部顺序。这一类消息为满足顺序性,必须Producer单线程顺序发送,且发送到同一个队列,这样Consumer就可以按照Producer发送的顺序去消费消息。
生产者发送的时候可以用MessageQueueSelector为某一批消息(通常是有相同的唯一标示id)选择同一个Queue,则这一批消息的消费将是顺序消息(并由同一个consumer完成消息)。或者Message Queue的数量只有1,但这样消费的实例只能有一个,多出来的实例都会空跑。
普通顺序消息
顺序消息的一种,正常情况下可以保证完全的顺序消息,但是一旦发生异常,Broker宕机或重启,由于队列总数发生发化,消费者会触发负载均衡,而默认地负载均衡算法采取哈希取模平均,这样负载均衡分配到定位的队列会发化,使得队列可能分配到别的实例上,则会短暂地出现消息顺序不一致。
如果业务能容忍在集群异常情况(如某个 Broker 宕机或者重启)下,消息短暂的乱序,使用普通顺序方式比较合适。
严格顺序消息
顺序消息的一种,无论正常异常情况都能保证顺序,但是牺牲了分布式 Failover 特性,即 Broker集群中只要有一台机器不可用,则整个集群都不可用,服务可用性大大降低。
如果服务器部署为同步双写模式,此缺陷可通过备机自动切换为主避免,不过仍然会存在几分钟的服务不可用。(依赖同步双写,主备自动切换,自动切换功能目前并未实现)
目前已知的应用只有数据库 binlog 同步强依赖严格顺序消息,其他应用绝大部分都可以容忍短暂乱序,推荐使用普通的顺序消息
RocketMQ——角色与术语详解的更多相关文章
- Spring框架学习05——AOP相关术语详解
1.Spring AOP 的基本概述 AOP(Aspect Oriented Programing)面向切面编程,AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视.事务管理.安全检查 ...
- Zynq7000术语详解,不懂啥是PL,PS,APU,SCU?那就进来看看吧
Zynq7000术语详解,不懂啥是PL,PS,APU,SCU?那就进来看看吧 相信大家刚看到Zynq手册的时候,对着那么一大堆缩略语肯定是一头雾水,特转来一篇文章,为大家解惑 摘要:本文介绍与 ...
- 刨根问底 | Elasticsearch 5.X集群多节点角色配置深入详解【转】
转自:https://blog.csdn.net/laoyang360/article/details/78290484 1.问题引出 ES5.X节点类型多了ingest节点类型. 针对3个节点.5个 ...
- Elasticsearch 8.X 节点角色划分深入详解
文章转载自: https://mp.weixin.qq.com/s/3486iH3VH7TV6lza-a7adQ 0.问题引出 如果你的 Elasticsearch 集群是 7.9 之前的版本,在配置 ...
- Eureka(一)术语详解(用具体的事物理解抽象的概念)
最近工作较闲,所以自己研究了下eureka的原理,实现,和集群搭建等.(注:我没实操过eureka集群项目,都是自己做的demo产生的结论,如果有错误欢迎指出) 首先说一下我对eureka的一些术语的 ...
- 2 rocketmq mqadmin 的用法详解
参考文档 http://jameswxx.iteye.com/blog/2091971 1.1. 控制台使用 RocketMQ 提供有控制台及一系列控制台命令,用于管理员对主题,集群,broker 等 ...
- UX术语详解:任务流,用户流,流程图以及其它全新术语
以下内容由Mockplus(摹客)团队翻译整理,仅供学习交流,Mockplus是更快更简单的原型设计工具. 用户体验拥有一长串专业的术语和可交付内容.当在线查看UX相关职位描述时,所罗列的这类术语更是 ...
- Asp.Net Core 中IdentityServer4 实战之角色授权详解
一.前言 前几篇文章分享了IdentityServer4密码模式的基本授权及自定义授权等方式,最近由于改造一个网关服务,用到了IdentityServer4的授权,改造过程中发现比较适合基于Role角 ...
- RabbitMQ,Apache的ActiveMQ,阿里RocketMQ,Kafka,ZeroMQ,MetaMQ,Redis也可实现消息队列,RabbitMQ的应用场景以及基本原理介绍,RabbitMQ基础知识详解,RabbitMQ布曙
消息队列及常见消息队列介绍 2017-10-10 09:35操作系统/客户端/人脸识别 一.消息队列(MQ)概述 消息队列(Message Queue),是分布式系统中重要的组件,其通用的使用场景可以 ...
随机推荐
- 算法习题---5-4交换学生(UVa10763)
一:题目 有一组学生,他们手中分别有自己学校和想要去的目标学校(A,B).为了成功的交换学生,必须保证这一组学生中必须每两个人之间满足 s1 (A,B) 和 s2 (B,A).即两者原来和目标学校相对 ...
- 算法习题---5.5集合栈计算机(Uva12096)*****
一:题目 对于一个以集合为元素的栈,初始时栈为空. 输入的命令有如下几种: PUSH:将空集{}压栈 DUP:将栈顶元素复制一份压入栈中 UNION:先进行两次弹栈,将获得的集合A和B取并集,将结果压 ...
- Linux下安装maven-及常用命令
Linux下安装maven1.首先到Maven官网下载安装文件,目前最新版本为3.0.3,下载文件为apache-maven-3.0.3-bin.tar.gz,下载可以使用wget命令: 2. ...
- Qt编写气体安全管理系统13-短信告警
一.前言 短信告警这个模块在很多项目中都用上了,比如之前做过的安防系统,温湿度报警系统等,主要的流程就是收到数据判断属于某种报警后,组织短信字符串内容,发送到指定的多个手机号码上面,使用的是短信猫硬件 ...
- 通过直方图进行PCA准备
import graphviz import mglearn from mpl_toolkits.mplot3d import Axes3D from sklearn.datasets import ...
- 用python画 pareto front
用python画 pareto front 觉得有用的话,欢迎一起讨论相互学习~Follow Me 2D pf import os import matplotlib.pyplot as plt im ...
- 第七章 云原生生态的基石 Kubernetes
7.1 Kubernetes架构 K8s的核心组件: etcd: 协同存储,负责保存整个集群的状态. API:资源操作的唯一入口. controller manager: 维护集群的状态,执行故障检测 ...
- 【计算机视觉】基于OpenCV的人脸识别
一点背景知识 OpenCV 是一个开源的计算机视觉和机器学习库.它包含成千上万优化过的算法,为各种计算机视觉应用提供了一个通用工具包.根据这个项目的关于页面,OpenCV 已被广泛运用在各种项目上,从 ...
- docker安装MongoDB创建用户,并用工具Robo连接简单CRUD
搜索mongo docker search mongo 拉取mongo[这里默认为latest] docker pull mongo 查看本地镜像 启动容器[就是安装,-v后面的参数表示把数据文件挂载 ...
- mysql 事物控制语言
事务控制语言(DTL) 什么是事务 通常,在此之前,我们说,一条语句使用一个分号(;)来结束,并得到执行. 那么我们说,这个“一次性执行”的过程,可以称为“一个事务” ...