美文网首页收藏Java大数据
RocketMQ 原理:消息存储、高可用、消息重试、消息幂等性

RocketMQ 原理:消息存储、高可用、消息重试、消息幂等性

作者: Java弟中弟 | 来源:发表于2022-01-19 13:19 被阅读0次

目录

消息存储

消息存储方式

非持久化

RocketMQ 原理:消息存储、高可用、消息重试、消息幂等性
  1. 消息生成者发送消息到 MQ
  2. MQ 返回 ACK(Acknowledge Character)给生产者
  3. MQ push 消息给对应的消费者
  4. 消息消费者返回 ACK 给 MQ

持久化

RocketMQ 原理:消息存储、高可用、消息重试、消息幂等性
  1. 消息生成者发送消息到 MQ
  2. MQ 收到消息,将消息进行持久化,存储该消息
  3. MQ 返回 ACK 给生产者
  4. MQ push 消息给对应的消费者
  5. 消息消费者返回 ACK 给 MQ
  6. MQ 删除消息

注意:

①第 5 步 MQ 在指定时间内接到消息消费者返回 ACK,MQ 认定消息消费成功,执行 6 。

②第 5 步 MQ 在指定时间内未接到消息消费者返回 ACK,MQ 认定消息消费失败,重新执行 4、5、6 。

消息存储介质

RocketMQ 原理:消息存储、高可用、消息重试、消息幂等性

数据库

  • 实现:ActiveMQ
  • 缺点:数据库瓶颈将成为 MQ 瓶颈

文件系统

  • 实现:RocketMQ/Kafka/RabbitMQ
  • 解决方案:采用消息刷盘机制进行数据存储
  • 缺点:硬盘损坏的问题无法避免

消息存储与读写方式

SSD(Solid State Disk):固态硬盘

  • 随机写(100 KB/s)
  • 顺序写(600 M B/s):1秒1部电影

Linux 系统发送数据的方式

  • “零拷贝”技术数据传输由传统的 4 次复制简化成 3 次复制,减少 1 次复制过程Java 语言中使用 MappedByteBuffer 类实现了该技术要求:预留存储空间,用于保存数据(1G 存储空间起步)
RocketMQ 原理:消息存储、高可用、消息重试、消息幂等性

消息存储结构

RocketMQ 原理:消息存储、高可用、消息重试、消息幂等性

如图所示,MQ 数据存储区域包含如下内容:

  • 消息数据存储区域topicqueueIdmessage
  • 消费逻辑队列minOffsetmaxOffsetconsumerOffset
  • 索引key 索引创建时间索引……

刷盘机制

同步刷盘

RocketMQ 原理:消息存储、高可用、消息重试、消息幂等性
  1. 生产者发送消息到 MQ,MQ 接到消息数据
  2. MQ 挂起生产者发送消息的线程
  3. MQ 将消息数据写入内存
  4. 内存数据写入硬盘
  5. 磁盘存储后返回 SUCCESS
  6. MQ 恢复挂起的生产者线程
  7. 发送 ACK 到生产者

异步刷盘

RocketMQ 原理:消息存储、高可用、消息重试、消息幂等性
  1. 生产者发送消息到 MQ,MQ 接到消息数据
  2. MQ 将消息数据写入内存
  3. 发送 ACK 到生产者

小结

  • 同步刷盘 :安全性高,效率低,速度慢(适用于对数据安全要求较高的业务)
  • 异步刷盘 :安全性低,效率高,速度快(适用于对数据处理速度要求较高的业务)
# 刷盘方式
#- ASYNC_FLUSH 异步刷盘
#- SYNC_FLUSH 同步刷盘
flushDiskType=SYNC_FLUSH

高可用

高可用实现

nameserver

  • 无状态 + 全服务器注册

消息服务器

  • 主从架构(2M-2S)

消息生产

  • 生产者将相同的 topic 绑定到多个 group 组,保证即使 broker master 挂掉,其他 master 仍可正常进行消息接收。

消息消费

  • RocketMQ 自身会根据 broker master 的压力确认是否由 master 承担消息读取的功能,当 master 繁忙时候,自动切换由 slave 承担数据读取的工作。

主从复制

同步复制:

  • master 接到消息后,先复制到 slave,然后反馈给生产者写操作成功
  • 优点:数据安全,不丢数据,出现故障容易恢复
  • 缺点:影响数据吞吐量,整体性能低

异步复制:

  • master 接到消息后,立即返回给生产者写操作成功,当消息达到一定量后再异步复制到slave
  • 优点:数据吞吐量大,操作延迟低,性能高
  • 缺点:数据不安全,会出现数据丢失的现象,一旦 master 出现故障,从上次数据同步到故障时间的数据将丢失

配置方式:

#Broker 的角色
#- ASYNC_MASTER 异步复制Master
#- SYNC_MASTER 同步双写Master
#- SLAVE
brokerRole=SYNC_MASTER

负载均衡

Producer 负载均衡:

  • 内部实现了不同 broker 集群中对同一 topic 对应消息队列的负载均衡

Consumer 两种负载均衡策略:

  • 平均分配
  • 循环平均分配

消息重试

当消息消费后未正常返回消费成功的信息将启动消息重试机制

两种消息重试机制:

  • 顺序消息重试
  • 无序消息重试

顺序消息重试

  • 当消费者消费消息失败后,RocketMQ 会自动进行消息重试(每次间隔时间为 1 秒)。
  • 注意:应用会出现消息消费被阻塞的情况,因此,要对顺序消息的消费情况进行监控,避免阻塞现象的发生。
RocketMQ 原理:消息存储、高可用、消息重试、消息幂等性

无序消息重试

  • 无序消息包括普通消息、定时消息、延时消息、事务消息。
  • 无序消息重试仅适用于负载均衡(集群)模型下的消息消费,不适用于广播模式下的消息消费。
  • 为保障无序消息的消费,MQ 设定了合理的消息重试间隔时长。
RocketMQ 原理:消息存储、高可用、消息重试、消息幂等性

死信队列

概念:

  • 当消息消费重试到达了指定次数(默认 16 次)后,MQ 将无法被正常消费的消息称为死信消息(Dead-Letter Message)。
  • 死信消息不会被直接抛弃,而是保存到了一个全新的队列中,该队列称为死信队列(Dead-Letter Queue)。

死信队列的特征:

  • 归属某一个组(Gourp Id),而不归属 Topic,也不归属消费者。
  • 一个死信队列中可以包含同一个组下的多个 Topic 中的死信消息。
  • 死信队列不会进行默认初始化,当第一个死信出现后,此队列首次初始化。

死信队列中的消息的特征:

  • 不会被再次重复消费。
  • 死信队列中的消息有效期为 3 天,达到时限后将被清除。

死信处理:

  • 在监控平台中,通过查找死信,获取死信的 messageId,然后通过 id 对死信进行精准消费。

消息幂等

消息重复消费

消息重复消费原因:

  • 生产者发送了重复的消息网络闪断生产者宕机
  • 消息服务器投递了重复的消息网络闪断
  • 动态的负载均衡过程网络闪断/抖动broker重启订阅方应用重启(消费者)客户端扩容客户端缩容
RocketMQ 原理:消息存储、高可用、消息重试、消息幂等性

消息幂等

对同一条消息,无论消费多少次,结果保持一致,称为消息幂等性。

解决方案:

  1. 使用业务 id 作为消息的 key 。
  2. 在消费消息时,客户端对 key 做判定,未使用过放行,使用过抛弃。
  • 注意:messageId 由 RocketMQ 产生,messageId 并不具有唯一性,不能作用幂等判定条件。

常见的幂等方法示例:

  • 新增(不幂等):insert into order values(……)
  • 查询(幂等)
  • 删除(幂等):delete from 表 where id=1
  • 修改(不幂等):update account set balance = balance+100 where no=1
  • 修改(幂等):update account set balance = 100 where no=1

相关文章

网友评论

    本文标题:RocketMQ 原理:消息存储、高可用、消息重试、消息幂等性

    本文链接:https://www.haomeiwen.com/subject/hjerhrtx.html