
MQ
RocketMQ
重要概念
- Topic(主题)
- Queue(队列):一个Topic由多个Queue组成,消息被均匀地分布在这些Queue中。队列是消息存储和传输的实际载体。
- Consumer Group(消费者组)
- Consumer Instance(消费者实例)
一个Queue只能被同一个Consumer Group下的一个Consumer Instance消费。但一个Consumer Instance可以同时消费多个Queue。
队列是什么?和Topic有什么关系?
text
队列(Queue) 是Topic的分区(Partition) 单位。当你创建一个Topic时,必须指定它包含多少个Queue(例如8个、16个)。
消息不是直接存在Topic里的,而是存储在Topic下的各个Queue中。生产者发送消息到某个Topic,这条消息会根据一定的策略(如轮询、哈希)被路由到该Topic下的某一个Queue里。
关系:Topic是逻辑概念,Queue是物理概念。Topic是逻辑上的消息分类,而Queue是实际承载消息的实体。可以把Topic理解成一个由多个Queue组成的逻辑队列。
在创建Topic的时候要指定队列么?
text
是的,必须指定。 这是在创建Topic时最重要的参数之一(通常在管理控制台或通过命令创建时指定)。
例如,创建命令通常是这样的:
sh mqadmin updateTopic -n localhost:9876 -t YourTopicName -b -r 8 -w 8
这里的 -r 8 -w 8 通常就表示读写队列数各为8个。队列数量是Topic的固有属性,创建后通常不建议修改(修改很麻烦)。
一个队列只能被一个同Group的消费者实例消费如何理解?
这意味着对于同一个消费者组(Consumer Group)来说,它的所有实例会共同协商(通过RocketMQ的负载均衡机制)来分配某个Topic下的所有Queue。
场景一:消费者实例数 = 队列数(理想状态)
- Topic
OrderTopic
有 4 个 Queue (Q1, Q2, Q3, Q4)。 - 你的消费者组
OrderGroup
启动了 4 个实例 (C1, C2, C3, C4)。 - 负载均衡后,分配结果是:
- C1 -> Q1
- C2 -> Q2
- C3 -> Q3
- C4 -> Q4
- 每个消费者实例都“认领”了一个队列,分工明确,效率最高。
- Topic
场景二:消费者实例数 < 队列数(很常见)
OrderTopic
还是有 4 个 Queue (Q1, Q2, Q3, Q4)。OrderGroup
只启动了 2 个实例 (C1, C2)。- 负载均衡后,分配结果可能是:
- C1 -> Q1, Q2
- C2 -> Q3, Q4
- 每个消费者实例需要处理两个队列的消息,只要它们的处理能力跟得上,也没问题。
场景三:消费者实例数 > 队列数(资源浪费!)
OrderTopic
只有 4 个 Queue (Q1, Q2, Q3, Q4)。OrderGroup
却启动了 6 个实例 (C1, C2, C3, C4, C5, C6)。- 负载均衡后,分配结果只能是:
- C1 -> Q1
- C2 -> Q2
- C3 -> Q3
- C4 -> Q4
- C5 -> (无队列可分配,处于空闲状态)
- C6 -> (无队列可分配,处于空闲状态)
- C5和C6无法消费任何消息,白白浪费了服务器资源。
RocketMQ如何保证消息不丢失?
- 生产者发送消息,失败重试,再失败告警+落库
- broke默认是异步刷盘+集群部署
- 消费完成ack确认