88.kafka如何保证消息的顺序性

一、MQ遵循投递消息先进先出原则

1.为什么MQ会产生消息顺序的问题?

1.消费者集群;。
2. MQ服务端如果是集群;
在这里插入图片描述
单个消费者:
单个消费者情况下,MQ的队列会根据先进先出的原则,消费的顺序是不会打乱的、。I

在这里插入图片描述
当消费者集群:
mq消费者订阅到同一个队列情况时,消费者会做均摊消费或者是公平消费
有可能出现一下情况:在这里插入图片描述单个消费者情况下,MQ的队列会根据先进先出的原则,消费的顺序是不会打乱的。

2.队列原则:

先进先出

3.MQ消息顺序的行为产生的背景:

1.当我们往MQ中同一个队列投递消息行为不统一的情况 消费者在消费的时候就会产生先后顺序问题
注意:单台消费者是不存在消息的顺序的问题,但是单机版本的消费吞吐比较低,所以一般消费者肯定要集群
在多个消费者消费同一个队列中的消息时候,有可能产生消息顺序行为错乱的问题。

三、MQ顺序消息产生的背景有那些

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

不同broker,相当于不同的服务器,不确定消费者先拿到哪一个服务器 的消息。
在这里插入图片描述

四、MQ如何保证消息的顺序性

    @RequestMapping("/getOrderKafka")
    public String getOrderKafka() {
        String orderId = System.currentTimeMillis() + "";
//        // 发送insertmsg
        sendMsg(getSqlMsg("insert", orderId));
        // 发送Updatemsg
        sendMsg(getSqlMsg("update", orderId));
        // 发送deletemsg
        sendMsg(getSqlMsg("delete", orderId));
         return "success";
  private void sendMsg(String data) {
        // topic 名称 key data 消息数据
        kafkaTemplate.send("mayikt-topic", data);

    }
 public String getSqlMsg(String type, String orderId) {
        JSONObject dataObject = new JSONObject();
        dataObject.put("type", type);
        dataObject.put("orderId", orderId);
        return dataObject.toJSONString();
    }

运行结果:
不同分区 ,单个消费者获取消息的顺序 会不确定。
broke集群,单个消费者,消费消息的顺序会打乱。
在这里插入图片描述
在这里插入图片描述

五、解决MQ消息顺序的问题核心思路

1、为什么我们的MQ服务器端集群的话,单个消费者消费消息顺序会被打乱?

因为我们的投递消息分别存放到多个不同的Broker存放,单个消费者获取所有的Broker建
立长连接,获取顺序可能是随机的。

在这里插入图片描述
在这里插入图片描述
参数多了key
orderId作为key, key相同hash值就会相同,则会被分到同一个broker中。一个消费者,必定会按照 存放 先进先出的顺序来消费。

  @RequestMapping("/getOrderKafka")
    public String getOrderKafka() {
        String orderId = System.currentTimeMillis() + "";
        send(orderId, getSqlMsg("insert", orderId));
        // 发送Updatemsg
        send(orderId, getSqlMsg("update", orderId));
        // 发送deletemsg
        send(orderId, getSqlMsg("delete", orderId));
        return "success";
    }
/**
     * 发送消息的方法
     *
     * @param key  推送数据的key
     * @param data 推送数据的data
     */
private void send(String key, String data) {
        // topic 名称 key data 消息数据
        kafkaTemplate.send("mayikt-topic", key, data);

    }

运行结果:顺序没有被打乱在这里插入图片描述在这里插入图片描述

2、在什么样的情况下,消费者获取消息顺序不会打乱

(同一个 Broker、同一个消费者)。

3、如何解决kafka或者rocketmq消息顺序的问题?

答案:对相同业务逻辑设置相同的消息key,存放到同一个broker,最终对应一个消费者实
现消费。。

六、解决MQ消息顺序的问题总结

1.MQ如何保证消息的顺序的问题?

1.如果我们的生产者往我们的MQ投递消息行为不一样,可能会产生消息顺序的问题,。
如果我们的投递的消息到同一个队列中行为是一样的情况下,没有必要在意消息顺序的问
题。。
2.我们的 MQ存放消息默认的情况下本身就是有一定顺序,遵循先进先出的原则(单个MQ
情况下)。
3. 如果我们有多个消费者订阅同一个队列的情况下,可能会产生消费者顺序会被打乱
4.如果我们的Broker是集群的情况下,因为不同的消息可能会存放多个不同的Broker中,
单个消费者在获取消息的时候顺序可能会被打乱

2.解决消息顺序的核心思路:

保证我们的消息存放到同一个Broker中,对应只有一个消费者实现消费;。
备注: kafka对我们的消息设置相同的key, key 可以根据业务来定。。
但是我们的单个消费者消费消息吞吐非常低,可以采用消费者批量获取我们的消息,让后采
用内存队列实现存放。(也会根据消息都key计算相同的key存放到同一个内存队列中),
每个内存队列只会对应的一个线程实现处理。

3.多个内存队列,等同于 消费者集群。没有解决问题。

kafka严格解决消息顺序问题,只能是 一个消费者来消费
在这里插入图片描述

七、kafka的消费者分组的概念设计

在这里插入图片描述

1、当所有消费者在同一个分组,有3个分区:

在这里插入图片描述
有3个分区,2个消费者时:一定会有一个消费者消费2个分区。
此处演示的是 消费者1 分区0、分区1;消费者2只消费 分区2。保证严格按照顺序来消费。
当有3个消费者时,消费者1会消费 分区1,消费者2会消费 分区2,消费者3会消费 分区3.

1.1、当有2个消费者:

该消费者1只消费 分区0、分区1
在这里插入图片描述
该消费者2只消费 分区2在这里插入图片描述

1.2、当有3个消费者:

在这里插入图片描述
在这里插入图片描述

2、当2个消费者不在同一个组:

在这里插入图片描述

在这里插入图片描述
消费者1:
在这里插入图片描述
消费者2:
在这里插入图片描述
不在同一个组,可以重复消费。

3、Kafka的分组的特性:

1.如果多个消费者在同一个组内,最终只会有一个消费者实现消费消息;
2.Kafka分组默认消费者与Broker一对一;

八、为什么kafka吞吐高的原因

1、Kafka吞吐量为什么比较高原因:

  1. 使用顺序写的形式存储我们的数据。
    2.生产者和消费者都支持的批量处理
    采用异步形式+缓存区投递消息
    缺点:数据可能会产生丢失。
    3.数据的零拷贝 NI0支持。
    4.实 现对我们的topic分区存放。
    5.对我们数据实现压缩、减少带宽传输。。

在这里插入图片描述

数据的零拷贝:

在这里插入图片描述
在这里插入图片描述

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页