在传统的消息中间件如Kafka中,一个分区只能被一个消费者消费,这保证了分区内的严格顺序。然而,这种模型也存在局限,例如消费者数量不能超过分区总数。
如今,为了提升消费吞吐和扩展灵活性,新模型正在普及。Kafka自4.0版本引入了Share Group,而Apache Pulsar则原生支持Shared订阅模式,它们都允许一个分区被多个消费者并发消费。
然而,这种提升吞吐能力的模式也带来了代价:由于单个分区内的消息可能被分配给多个消费者处理,因此无法严格保证消息的处理顺序。
那么,在Pulsar中,如果业务场景要求消息顺序消费,我们该如何选择订阅模式呢?
1. Shared 订阅:无法保证分区内顺序
- 官方定义:在此模式下,消费顺序无法得到保证(“In this mode, the consumption order is not guaranteed.”)。
- 工作原理:采用轮询(round-robin)机制向消费者分发消息,这可能导致来自同一分区的消息被发送给不同的消费者实例。
- 结果:即使消费者数量少于分区数,同一分区的消息也可能被并行处理,从而破坏顺序性。
2. Failover 订阅:确保分区内顺序
- 官方定义:对于分区主题,顺序性在分区基础上得到保证。分区将分配给可用的消费者,但在任一时刻,每个分区最多只有一个活跃消费者(“...at most one consumer will be active at a given point in time.”)。
- 工作原理:每个分区在任何时刻都只有一个“活跃”消费者在消费。其他消费者作为故障转移的备用实例。
- 结果:这严格保证了单个分区内消息的消费顺序,即使消费者总数超过分区数。
3. Key_Shared 订阅:确保相同Key的消息顺序
- 工作原理:根据消息的Key(或排序键)进行分发。所有拥有相同Key的消息会被路由到同一个消费者。
- 结果:虽然不同Key的消息可能被乱序消费,但所有相同Key的消息能严格保证其生产顺序被消费。
总结与选择建议
| 订阅模式 |
顺序保证能力 |
适用场景 |
| Shared |
无法保证分区内顺序 |
追求最大吞吐量,顺序不敏感的场景 |
| Failover |
严格保证分区内顺序 |
需要分区内严格顺序,并兼顾高可用的场景 |
| Key_Shared |
严格保证相同Key的消息顺序 |
需要按键(如用户ID、订单号)保证顺序的场景 |
| Exclusive |
全局唯一消费者,自然保证顺序 |
单消费者场景,已较少使用 |
对于需要保证分区内消息顺序的业务,应当选择 Failover 或 Key_Shared 订阅类型,而非 Shared 订阅。相比之下,Pulsar凭借其灵活的多订阅模式,为不同场景下的顺序消费需求提供了清晰的解决方案。
|