RocketMQ 基本概念与工作原理

news2024/11/17 21:57:12

一、基本概念

消息(Message)

消息(Message)就是要传输的信息。一条消息必须有一个主题(Topic),主题可以看做是你的信件要邮寄的地址。

主题(Topic)

Topic表示一类消息的集合,每个主题包含若干条消息,每条消息只能属于一个主题。一个生产者可以同时发送多种Topic消息,而一个消费者只能对某种特定的Topic感兴趣,即只可以订阅和消息一种Topic的消息。
topic :message 1:n
message :topic 1:1
producer :topic 1 :n
consumer:topic 1:1

在这里插入图片描述

标签(Tag)

标签(Tag)可以看作子主题,它是消息的第二级类型,用于为用户提供额外的灵活性。使用标签,同一业务模块不同目的的消息就可以用相同 Topic 而不同的 Tag 来标识。
比如交易消息又可以分为:交易创建消息、交易完成消息等,一条消息可以没有 Tag 。标签有助于保持您的代码干净和连贯,并且还可以为 RocketMQ 提供的查询系统提供帮助。

简单来说TOPIC可以看作衣服,而TAG可以看作衣服下的【短袖】、【外套】、【卫衣】等

队列(Queue)

存储消息的物理实体。一个Topic中可以包含多个Queue,每个Queue中存放的就是该Topic的消息。一个Topic的Queue也被称为一个Topic中的消息的分区。
一个Topic的Queue中的消息只能被一个消费者组中的一个消费者消费。一个Queue中的消息不允许同一个消费者组中的多个消费者同时消费。
在这里插入图片描述
在这里插入图片描述

二、系统架构

在这里插入图片描述

Producer

就是消息生产者,可以集群部署。它会先和 NameServer 集群中的随机一台建立长连接,得知当前要发送的 Topic 存在哪台 Broker Master上,然后再与其建立长连接,支持多种负载平衡模式发送消息。

Consumer

消息消费者,也可以集群部署。它也会先和 NameServer 集群中的随机一台建立长连接,得知当前要消息的 Topic 存在哪台 Broker Master、Slave上,然后它们建立长连接,支持集群消费和广播消费消息。

Broker

主要负责消息的存储、查询消费,支持主从部署,一个 Master 可以对应多个 Slave,Master 支持读写,Slave 只支持读。Broker 会向集群中的每一台 NameServer 注册自己的路由信息。
在这里插入图片描述
Remoting Module:整个Broker的实体,负责处理来自clients端的请求。
Client Manager:客户端管理器。负责接收、解析客户端(Producer/Consumer)请求,管理客户端。
Store Server:存储服务、提供方便简单的API接口,处理消息存储到物理硬盘消息查询功能。
HA Server:高可用服务。提供Master Broker和Slave Broker之间的数据同步功能。
Index Server:索引服务。根据特定的Message key,对投递到Broker的消息进行索引服务,同时也提供根据Message Key对消息进行快速查询的功能。

NameServer

是一个很简单的 Topic 路由注册中心,支持 Broker 的动态注册和发现,保存 Topic 和 Borker 之间的关系。通常也是集群部署,但是各 NameServer 之间不会互相通信, 各 NameServer 都有完整的路由信息,即无状态。

路由注册

那各节点中的数据是如何进行数据同步的? 在Broker节点启动时,轮询NameServer列表,与每个NaemServer节点建立长连接,发起注册请求。在NameServer内部维护着一个Broker列表,用来动态存储Broker的信息。Broker节点为了证明自己是活着,为了维护与NameServer间的长连接,会将最新的信息以心跳包的方式上报给NameServer,每30秒发送一次心跳。心跳包中包含BrokerId、Broker地址、Broker名称、Broker所属集群名称等等。NameServer在接收到心跳包后,会更新心跳时间戳,记录这个Broker的最新存活时间。

主要功能

Broker管理:接受Broker集群的注册信息并且保存下来作为路由信息的基本数据;提供心跳检测机制,检查Broker是否还存活。

路由信息管理:每个NameServer中都保存着Broker集群的整个路由信息和用于客户端查询的队列信息。Producer和Consumer通过NameServer可以获取整个Broker集群的路由信息,从而进行消息的投递和消费。

交互过程

先启动 NameServer 集群,各 NameServer 之间无任何数据交互,Broker 启动之后会向所有 NameServer 定期(每 30s)发送心跳包,包括:IP、Port、TopicInfo,NameServer 会定期扫描 Broker 存活列表,如果超过 120s 没有心跳则移除此 Broker 相关信息,代表下线。

这样每个 NameServer 就知道集群所有 Broker 的相关信息,此时 Producer 上线从 NameServer 就可以得知它要发送的某 Topic 消息在哪个 Broker 上,和对应的 Broker (Master 角色的)建立长连接,发送消息。

Consumer 上线也可以从 NameServer 得知它所要接收的 Topic 是哪个 Broker ,和对应的 Master、Slave 建立连接,接收消息。

路由剔除

由于Broker关机、宕机或网络抖动等原因,NameServer没有收到Broker心跳,NameServer可能会将其从Broker列表中剔除。

NameServer中有一个定时任务,每隔10秒应付扫描一次Broker表,查看每一个Broker的最新心跳时间戳距离当前时间是否超过120秒,如果超过,则会判定Broker失效,然后将其从Broker列表中剔除。

路由发现

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

  • Pull模型:拉取模型。存在的问题:实时性较差。
  • Push模型:推送模型。其实时性较好,是一个“发布-订阅”模型,需要维护一个长连接。而长连接的维护需要资源成本。(该模型适合于实时性要求较高,Client数量不多,Server数据变化较频繁)
  • Long Polling:长轮询模型。其实是对Push与Pull模型的整合,充分利用了这两种模型的优势,屏蔽了它们的劣势。

工作流程

  1. 启动NameServerNameServer启动后开始监听端口,等待BrokerProducerConsumer连接。
  2. 启动Broker时,Broker会与所有的NameServer建立并保持长连接,然后每30秒向NameServer定时发送心跳包。
  3. 发送消息前,可以先创建Topic,创建Topic时需要指定该Topic要存储在哪些Broker上,在创建Topic时也会将TopicBroker的关系写入到NameServer中。该步可选,在发送消息时也可以自动创建Topic(自动创建Topic时,默认采用的是Broker模式,会为每个Broker默认创建4个Queue)。
  4. Producer发送消息,启动时先跟NameServer集群中的其中一台建立长连接,并从NameServer中获取路由信息,即当前发送的Topic消息的QueueBroker的地址(IP + Port)的映射关系。然后根据算法策略从队选择一个Queue,与队列所在的Broker建立长连接从而向Broker发消息。在获取到路由信息后,Producer会首先将路由信息缓存到本地,再每30秒从NameServer更新一次路由信息。
  5. ConsumerProducer类似,跟其中一台NameServer建立长连接,获取其所订阅Topic的路由信息,然后根据算法策略从路由信息中获取到其所要消息的Queue,然后直接跟Broker建立长连接,开始消费其中的消息。Consumer在获取到路由信息后,同样也会每30秒从NameServer更新一次路由信息。不同于Producer的是:Consumer还会向Broker发送心跳,以确保Broker的存活状态。

Topic的创建模式

集群模式:该模式下创建的Topic,在该集群中所有Broker中的Queue数量是相同的。
在这里插入图片描述
Broker模式:该模式下创建的Topic,在该集群中每个Broker中的Queue数量可以不同。
在这里插入图片描述

读/写队列

从物理上,读/写队列是同一个队列。所以,不存在读/写队列数据同步问题。读/写队列是逻辑上进行区分的概念。一般情况下,读/写队列数量是相同的。
例如1:创建Topic时设置的写队列数量为8,读队列数量为4,此时系统会创建8个Queue,分别是 0 1 2 3 4 5 6 7。Prodecer会将消息写入到这8个队列,但Consumer只会消费 0 1 2 3 这4个队列中的消息, 4 5 6 7 中的消息是不会被消费到的。

例如2:创建Topic时设置的写队列数量为4,读队列数量为8,此时系统会创建8个Queue,分别是 0 1 2 3 4 5 6 7。Prodecer会将消息写入 0 1 2 3 到这4个队列,但Consumer只会消费 0 1 2 3 4 5 6 7 这8个队列中的消息, 4 5 6 7 中的是没有消息的。假设Consumer Group中包含两个Consumer,Consumer1消费 0 1 2 3 ,而Consumer2消费 4 5 6 7 ,实际情况是,Consumer2是没有消息可消费的。
在这里插入图片描述
设计目的:为了方便Topic的Queue缩容。

缩容

原来创建的Topic中包含16个Queue,如何能够使Queue缩容为8个,还不会丢失消息?
可以动态修改写队列数量为8,读队列数量不变。此时新的消息只能写入前8个队列,而消费者消费的却是16个队列中的数据。当发现后8个Queue中的消息消费完毕后,就可以再将读队列数量动态设置为8。整个缩容过程没有丢失任何消息。
在这里插入图片描述

三、集群搭建理论

在这里插入图片描述

数据复制与刷盘策略

在这里插入图片描述

复制策略

复制策略是Broker的Master与Slave间的数据同步方式。

同步复制: 消息写入master后,master会等待slave同步数据成功后才向Producer返回成功ACK。
异步复制: 消息写入master后,master立即向Producer返回成功ACK,无需等待slave同步数据成功。
异步复制策略会降低系统的写入延迟,RT变小,提高了系统的吞吐量。

刷盘策略

刷盘策略是Broker中消息的落盘方式,即消息发送到Broker内存后消息持久化到磁盘的方式。
同步刷盘: 当消息持久化到Broker的磁盘后才算是消息写入成功。
异步刷盘: 当消息写入到Broker的内存后即表示消息写入成功,无需等待消息持久化到磁盘。

1.异步刷盘策略会降低系统的写入延迟,RT变小,提高了系统的吞吐量。
2.消息写入到Broker的内存,一般是写入到了PageCache
3.对于异步刷盘策略,消息会写入PageCache后立即返回成功ACK。但并不会立即做落盘操作,而是当PageCache到达一定量时会自动进行落盘。

Broker集群模式

单Master

只有一个Broker(其本质上就不能称为集群)。这种方式也只能是在测试时使用,生产环境下不能使用,因为存在单点问题。

多Master

Broker集群仅由多个Master构成,不存在Slave。同一Topic的各个Queue会平均分配在各个Master节点上。

优点: 配置简单,单个Master宕机或重启维护对应用无影响(前提在磁盘配置为RAID10时,即使机器宕机不可恢复情况下,由于RAID10磁盘非常可靠,消息也不会丢失,异步刷盘丢失少量消息,同步刷盘一条不丢),性能高。
缺点: 单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅(不可消息),消息实时性会受到影响。

多Master多Slave模式——异步复制

Broker集群由多个Master构成,每个Master又配置了多个Slave(在配置了RAID磁盘阵列的情况下,一个Master一般配置一个Slave即可)。MasterSlave的关系是主备关系,即Master负责处理消息的读写请求,而Slave仅负责消息的备份与Master宕机后的角色切换。
异步复制是指复制策略中的异步复制策略:消息写入master后,master立即向Producer返回成功ACK,无需等待slave同步数据成功。

多Master多Slave模式——同步双写

该模式是多MasterSlave模式的同步复制实现。所谓同步双写,指的是消息写入Master成功后,Master会等待Slave同步数据成功后才向Producer返回成功ACK,即MasterSlave都要写入成功后才会返回成功ACK,也即双写。

最佳实践:一般会为Master配置RAID10磁盘阵列,再配置一个Slave。即利用了RAID10磁盘阵列的高效、安全性,又解决了可能会影响订阅的问题。

多Maste+RAID阵列,与多Master多Slave集群的区别是什么?

  1. 多Master+RAID阵列,其仅仅可以保证数据不会丢失,即不影响消息写入,但可能影响消息订阅。但执行效率要远高于多Master多Slave集群。
  2. 多Master多Slave集群,其不仅可以保证数据不会丢失,也不影响消息写入。但执行效率要低于多Master+RAID阵列。

四、RocketMQ工作原理

消息的生产

生产过程

Producer将消息写入到某Broker中的某Queue中,其过程如下:

  1. Producer发送消息之前,先向NameServer发出获取消息Topic的路由信息的请求。
  2. NameServer返回该Topic的路由表Broker列表
  3. Producer根据代码中指定的Queue选择策略,从Queue列表中选出一个队列,用于后续存储消息。
  4. Producer对消息做一些特殊处理,例如:消息本身超过4M,则会对其进行压缩。
  5. Producer向选择出的Queue所在的Broker发出RPC请求,将消息发送到选择出的Queue。

路由表: 是一个Map,key为Topic名称,value为QueueData实例列表(所有涉及该Topic的BrokerName列表)。
  QueueData并不是一个Queue对应一个QueueData,而是一个Broker中该Topic的所有Queue对应一个QueueData。

Broker列表: 是一个Map,key为brokerName,value为BrokerData。
  一套brokerName名称相同的Master-Slave小集群对应一个BrokerData。BrokerData中包含brokerName及一个map。该map的key为brokerId,value为该broker对应的地址。brokerId为0表示该broker为Master,非0表示Slave。

Queue选择算法

无序消息
  轮询算法: 默认选择算法,保证每个Queue中可以均匀的获取到消息。
【会出现某些Brake上的Queue投递延迟较严重,则导致Producer的缓存队列中出现消息积压,影响消息投递性能。】

  最小投递延迟算法: 该算法会统计每次消息的时间延迟,然后根据统计出的结果将消息投递到时间延迟最小的Queue。如果延迟相同,则采用轮询算法投递。
【会出现消息在Queue上分配不均】

消息的存储

RocketMQ中的消息存储在本地当前用户主目录下的store中。
在这里插入图片描述
abort:中止文件,启动后自动创建,正常关闭Broker自动消失,如关闭后还出现说明Broker非正常关闭。
checkpoint:存放commitlog、consumequeque、index文件的最后刷盘时间戳。
config:存放Broker运行期间的一些配置数据。
commitlog:存放消息
consumequeue: 存放队列
index:存放消息索引文件indexFile
lock: 运行期间使用的全局资源锁

commitlog文件

commitlog文件在源码中对应mappedFile。当前Broker中所有消息都是落盘到mappedFile中,文件大小为1G,文件名由20位十进制数构成,表示当前文件的第一条消息的起始位移偏移量。
在这里插入图片描述
一个Broker仅包含一个commitlog目录,所有的mappedFile文件都是存放在该目录中,无论当前Broker中有多少Topic消息,这些消息都被顺序写入到mappedFile文件中,即这些消息在Broker中存放时并没有按照Topic进行分类存放。

消息单元

在这里插入图片描述
mappedFile文件内容由一个个的消息单元构成,每个消息单元中包含消息总长度MsgLen、消息的物理位置PhysicalOffset、消息体内容Body、消息体长度BodyLength、消息主题Topic、Topic长度TopicLength、消息生产者BornHost、消息发送时间戳BornTimestamp、消息所在的队列QueueId、

consumequeque

为了提高效率,会为每个Topic在~/store/consumequeue中创建一个目录,目录名为Topic名称。在该Topic目录下,有该Topic的Queue目录,目录名为queueId。每个queueId目录中存放着若干consumequeue文件,consumequeue文件是commitlog的索引文件,可以根据consumequeue定位到具体的消息。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

索引条目

在这里插入图片描述
每个consumequeue文件可以包含30W个索引条目,每个索引条目包含了三个消息重要属性:消息在mappedFile文件中的偏移量CommitLog Offset、消息长度、消息Tag的hashcode值。这三个属性占20个字节,所以文件大小是固定的 30w * 20 字节。文件中所有消息的Topic一定是相同的,但是每条消息的Tag可能是不同的。

对文件的读写

在这里插入图片描述

消息写入

一条消息进入到Broker后经历了以下几个过程才最终被持久化。

  1. Broker根据queueId,获取到该消息对应索引条目要在consumequeue目录中的写入偏移量,即QueueOffset。
  2. 将queueId、queueOffset等数据,与消息一起封装为消息单元
  3. 将消息单元写入到commitlog
  4. 同时,形成消息索引条目
  5. 将消息索引条目分发到相应的consumerqueue
消息拉取

当Consumer来拉取消息时会经历以下几个过程。

  1. Consumer获取到其要消费消息所在Queue的消费偏移量offset,计算出其要消费消息的消息offset。(消费offset即消费进度,consumer对某个Queue的消费offset,即消费到了该Queue的第几条消息。消息offset = 消费offset + 1)
  2. Consumer向Broker发送拉取请求,其中会包含其要拉取消息的Queue、消息offset及消息Tag。
  3. Broker计算在该consumequeue中的queueOffset。(queueOddset = 消费offset * 20 字节)
  4. 从该queueOffset处开始向后查找第一个指定Tag的索引条目。
  5. 解析该索引条目的前8个字节,即可定位到该消息在commitlog中的commitlog offset
  6. 从对应commitlog offset中读取消息单元,并发送给Consumer

indexFile

除了通过指定Topic进行消息消费外,RocketMQ还提供了根据key进行消息查询的功能。该查询是通过store目录中的index子目录中的indexFile进行索引实现的快速查询。这个indexFile中的索引数据是在包含了key的消息被发送到Broker时写入的。如果消息中没有包含key,则不会写入。

索引条目结构

每个Broker中会包含一组indexFile,每个indexFile都是以一个时间戳命名的。每个indexFile文件由三部分组成:indexHeader,slots槽位,indexes索引数据。每个indexFile文件中包含500w个slot槽,每个槽又可能会挂载很多index索引单元。
在这里插入图片描述
在这里插入图片描述
beginTimestamp:第一条消息的存储时间
endTimestamp:最后一条消息存储时间
beginPhyoffset:第一条消息在commitlog中的偏移量commitlog offset
endPhyoffset:最后一条消息在commitlog中的偏移量commitlog offset
hashSlotCount:已经填充有index的slot数量
indexCount:所包含的索引个数(统计出当前indexFile中所有slot槽下挂载的所有index索引单元的数量之和)
在这里插入图片描述
在这里插入图片描述
keyHash:消息中指定的业务key的hash值
phyOffset:当前key对应的消息在commitlog中的偏移量commitlog offset
timeDiff:当前key对应消息的存储时间与当前indexFile创建时间的时间差
preIndexNo:当前slot下当前index索引单元的前一个index索引单元的indexNo

文件名的作用

每个indexFile都是以一个时间戳命名的,根据业务key进行查询时,查询条件除了key之外,还需要指定一个要查询的时间戳,表示要查询不大于该时间戳的最新消息,即查询指定时间戳之前存储的最新消息。

查询流程

定位计算式子
计算指定消息key的slot槽位序号
slot槽位序号 = key的hash % 500w
计算槽位序号为 n 的slot在indexFile中的起始位置
slot(n)位置 = 40 + (n - 1) * 4
计算indexNo为m的index在indexFile中的位置
index(m)位置 = 40 + 500w * 4 + ( m - 1) * 20

40 为indexFile中indexHeader的字节数
500w * 4 中所有slots所占的位数

消息的消费

消费者从Broker中获取消息的方式:pull拉取方式 和 push推动方式
消费者组对消息消费的模式:集群消费Clustering 和 广播消费Broadcasting

推拉消费类型

拉取式消费

Consumer主动从Broker中拉取消息,主动权由Consumer控制。一旦获取了批量消息,就会启动消费过程。该方式的实时性弱,即Broker中有了新的消息时消费者并不能及时发现并消费。

推送式消费

该模式下Broker收到数据后会主动推送给Consumer,实时性高。
该获取方式是典型的发布-订阅模式,即Consumer向其关联的Queue注册了监听器,一旦发现有新的消息到来应付触发回调的执行,回调方法是Consumer去Queue中拉取消息。这都基于Consumer与Broker间的长连接,维护需要消耗系统资源。

拉取式消费 VS 推送式消费
pull:需要应用去实现对关联Queue的遍历,实时性差,但便于应用控制消息的拉取;
push:封装了对关联Queue的遍历,实时性强,但会占用较多的系统资源;

消费模式

广播消费

在这里插入图片描述
该模式下,相同Consumer Group的每个Consumer实例都接收同一个Topic的全量消息。即每条消息只会被发送到Consumer Group中的每个Consumer。

集群消费

在这里插入图片描述
该模式下,相同的ConsumerGroup的每个Consumer实例平均分摊同一个Topic的消息。即每条消息只会被发送到Consumer Group中的某个Consumer。

消费进度保存

广播模式:消费进度保存在Consumer端,因Consumer Group中每个Consumer都会消费所有消息,但是它们的消费进度是不同的,所以Consumer各自保存各自的消费进度。
集群模式:消费进度保存在Broker中,因Consumer Group中所有Consumer共同消费同一个Topic的消息,同一条消息只会被消费一次,消费进度会参与到消费的负载均衡中,故消费进度是需要共享的。

Rebalance机制【集群消费】

在这里插入图片描述
Rebalance即再均衡,指的是,将一个Topic下的多个Queue在同一个Consumer Group中的多个Consumer间进行重新分配的过程。例:一个Topic下5个队列,在只有1个消费者的情况下,这个消费者将负责消费这5个队列的消息,如果此时我们增加一个消费者,那么就可以给其中一个消费者分配2个队列,给另一个分配3个队列,从而提升消息的并行消费能力。

Rebalance限制

由于一个队列最多分配给一个消费者,因此当某个消费者组下的消费者实例数量大于队列的数量时,多余的消费者实例将分配不到任何队列。

Rebalance产生的原因

消费者所订阅Topic的Queue数量发生变化,或者消费者组中消费者的数量发生变化。

1.Queue数量发生变化的场景:Broker扩容或缩容;Broker升级运维;Broker与NameServer间的网络异常;Queue扩容或缩容。
2.消费者数量发生变化的场景:Consumer Group扩容或缩容;Consumer 升级运维;Consumer 与NameServer间的网络异常。

Rebalance过程

在Broker中维护着多个Map集合,这些集合中动态存放着当前Topic中Queue的信息、Consumer Group中Consumer实例的信息。一旦发现发现消费者所订阅的Queue数量发生变化,或消费者组中消费者的数量发生变化,立即向Consumer Group中的每个实例发出Rebalance通知。Consumer实例在接收到通知后会采用Queue分配算法自己获取到相应的Queue,即由Consumer实例自主进行Rebalance。

Queue分配算法

一个Topic中的Queue只能由Consumer Group中的一个Consumer进行消费,而一个Consumer可以同时消费多个Queue中的消息。那么Queue与Consumer间的配对关系是有算法策略的。

平均分配策略

该算法是要根据 avg = QueueCount / CounsumerCount 的计算结果进行分配的。如果能够整除,则按顺序将avg个Queue逐个分配Consumer;如果不能整除,则将多余出的Queue按照Consumer顺序逐个分配。
在这里插入图片描述

环形分配策略

该算法是根据消费者的顺序,依次在由Queue队列组成的环形图中逐个分配。
在这里插入图片描述

一致性hash分配策略

该算法是会将Consumer的hash值作为Node节点存放在hash环上,然后将Queue的hash值也放到hash环上,通过顺时针方向,距离Queue最近那个Consumer就是该Queue要分配的Consumer。
在这里插入图片描述

同机房分配策略

该算法会根据Queue的部署机房位置和Consumer位置,过滤出当前Consumer相同机房的Queue。然后按照平均分配策略或环形平均策略对同机房Queue进行分配。如果没有同机房Queue,则按照平均分配策略或环形平均策略对所有Queue进行分配。
在这里插入图片描述

对比

一致性hash算法可以有效减少由于消费者组扩容或缩容所带来的大量的Rebalance。 应用于Consumer数量变化较频繁的场景。
在这里插入图片描述
在这里插入图片描述

至少一次原则

每条消息必须要被成功消费一次。Consumer在消费完消息后会向其消费进度记录器提交其消费消息的offset,offset被成功记录到记录器中,那么这条消息就被成功消费了。

消费进度记录器:
广播消费模式:Consumer本身就是消费进度记录器。
集群消费模式:Broker是消费进度记录器。

订阅关系的一致性

同一个消费者组(Group ID相同)下所有Consumer实例所订阅的Topic与Tag及对消费的处理逻辑必须完全一致。否则,消息消费的逻辑就会混乱,甚至导致消息丢失。
正确订阅关系
在这里插入图片描述
错误订阅关系
在这里插入图片描述
在这里插入图片描述

offset管理

offset:Consumer的消费进度offset

offset本地管理模式

当消费模式为广播消费时,offset使用本地模式存储。因为每条消息会被所有的消费者消费,每个消费者管理自己的消费进度,各个消费者之间不存在消费进度的交集。
Consumer在广播消费模式下offset相关数据以json形式持久化到Consumer本地磁盘文件中,默认文件路径为当前用户主目录下的.rocketmq_offsets /${clientId} /${group} /offsets.json。 clientId 为当前消费者id, group 消费者组名称。

offset远程管理模式

当消费模式为集群消费时,offset使用远程管理模式。因为所有Consumer实例对消息采用的是均衡消费,所有Consumer共享Queue的消费进度。
Consumer在集群消费模式下offset相关数据以json形式持久化到Broker磁盘文件中,文件路径为当前用户主目录下的store / config / consumerOffset.json

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/128747.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

A机器连接同一局域网下的B机器的虚拟机中的mysql

一 背景描述 1.1 需求描述 B机器windows10 的机器ip为: 172.16.71.13 在其上的虚拟机中安装了mysql,虚拟机的ip为 192.168.152.141 。 A机器的ip为:172.16.71.14 ; 需求: A机器想访问 B机器172.16.71.13 这台机…

aardio - 【库】libxl库,一个dll操作excel

经常用到excel操作,也有几个现成的库能实现我需要的功能,但用起来总是感觉不顺手。 于是便抽了两天时间,在aaz.libxl库的基础上,按照我的使用习惯进行了修改。 以后再也不用为操作excel发愁啦。 下载地址:http://che…

广州车展|埃安超跑Hyper GT登场,给年少有为者的时代献礼

近年来,随着中国新能源的技术日趋成熟,中国新能源车开始蓬勃发展,逐渐占据了可观的市场份额,并朝着高端化迈进。有一个有趣的现象:希望进军豪华纯电市场的中国车企,几乎都会与特斯拉对标。然而,…

2023新一代设备管理系统助力企业高效化巡检

设备数量和种类都比较多的情况下,工厂设备管理员的工作往往压力巨大,因为生产环环相扣,每一个环节如果出现问题,都会影响到生产。如果隐患不能及时处理,会影响设备的正常和安全运转,严重的会波及到周围相关…

SpringBoot+Shiro+JWT+Mybatis-Plus搭建admin-shiro管理系统

1、项目背景 从零开始搭建一个项目骨架,最好选择合适,熟悉的技术,并且在未来易拓展,适合微服务化体系等。所以一般以Springboot作为我们的框架基础,这是离不开的了。 然后数据层,我们常用的是Mybatis&…

佳创视讯亮相第十八届文博会,VR直播全民化备受瞩目

2022年12月28日,第十八届中国(深圳)国际文化产业博览交易会正式面向公众开放。本届文博会采取线下为主、线上同步的方式,强化线上线下交互联动,旨在推动中华文化产业高质量发展,加强对外文化合作交流。展会共吸引2532家政府组团、文化机构和企业线下参展,870家机构和企业线上参…

SpringSecurity(二十四)--OAuth2:使用JWT和加密签名(下)非对称密钥加密

一、前言 由于上文对称密钥涉及到的内容比较多,所以这一节的非对称密钥加密拆开成这一节单独讲解。 所以大家尽量先阅读完上一章的内容后再浏览这一章内容会更好。 二、使用通过JWT和非对称密钥签名的令牌 本节将实现OAuth2身份验证的一个示例,其中授…

自定义事件实现rpc的调用C++和蓝图实现举例

参考视频:https://www.youtube.com/watch?vGcZQ2o6LpDI 1.自定义事件的方式实现rpc run on server 修改角色的最大速度,方框1,让客户端先行,速度直接改变;然后方框2,告知服务器,自己的速度已经…

双脚在路上,钢笔在手里,想法在脑中,2023年CSDN将在心头

☔️(一)行走过的道路 一年的时间说长不长,说短不短,所渡过时光的长短在于你是否留意你曾走过的路。 🐴① 记得2022年初我所许下的flag,是要在CSDN平台上运用今年一年的时间撰写超50篇的技术文章&#xff0…

MySQL-运算符详解

1. 算数运算符 运算符名称作用示例加法计算两个值或表达式的和SELECT A B-减法计算两个值或表达式的差SELECT A - B*乘法计算两个值或表达式的乘积SELECT A * B/或DIV除法计算两个值或表达式的商SELECT A / B%或MOD求模(求余)计算两个值或表达式的余数SELECT A % B 2. 比较运…

vue导入私有组件和注册全局组件和props自定义属性

目录先下载并配置插件导入私有组件注册全局组件props自定义属性使用先下载并配置插件 导入的时候需要路径,有个符号,但不能提示路径,需要手打路径,会发现很麻烦,这时候可以通过vscode插件来解决 vscode搜索Path Autocomplete 配置插件,点击插件设置—扩展设置,点开任意一个set…

CRM客户关系管理:赢得和留住客户的指南

客户管理是一个涉及协调和管理客户与企业之间互动的过程。它对企业的商誉及其保留和获得新客户的能力有重大影响。 一般来说,客户管理可以分解成四个不同的部分: - 了解客户的需求以及他们想从你这里得到什么 - 满足这些要求并对他们的询问提供充分的…

EIZO船舶触摸屏维修T1502-B

EIZO船舶触摸屏使用注意事项: 1 由于显示器电子零件的性能需要约30分钟才能稳定,因此在电源开启之后,应调整显示器30分钟以上。 2为了降低因长期使用而出现的发光度变化以及保持稳定的发光度,建议您以较低亮度使用显示器。 3 当显示器长期显示一个图像的情况下再…

传统卷积与Transformers 优缺点对比

近两年Transformer如日中天,刷爆各大CV榜单,但在计算机视觉中,传统卷积就已经彻底输给Transformer了吗? 回答1 作者:DLing 链接:https://www.zhihu.com/question/531529633/answer/2819350360 看在工业界还…

【云原生进阶之容器】第二章Controller Manager原理--client-go剖析

2 Client-go Kubernetes 官方从 2016 年 8 月份开始,将 Kubernetes 资源操作相关的核心源码抽取出来,独立出来一个项目 client-go,Kubernetes中使用client-go作为Go语言的官方编程式交互客户端库,提供对api server服务的交互访问。对于k8s的二次开发,熟练掌握client-go是十…

大胆预测,2023年Android 行业什么技术最重要~

随着Android 时代的发展,在2022的这一年里,感觉自己经历了许多,从年初到年底,见证了不是互联网公司的裁员、优化、毕业、输送人才……等一些列的操作,估计有些人和我一样对Android未来感到茫然,不少人可能会…

发表计算机SCI论文,是先写中文,还是直接写英文论文? - 易智编译EaseEditing

经过高考、四六级和研究生考试,我们都有一定的英文基础,也都知道英文和中文的差别就是中国人和欧美人的思维差别。在这里对中英文写作的优缺点进行列举和分析: 直接写英文论文: (1)中英文表述方式差异明显…

【图像算法】pytesseract简单实现图片数字识别

【前置目的】 识别视频中是否包含目标元素; 抽象自动化,就是处理一段含有时间戳的视频; 再核心就是对视频进行图片裁减,识别出图片中的数字,做数学计算延时。 【学习地址】 环境:mac、python3、pytesserac…

PCB阻焊桥的工艺设计,华秋一文告诉你

PCB表面的一层漆称为阻焊油墨,也就是PCB线路板防焊油墨。阻焊油墨是PCB线路板中非常常见也是主要使用的油墨。阻焊油墨一般90%都是绿色的,但也有其他颜色,例如:红色、蓝色、黑色、白色、黄色称之为杂色油墨。 阻焊油墨的作用就是…

星尘数据完成5000万元A轮融资,Autolabeling加速自动驾驶量产

近日,国内领先的AI数据服务商星尘数据宣布完成A轮融资5000万元人民币,本轮融资由华映资本领投,小米生态链背景的厚天资本和瑞夏资本跟投。融资将用于端到端的数据闭环系统研发、商务拓展以及供应商合作。星尘数据创始人、CEO章磊表示&#xf…