rocketmq和kafka的区别之顺序消费

一.背景

rocketmq和kafka都可以保证消息消费的有序性, 但是由于设计理念的区别导致大家的实现方式完全不同。

相同点

两者都是通过key取模 使拥有相同key的消息进入同一个分区中。

二.差异

两者在消费端的处理模式是不同的。

1. rocketmq的实现方式

 rocketmq采用一个消费者实例 + 内部线程池的模型。为保证消费的有序性需要加3把锁
 1. 消费者实例对Broker实例的MessageQueue加锁, 保证该队列的消息只会投递给
     同一个消费者实例
  2. 消费者实例单次拉取多条消息到l本地ProcessQueue,并且提交到线程池。 为了保证同一时间一个queue只会被同一个线程消费,要对本地的MessageQueue加锁。持锁的线程才有资格消费。
  3. 消费线程对ProcessQueue加锁,因为要确保在发生重平衡时 Rebalance线程无法获取到ProcessQueue的锁, 无法对ProcessQueue修改,造成重复消费。
1.1 消费线程对ProcessQueue加锁要解决什么问题?
时刻线程操作说明
T1消费线程AProcessQueue.msgTreeMap中取出10条消息消息处于"在途"状态,已从队列取出但未完成处理
T2Broker触发重平衡(如新消费者加入)通知当前消费者不再负责MessageQueue-X
T3重平衡线程ProcessQueue-X.dropped = true,准备移除队列并持久化消费进度此时认为该队列已不再属于当前消费者
T4消费线程A处理完10条消息,尝试更新消费进度并删除msgTreeMap中的消息操作一个可能已被标记为丢弃的队列

重平衡线程在T3时刻持久化的消费进度不包含T1时刻取出的10条"在途"消息

在这里插入图片描述

2. kafka的实现方式

1. kafka采用一个线程对应着一个消费者的模型
2. 一个应用实例可以有多个消费者(KafkaConsumer), 每个Kafka都是单线程执行的。
   即一个应用实例有多个消费者实例, 这些消费者实例是单线程运行的,所以不需要有rocketmq的3把锁。

三. 为什么会有这样的差异?

1. 因为rocketmq采用rocketmq采用一个消费者实例 + 内部线程池的模型, 加上考虑到重平衡的影响,需要加3次锁。
2. kafka采用一个线程对应着一个消费者的模型, 本身就是单线程执行的,不存在并发的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值