Spring Cloud(十二):消息中心篇-RocketMq与Kafka选型(四)

Spring Cloud(十二):消息中心篇-RocketMq与Kafka选型(四)

大家好,我是杰哥


前三篇RocketMq与Kafka选型(一)、RocketMq与Kafka选型(二)以及RocketMq与Kafka选型(三)中,主要对两者的前几个方面分别进行了分析对比。今天,我们再接着看看消息中心的其余方面的不同点~(毕竟,也该是终结这一part的时候啦)


01.两者的相同点

02.部署架构不同

03.工作流程不同

04.日志存储方式不同

05.保证消息顺序消息的方法是否相同

06.消息重复机制不同

07.是否支持延时消息

08.消息过滤方式不同

09.消息失败支持重试吗?

10.事务不同

11.是否支持回溯消费?

12.高可用机制不同


一 比较

六个方面


01.是否支持延时消息


1 RocketMQ支持固定延时等级的延时消息,等级可配置

2 kfaka不支持延时消息

02.消息过滤方式不同

1 RocketMQ执行过滤是在Broker端,支持tag过滤及自定义过滤逻辑

2 Kafka不支持Broker端的消息过滤,需要在消费端自定义实现

03.消息失败是否支持重试


1 Kafka不支持重试

2 RocketMQ支持定时重试,每次重试间隔逐渐增加

04.事务机制不同

两个消息中心的事务机制也有所不同。RocketMq通过二阶段提交和回查机制能够实现分布式场景下的事务:两个系统进行处理同一业务流程交易时,保证生产方处理和发送消息阶段两个动作要么同时成功,要么同时失败。而Kafka则是保证生产者发送多条消息可以封装在一个事务中,形成一个原子操作

1 RocketMq的事务机制

看这样一个例子:

Spring Cloud(十二):消息中心篇-RocketMq与Kafka选型(四)

当用户下了订单,并成功付款100元之后,A系统则会扣掉用户账户的100元,并通过B系统为其账户增加100个积分。而执行步骤是

1)A系统扣减100元

2)将结果通过消息中心发送给包含B服务在内的其他服务

3)B服务执行增加100个积分

此时,若第一步和第二步不是同时执行,即

1)先执行了扣减动作,但还没来得及发送消息。则最终的结果是用户的钱被扣掉了,但是B系统未收到任何增加积分的通知,因此导致用户并没有添加到积分

2)若先发送了消息,还未来得及执行扣减动作。那么最终将会少收用户100元钱

那么,为了尽可能地保证这一业务流程的执行逻辑,则需要保证A系统的扣减100元的操作和发送消息的操作要么同时成功,要么同时失败。否则其中任何一个操作成功了而另一个操作失败了,都会出现上述逻辑错乱的情况~

而RocketMq的事务就是来保证这种场景下的逻辑的,我们来看看RocketMq的事务执行流程

RocketMq的事务机制如图所示:

Spring Cloud(十二):消息中心篇-RocketMq与Kafka选型(四)

1)生产者向broker端发送半事务消息

2)Broker将消息持久化成功之后,向生产者回复ACK,确认半消息已经发送成功

3)接收到响应,生产者便开始执行本地事务逻辑

4)执行结束之后,生产者根据本地事务执行结果,向Broker提交二次确认结果(CommitRollback

此外,若因网络抖动等原因,导致Broker未收到步骤4的二次确认结果时,则需要进行消息回查,进入第5步:


5)经过固定时间后,Broker向生产者将对该消息发起消息回查

6)生产者检查该条消息的本地事务结果

7)发送方根据检查得到的本地事务的最终状态再次提交二次确认(Commit 或Rollback)

8)此时,Broker将有可能收到两种状态

a 若Broker收到Commit状态则将半消息标记为可投递,订阅方最终将收到该消息

b 若Broker收到Rollback状态则删除半消息,订阅方将不会接受该消息


2、Kafka的事务机制


Kafka处理的事务场景则是:确保跨分区的多个写操作的原子性。它的事务特性本质上代表了三个功能:原子写操作,避免重复消息(Zombie fencing)和读事务消息



1)原子写操作


在同一个事务中的消息,要么同时发生成功,要么统一发送失败


2)避免重复消息


在发送事务消息过程中,若生产者集群中某个实例在发送过程中突然宕机,则会由另一个实例进行来替代它的工作,此时若原实例恢复了,继续进行之前的发送工作,便会出现消息重复的情况


而为了解决这种情况,类似于zookeeper解决脑裂问题的一个思想,就是引入epochKafka会在每次进行事务初始化时赋一个递增的epoch值给producer


宕机的实例恢复之后,继续发送消息到broker。而broker只会接收具有最新epoch的生产者的请求,并拒绝掉其他请求,这样便会避免了重复消息(需要注意的是,此处的消息重复场景与上篇文章提到的重复还有一点区别。只是这种因为生产者宕机导致消息重复发送的情况,kafka本身已经通过判断epoch值来直接给避免掉了)


3)读事务消息

为了保证事务特性,Consumer如果设置了isolation.level = read_committed,那么它只会读取已经提交了的消息。在Producer成功提交事务后,Kafka会将所有该事务中的消息的Transaction Marker从uncommitted标记为committed状态,从而所有的Consumer都能够消费

总结

RocketMq的事务机制是两个系统进行处理同一业务流程交易时,保证生产方处理和发送消息阶段两个动作要么同时成功,要么同时失败

而Kafka则是保证生产者发送多条消息可以封装在一个事务中,形成一个原子操作


05.是否支持回溯消费


两者均支持消息的回溯消费


均需要先根据时间戳找到offset,然后从offset开始消费


06.高可用机制不同


两者的高可用机制不同,具体来说是控制的粒度不一样



二 总结

总而言之


RocketMq和Kafka的对比总结篇共4篇文章,分别通过十几个方面,对RocketMqKafka进行了全方位的比较。本篇主要对两者的以下几点进行了分析比较


07.是否支持延时消息

08.消息过滤方式不同

09.消息失败支持重试吗?

10.事务不同

11.是否支持回溯消费?

12.高可用机制不同


相信看到这里,通过两个消息中心各个方面特点的分析比较的形式,你已经比较深入地了解到了这两个消息中心了。


总得来说,两者的设计思路还是有很多相同点的,比如两者的topic均可分为多个分区,写消息均是采用顺序写,发送消息采用零拷贝的方式;其不同点主要体现在两者的部署架构不同日志存储方式不同事务机制不同以及高可用机制不太相同等几点


如果大家有什么疑问,可以翻翻前面几篇文章,如果翻了之后还有疑问,那就欢迎向我留言,探讨一番哦~


嗯,就这样。每天学习一点,时间会见证你的强大~


下期预告:

Spring Cloud(十二):消息中心篇-RocketMq与Kafka选型(四)

展开阅读全文

页面更新:2024-04-03

标签:消息   生产者   原子   分区   机制   事务   两个   操作   方式   系统   中心

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top