RocketMQ零碎知识点
1.事务消息如何保证
- 基于两阶段提交和定时任务回查
2.事务消息执行流程
- 1.应用程序完成本地事务后,同步调用MQ消息发送接口,发送状态为prepare的消息,发送成功后等待本地事务的执行情况。为两阶段提交的第一阶段
- 2.同时MQ会将prepare消息备份其主题和消息队列,将消息存储在RMQ_SYS_TRANS_HALF_TOPIC的消息消费队列中,然后会开启一个定时任务,消费该消息队列的消息,并向应用程序发起消息事务状态回查,根据反馈的状态之下,同时设有回查次数,超过次数未获取到状态,默认回滚。此为定时任务回查
- 3.根据本地事务的返回状态执行提交,回滚,然后结束事务。此为两阶段提交的第二阶段
3.消息的存储
- Commitlog 存储所有主题的消息,顺序写入,通过文件名表示的偏移量来定位第一条消息
- ConsumeQueue 相当于主题跟队列的索引,一个消费队列对应一个文件,异步将消息转发到该队列
- IndexFile 加速消息的检索,主要存储消息Key和Offset的对应关系
存储优化
- MappedFile 内存映射文件,是一种预先分配机制
- TransientStorePool 短暂存储池,将内存映射的数据定时复制到目的物理文件对应的内存映射,是一种内存锁定,避免被进程将内存交换到磁盘
4.过期文件删除机制
- 非当前写文件在一定时间间隔内没有被再次更新,则认为是过期文件,可以直接删除。时间间隔默认72小时
5.消息存储最终一致性保证
- 当Broker由于某个原因宕机,会导致存储的三个文件不一致
- 若Broker上一次是异常退出,会在store目录下留下一个abort文件,这个abort文件是通过启动创建,正常退出时通过JVM钩子函数删除该文件,因此下一次启动时存在该文件,说明为异常退出,需要进行数据修复
6.MQ选型以及其他MQ优缺点
- RabbitMQ,erlang开发,吞吐量相较于rocketmq低了一个数量级,每秒处理几万到几十万的消息,当大量消息堆压时性能会急剧下降
- Kafaka,适合日志等离线处理场景,因为延时较高。社区活跃,生态完善,支持消息大量堆积,可以批量发送的接受消息,拥有极高的吞吐量
- RocketMQ,java开发,分布式场景下的高可靠性,支持大量消息堆积,支持事务消息,可以批量接受消息,不能批量发送消息,吞吐量次于Kafaka
7.RocketMQ组件及特点
- NameServer:无状态的注册中心,可以集群化,相互之间无消息传递
- Producer:消息的生产者,负责发送消息到Broker
- Broker:mq的核心,负责消息收发和持久化
- Consumer:消息的消费者,负责从Broker拉取消息进行消费,并在消费完之后进行ack
8.集群消费与广播消费
- mq默认为集群消费,即一条消息只会在同一个个group中只会消费一次
- 广播消费,本质上是无视了group的划分,每个消费者都会进行消费
9.NameServer作用
- 路由发现:30s心跳检查更新时使用了读写锁,因此路由管理的保存用的是线程不安全的HashMap。且为非实时,由客户端拉取路由的时候发现broker的变化,由客户端去处理,保证NameServer的简洁性
- 路由管理:保存Broker的活跃列表和Topic的对应关系
- 路由删除:若broker2分钟没有发送心跳数据则从路由中删除
10.NameServer与Zookeeper的区别
- NameServer无状态,节点之间无信息同步
- Zookeeper分主从读写的角色,意外情况需要选举产生master,复杂度高,但数据一致性好
11.重复消费如何解决
出现原因:
- 1.业务上重复和mq发送消息
- 2.消费者消费完成后ack时未成功到达导致的重复消费
解决方案:核心思路:若能保证消息的幂等性,重复消费就不会造成业务上的问题 - 1.生产者幂等性:发送时先查询消息中是否存在,缺陷,高并发时效率下降。方案二:成功发送到mq后写入redis记录,每次在redis中查询,缺陷,不能完全保证幂等
- 2.消费者幂等:在业务对应的数据库操作中进行查询数据是否已经生效
12.如何保证顺序消费
- 将需要顺序消费的消息放入同一topic中
13.RocketMQ怎么保证消息不丢失
- Produce端:采用send()同步发送,设置失败重试
- Broker端:设置为同步刷盘(默认是异步刷盘),即刷盘成功返回ack。同时需要集群部署,主从部署,并设置主从复制为同步复制
- Consumer端:消费完成返回ConsumeConcurrentlyStatus.CONSUME_SUCCESS认为消费成功,否则进行重新消费
14.RocketMQ怎么处理消息堆积
- 扩容comsumer
- producer限流
- 若是queue数量不足,可以启动consumer搬运topic到新的topic来扩充queue
15.RocketMQ高可用
- 存储高可用:Brocker采用master,slave集群,master支持读写,slave仅支持读,brokerId为0表示该broker为master
- 消费高可用:Consumer进行消费时,若当前master不可用,会自动切换到slave读
- 发送高可用:一个topic对应多个broker组,其中一个master不可用时,其他组的master仍可用,但不支持slave升级master