RocketMQ和Kafka的区别,以及如何保证消息不丢失和重复消费

这篇具有很好参考价值的文章主要介绍了RocketMQ和Kafka的区别,以及如何保证消息不丢失和重复消费。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

消息队列RocketMQ和Kafka的区别

性能(单台) 语言 多语言支持客户端 优缺点
RocketMQ 十万级 java java
  • 模型简单、接口易用,在阿里有大规模应用
  • 文档少,支持的语言少
Kafka 百万级 服务端scala,客户端java 主流语言均支持
  • 天生分布式、性能最好,常用于大数据领域
  • 运维难度大,对zookeeper强依赖,多副本机制下对带宽有一定要求
  • RocketQA适用于高性能、高可用的消息传递场景,具有丰富的消息过滤和分布式事务特性;
  • Kafka适用于高吞吐量、低延迟的实时数据处理和事件驱动的架构场景,具有良好的可伸缩性和持久性

Kafka 消费顺序、消息丢失和重复消费

RocketMQ和Kafka的区别,以及如何保证消息不丢失和重复消费,中间件,rocketmq,kafka,分布式

Kafka 采用的是发布 - 订阅模型。

RocketMQ 的消息模型和 Kafka 基本是完全一样的。唯一的区别是 Kafka 中没有队列这个概念,与之对应的是 Partition(分区)

Kafka的多副本机制

Kafka 为分区(Partition)引入了多副本(Replica)机制。

分区(Partition)中的多个副本之间会有一个叫做 leader 的家伙,其他副本称为 follower。我们发送的消息会被发送到 leader 副本,然后 follower 副本才能从 leader 副本中拉取消息进行同步。生产者和消费者只与leader副本做交互。

Kafka 的多分区(Partition)以及多副本(Replica)机制有什么好处呢?

  1. Kafka 通过给特定 Topic 指定多个 Partition, 而各个 Partition 可以分布在不同的 Broker 上, 这样便能提供比较好的并发能力(负载均衡)。
  2. Partition 可以指定对应的 Replica 数, 这也极大地提高了消息存储的安全性, 提高了容灾能力,不过也相应的增加了所需要的存储空间。

Kafka如何保证消息的顺序消费

  • 一个topic只对应一个partition
  • (推荐)发送消息的时候指定key/partition【采用对象的id做为key】

Kafka 中发送 1 条消息的时候,可以指定 topic, partition, key,data(数据) 4 个参数。如果你发送消息的时候指定了 Partition 的话,所有消息都会被发送到指定的 Partition。并且,同一个 key 的消息可以保证只发送到同一个 partition,这个我们可以采用表/对象的 id 来作为 key 。

如何保证消息不丢失

  • 生产者消息丢失

生产者消息是如何丢失的?

生产者调用send方法发送消息之后【异步操作】,消息可能因为网络原因没有发出去

为了确定消息发送是否成功,需要判断消息发送的结果。

一般采用如下做法,采用回调函数获取消息发送的状态,并且为生产者设置重试次数和重试间隔,一般为3

@Slf4j
public class KafkaDemo {
    @Autowired
    KafkaTemplate kafkaTemplate;

    public void sendMessage(String topic,Object o) throws ExecutionException, InterruptedException {
        ListenableFuture<SendResult<String, Object>> future= kafkaTemplate.send(topic,o);
        future.addCallback(new ListenableFutureCallback<SendResult<String, Object>>() {
            @Override
            public void onFailure(Throwable ex) {
                log.error("生产者发送消息:{} 失败,原因:{}", o.toString(), ex.getMessage());
            }

            @Override
            public void onSuccess(SendResult<String, Object> result) {
                log.info("生产者成功发送消息到topic:{} partition:{}的消息",result.getProducerRecord().value().toString());
            }
        });
    }
}
  • 消费者消息丢失

消息在被追加到 Partition(分区)的时候都会分配一个特定的偏移量(offset)。偏移量(offset)表示 Consumer 当前消费到的 Partition(分区)的所在的位置。Kafka 通过偏移量(offset)可以保证消息在分区内的顺序性

消费者消息是如何丢失的?

当消费者拉取到了分区的某个消息之后,消费者会自动提交了 offset。自动提交的话会有一个问题,试想一下,当消费者刚拿到这个消息准备进行真正消费的时候,突然挂掉了,消息实际上并没有被消费,但是 offset 却被自动提交了

解决方案:

关闭自动提交offset,每次在真正消费完消息之后再手动提交offset。

但是这样也会带来重复消费的情况,比如,消费了一半还没提交offset突然挂掉,那么这个消息理论上会被消费两次,这种情况怎么办?【保证幂等性】

  • kafka丢失了消息

kafka是如何丢失消息的?【多副本机制】

假如 leader 副本所在的 broker 突然挂掉,那么就要从 follower 副本重新选出一个 leader ,但是 leader 的数据还有一些没有被 follower 副本的同步的话,就会造成消息丢失。

1)acks=all 所有副本全部收到消息时,生产者才会接收到来自服务器的响应

2)  replication.factor >= 3 每个分区至少有3个副本

3)  min.insync.replicas > 1 消息至少被写入2个副本,才算是被成功发送

4)unclean.leader.election.enable = false 当leader副本发生故障时不会从followers副本中和leader副本同步程度达不到要求的副本中选出leader,降低了消息丢失的可能性。

如何保证消息不被重复消费

kafka出现重复消费的原因?

1)消费者已经消费了的消息没有正确提交offset(根本原因)

2)kafka侧因为服务端业务处理时间过长或者网络连接等原因,让kafka认为服务假死,触发了分区rebalance

解决方案

  • 消费者做幂等校验【如redis的set、mysql的主键等天然的幂等功能】
  • 关闭自动提交,enable.auto.commit=false,开发者在代码中手动提交offset
    • 消费完消息再提交:依旧有重复消费的风险,和自动提交一样
    • 拉取到消息即提交:会有消息丢失的风险,允许消息延时的场景,一般采用这种方式。通过定时任务在业务不繁忙的时候做数据兜底。

Kafka失败重试机制

kafka消费者默认配置下最多重试10次,每次时间间隔0,即立即重试。如果在 10 次重试后仍然无法成功消费消息,则不再进行重试,消息将被视为消费失败。

RocketMQ顺序消费、消息丢失和重复消费

生产者组中的生产者会向主题发送消息,而 主题中存在多个队列,生产者每次生产消息之后是指定主题中的某个队列发送消息的。

RocketMQ和Kafka的区别,以及如何保证消息不丢失和重复消费,中间件,rocketmq,kafka,分布式

RocketMQ 通过使用在一个 Topic 中配置多个队列并且每个队列维护每个消费者组的消费位置 实现了 主题模式/发布订阅模式 

顺序消费

RocketMQ在topic上是无序的,只有在队列层面才能保证是有序的。

【把同一主题消息放入相同的队列】

顺序需要由3个阶段去保障:

  • 消息被发送时保持顺序
    • 将同一订单的消息发送到相同的队列【通过MessageQueueSelector来实现队列的选择】,通过对订单的唯一标识做Hash,将同一个订单的消息发送到相同的队列
  • 消息被存储时保持和发送时顺序一致
  • 消息被消费时保持和存储时的顺序一致
    • 同一个订单的消息被同一个消费者消费【订单id做hash选择相同的队列】
    • 消费者消费完一条消息之后,才能接着消费下一条【单线程消费】

消息不丢失、可靠性保证

  • 发送端丢失消息
    • 发送端在发送消息时,传入回调接口实现类,调用该发送接口后不会阻塞,发送方法会立即返回,回调任务会在另一个线程中执行,消息发送结果会回传给相应的回调函数。具体的业务实现可以根据发送的结果信息来判断是否需要重试来保证消息的可靠性。
  • 存储端丢失消息
    • 主从复制保证
  • 消费端丢失消息
    • 消费重试
    • 死信队列
      • 未能成功消费的消息,消息队列并不会立刻将消息丢弃,而是将消息发送到死信队列,其名称是在原队列名称前加%DLQ%,如果消息最终进入了死信队列,则可以通过RocketMQ提供的相关接口从死信队列获取到相应的消息,保证了消息消费的可靠性。
    • 消息回溯
      • Consumer已经消费成功的消息,或者之前消费业务逻辑有问题,现在需要重新消费。要支持此功能,则Broker存储端在向Consumer消费端投递成功消息后,消息仍然需要保留。重新消费一般是按照时间维度,例如由于Consumer系统故障,恢复后需要重新消费1小时前的数据。RocketMQ Broker提供了一种机制,可以按照时间维度来回退消费进度,这样就可以保证只要发送成功的消息,只要消息没有过期,消息始终是可以消费到的

重复消费

消费者端做幂等

如何解决消息堆积

产生原因:生产者生产消息过快or消费者消费消息太慢

生产者限流降级,增加多个消费者实例。文章来源地址https://www.toymoban.com/news/detail-795458.html

到了这里,关于RocketMQ和Kafka的区别,以及如何保证消息不丢失和重复消费的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 一线大厂面试真题-Kafka如何保证消息不丢失

    目录 问题解答 面试点评 (如图) kafka 是 一个用来实现异步消息通信的中间件,它的整个架构由Producer、 Consumer 、 Broker组成。 所以,对于 kafka 如 何保证消息不丢失这个问题,可以从三个方面来考虑和实现 : 首先 是Producer端,需要确保消息能够到达Broker并实现消息存储,在这

    2024年02月01日
    浏览(60)
  • 一文彻底搞懂Kafka如何保证消息不丢失

    Producer:生产者,发送消息的一方。生产者负责创建消息,然后将其发送到 Kafka。 Consumer:消费者,接受消息的一方。消费者连接到 Kafka 上并接收消息,进而进行相应的业务逻辑处理。 Consumer Group:将多个消费者组成一个消费者组,一个消费者组可以包含一个或多个消费者。

    2024年04月22日
    浏览(42)
  • Kafka、RocketMQ、RabbitMQ如何保证消息的顺序消费?

    一、1个Topic(主题)只创建1个Partition (分区),这样生产者的所有数据都发送到了一个Partition (分区),保证了消息的消费顺序; 二、生产者在发送消息的时候指定要发送到哪个 Partition,这样同一个 Partition 的数据会被同一个消费者消费,从而保证了消息的消费顺序。 实现思路

    2024年02月09日
    浏览(48)
  • Kafka如何保证消息的消费顺序【全局有序、局部有序】、Kafka如何保证消息不被重复消费、Kafka为什么这么快?【重点】、Kafka常见问题汇总【史上最全】

    目录 Kafka消息生产 一个Topic对应一个Partition 一个Topic对应多个Partition Kafka消息的顺序性保证(Producer、Consumer) 全局有序 局部有序  max.in.flight.requests.per.connection参数详解 Kafka的多副本机制 Kafka的follower从leader同步数据的流程 Kafka的follower为什么不能用于消息消费 Kafka的多分区

    2024年04月11日
    浏览(54)
  • mq常见问题:消息丢失、消息重复消费、消息保证顺序

    mq常见问题:消息丢失、消息重复消费、消息保证顺序 消息丢失问题 拿rabbitmq举例来说,出现消息丢失的场景如下图 从图中可以看到一共有以下三种可能出现消息丢失的情况: 1 生产者丢消息 生产者在将数据发送到MQ的时候,可能由于网络等原因造成消息投递失败 2MQ自身丢

    2024年02月09日
    浏览(60)
  • Kafka怎么保证数据不丢失,不重复

    生产者数据不丢失 Kafka的ack机制:在kafka发送数据的时候,每次发送消息都会有一个确认反馈机制,确保消息正常能够被收到,其中状态有0,1,-1. ack = 0:producer不等待broker同步完成的确认,继续发送下一条(批)信息。 ack = 1(默认):producer要等待leader成功收到数据并确认,

    2024年02月11日
    浏览(50)
  • 消息中间件(RocketMQ、RabbitMQ、ActiveMQ、Redis、kafka、ZeroMQ)以及之间的区别

    目录 一、什么是消息中间件 二、消息中间件的组成 1、Broker 2、Producer 3、Consumer 4、Topic 5、Queue 6、Message 三、消息中间件通信模式 1、点对点(kafka不支持这种模式)  2、发布/订阅  四、消息中间件的作用 1、系统解耦 2、提高系统响应时间 3、为大数据处理架构提供服务 五、

    2024年01月25日
    浏览(52)
  • 大数据面试题:Kafka怎么保证数据不丢失,不重复?

    面试题来源: 《大数据面试题 V4.0》 大数据面试题V3.0,523道题,679页,46w字 可回答:Kafka如何保证生产者不丢失数据,消费者不丢失数据? 参考答案: 存在数据丢失的几种情况 使用同步模式的时候,有3种状态保证消息被安全生产,在配置为1(只保证写入leader成功)的话,

    2024年02月15日
    浏览(41)
  • Kafka怎么保证消息发送不丢失

    Kafka发送消息是异步发送的,所以我们不知道消息是否发送成功,所以会可能造成消息丢失。而且Kafka架构是由生产者-服务器端-消费者三种组成部分构成的。要保证消息不丢失,那么主要有三种解决方法: 生产者(producer)保持同步发送消息 服务器端(broker)持久化设置为同

    2024年02月04日
    浏览(54)
  • kafka消息丢失面试题,RocketMQ消息丢失场景及解决办法

    互联网行业更新换代非常快,行业常态便是不断学习,因此这些主流技术你一个都不能落下! ①并发编程 Java并发编程是整个Java开发体系中最难以理解,但也是最重要的知识点之一,因此学习起来比较费劲,从而导致很多人望而却步,但是无论是职场面试还是高并发高流量的

    2024年03月17日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包