侧边栏壁纸
博主头像
Mr.D的小破站博主等级

身如柳絮随风扬,无论云泥意贯一

  • 累计撰写 21 篇文章
  • 累计创建 9 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

MQ

Mr.D
2024-11-29 / 0 评论 / 0 点赞 / 3 阅读 / 7866 字

为什么使用消息队列?

  1. 异步处理

    1. 同样的时间可以做更多的事情,实现快速响应

  2. 系统解耦

    1. 比如订单和库存系统是高耦合,使用mq,订单系统写消息到mq,库存系统从mq拉取数据,从而实现解耦。

  3. 流量削峰

    1. 通过MQ接收大量的请求,在平滑地将消息发送给DB,达到解耦,缓解压力。跟“水库”一样。

如何保证消息队列的高可用?

kafka由多个broker(kafka实例)组成,每个broker是一个节点;创建一个topic(消息的主题),可以划分多个partition(topic分区),每个partition可以作用于不同的broker上,每个partition就放一部分数据,每个partition可以设置相应的副本来做高可用。

分区可以解决存储问题,副本解决高可用问题。

如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?

消费者幂等性

幂等性

  1. 依赖数据库的主键或唯一键

  2. 自己写一个去重表(日志表),当前操作的这个业务一定要和去重表在同一事务中

依赖redis去重

更新的时候,可以带版本更新

修改version字段

生产者幂等性

生产者发送消息会携带pid和这条消息的序号,在paration存储消息,pid,序号。如果生产这没有收到broker的ack确认,重复发送,broker会检查对应的pid和序号是否存储。

如何保证消息的顺序性?

生产这写入消息到topic,kafka将根据不同的策略将数据分配到不同的分区中。

  1. 轮询分区策略

  2. 随机分区策略

  3. 按key分区分配策略

轮询,随机都会导致一个问题,生产到kafka的数据是乱序存储的。按key分区可以实现局部有序,但会造成数据倾斜,所以按照实际情况来取舍。

如何保证消息的可靠性传输?或者说,如何处理消息丢失的问题?

消费端弄丢数据:

你没有消费到这个消息,但kafka以为你消费好了,造成消息丢失。关闭自动提交offset,自己手动提交offset

kafka弄丢了数据:

kafka的某个broker宕机了,重新选举partition的leader,leader宕机了,重新选个follower称为leader,数据会少了一些。

  1. 要求每个partition至少由2个副本

  2. 在producer端设置acks=all。要求每条数据,必须是写入所有replica之后,才能认为是写成功了

  3. producer端设置retries=max(很大值)。写入失败,就无限重试。

说一下kafkaack机制

  1. ack为0时,不等待broker确认,直接发送下一条数据,性能最高,但可能会存在数据丢失的情况。

  2. ack为1时,等待leader副本确认接收后,才会发送下一条数据,性能中等

  3. ack为-1或者all时,等待所有副本已经将数据同步后,才会发送下一条数据,性能最慢

kafka如何实现单播和多播

单播

一条消息只能被某一个消费者消费的模式称为单播。要实现消息单播,只要让这些消费者属于同一个消费组即可。当生产者发送一条消息时,两个消费者中只有一个能搜到消息。

多播

让多个消费者分别属于不同的消费组就可以实现多播。

广播

每个消费者属于不同的消费组

kafka体系结构

一个topic下有多个分区

一个分区有多个副本,但是只有一个leader,其他follow。读写在leader,follow是备份容灾。

消息积压

新建一个topic,可以有多个分区,可以启用多个consumer。把之前topic的consumer收到的消息不处理,直接发给新的topic。

0

评论区