【思维导图】消息队列MQ

838 阅读2分钟

整理自 adjava.netlify.app/#/./docs/hi…

GitHub: github.com/KinghooWei/… 含PDF文件和XMind文件

转载注明出处:juejin.cn/post/693873…

消息队列.png

消息队列

使用场景

解耦

  • 发布订阅消息模型

异步

  • 处理耗时操作

削峰

  • 高并发

种类

ActiveMQ

RabbitMQ

  • 延迟低

RocketMQ

Kafka

缺点

系统可用性降低

系统复杂度提高

一致性问题

高可用

RabbitMQ

  • 单机模式
  • 普通集群模式
  • 镜像集群模式

Kafka

  • 分布式架构:创建topic,划分为多个partition,每个partition放一部分数据,存在于不同的broker上

  • 副本机制:将partition的所有replica分布在不同机器上,通过leader读和写

    • 写:消费者写leader,leader写本地磁盘,follower主动从leader中pull数据,所有follower同步完成后发送ack给leader,leader返回写成功信息给消费者
    • 读:leader收到ack后,才能被消费者读到

设计MQ

参照Kafka,分布式架构,可扩展,增加吞吐量

落地磁盘,顺序写,没有磁盘随机读写的寻址开销

高可用,多副本

数据0丢失

幂等性

场景:消费者还没来得及提交offset,就发生重启

方案

  • 数据库:设置主键,防止出现脏数据;insert之前先查,有则update
  • Redis:天然幂等
  • 生产者发送的数据加一个全局唯一id,每次消费根据id查询Redis,有则丢弃,没则写Redis并处理

可靠性传输

Kafka

  • 消费者:消费者提交了offset,但没来得及处理就挂了

    • 可以先处理再提交offset,但要注意幂等性问题
  • Kafka:follower还没同步好数据,leader就挂了

    • partition至少有2个follower
    • 至少有1个follower跟leader保持联系
    • 数据写入所有follower,生产者才认为写成功
    • 一旦写入失败,无限重试

RabbitMQ

  • 生产者

    • 事务机制
    • confirm机制
  • RabiitMQ

    • 持久化结合生产者的confirm机制
  • 消费者

    • 关闭RabbitMQ自动ack

顺序性

Kafca

  • 消费者开多线程处理数据破坏顺序性

    • 消费之写N个内存queue,具有相同key的数据都到同一个内存queue,对于N个线程,每个线程分别消费一个内存queue

RabbitMQ

  • 多个消费者消费数据,处理时破坏了顺序性

    • 拆分多个queue,每个queue一个consumer

消息积压

修复消费者,暂停运行现有消费者

新建topic,partition是原来的10倍

写一个分发数据的消费者程序

临时征用10倍的机器部署消费者

RocketMQ

  • 提高消费并行度
  • 批量方式消费
  • 跳过非重要消费
  • 优化每条消息消费过程

消息过期失效

批量重导