MQ详解
2021-03-18 15:22:43 36 举报
AI智能生成
MQ详解
作者其他创作
大纲/内容
2.MQ的选型对比<br>
kafka
优势:超高吞吐,可达到10万级别<br>
劣势
天生设计允许丢失数据,保证高吞吐<br>
MQ功能过于简单
也可以使用消息0丢失,但吞吐量会下降
适用场景
大数据领域的用户日志传输,高吞吐,允许数据丢失<br>
RabbitMQ
优势
MQ功能强大<br>
完善的可视化管理工作台<br>
国内大中小公司落地实践案例多<br>
劣势
扛高并发能力较弱
erlang语言开发,不方便改造源码<br>
适用场景
中小型公司业务系统使用,无超高并发场景,无需改造源码<br>
RocketMQ
优势
MQ功能强大
完善的可视化管理工作台<br>
阿里、滴滴、网易等互联网大厂都在用<br>
高并发能力极强<br>
支持数据0丢失的配置<br>
java语言开发,方便改造源码<br>
劣势
官方文档相对简单<br>
适用场景
大中小公司的业务系统
4.RocketMQ底层原理
Broker数据存储机制<br>
为什么Broker数据存储机制是最重要的
commitLog数据存储机制<br>
ConsumeQueue消息offset存储机制<br>
CommitLog写入性能优化<br>
文件顺序追加写入
基于os cache写入<br>
os后台线程异步刷盘<br>
异步刷盘策略
高吞吐,但是会丢失数据
同步刷盘策略
低吞吐,不会丢失数据
Broker读写分离架构原理<br>
CommitLog基于os cache实现写入优化<br>
ConsumeQueue基于os cache实现读取优化<br>
CommitLog基于os cache+磁盘一起读取<br>
CommitLog什么时候从os cache读,什么时候从磁盘读<br>
Master Broker什么时候指示从Slave Broker读<br>
Broker高可用主从架构<br>
基于Dledger管理CommitLog
一组Broker启动时选举leader<br>
Dledger基于Raft协议选举<br>
Raft协议的随机休眠机制<br>
leader可以写入,但是follower不能写入<br>
Leader写入之后进行数据同步<br>
uncommitted消息同步给Follower<br>
过半Follower返回ack即可认为消息写入成功<br>
Dledger在本地执行commit
Dledger将commit消息发送给Follower<br>
Leader崩溃之后<br>
剩余Follower重新选举出Leader
Leader自动热切换
Leader自动完成数据恢复
新Leader继续执行写入任务
producer底层原理<br>
MessageQueue是什么
MessageQueue如何分散在Broker上<br>
写入消息时,如何选择MessageQueue
Broker故障时的容错处理机制<br>
Consumer底层原理<br>
一条消息如何分配给不同的消费组<br>
消费组内部如何分配消息<br>
集群模式<br>
广播模式
MessageQueue如何分配给多台机器消费<br>
如何拉取消息
push模式
pull模式
Broker如何读取数据返回给消费者
基于ConsumeQueue读取消息offset<br>
从CommitLog中读取消息数据<br>
消费者处理消息<br>
回调注册的监听函数来处理<br>
提交消息处理进度<br>
Broker存储consumer的消息Offset<br>
消费组内的重平衡reBalance<br>
消费组内机器宕机<br>
消费组进行机器的扩容<br>
关于MQ使用到的黑科技技术
基于Netty扩展出高性能网络通信架构
基于mmap内存映射实现磁盘文件的高性能读写
RocketMQ相关实践<br>
消息零丢失总体方案
Producer发送消息零丢失方案
RocketMQ事务消息的实现<br>
1.发送half消息(本质上就是需要发送的消息本身),试探MQ<br>
2.若处理逻辑成功,发送对half消息的commit操作指令<br>
3.若处理逻辑失败,则发送rollback操作指令<br>
4.MQ接收half消息成功后,迟迟得不到commit操作指令,则回调补偿生产者,生产者需要对其响应commit或者rollback指令<br>
底层原理详解
正常写入Broker操作流程<br>
1.写入数据到topic,其实是定位到topic中的某个MessageQueue中<br>
2.再定位到某个Broker上,写入该机器上的CommitLog文件中<br>
3.同时将消息索引offset写入到入MessageQueue对应的ConsumeQueue文件<br>
half相关操作流程
1、2相同操作
3.不写入到ConsumeQueue中,而是写入自己内部half_topic中<br>
4.half消息执行commit操作,则在half_topic中标记为commit状态,并将其消息索引写入consumeQueue中<br>
5.half消息执行rollback操作,并不是删除磁盘中commitLog中的数据,而是标记该条消息为rollback状态<br>
6.存在定时任务扫描half消息,不断地去回调补偿生产者,最大尝试次数为15次<br>
Broker存储消息零丢失方案
同步刷盘<br>
Raft协议主从同步<br>
Consumer消息零丢失方案<br>
手动提交offset
自动故障转移<br>
消息零丢失的优势与劣势<br>
优势
劣势
总结
消息重复消费的问题<br>
重复发送(有无必要解决??)
消费方保证幂等性即可,如每次消费查询数据库中是否已经存在该条数据
消费处理异常的问题<br>
重试队列
死信队列
kafka追求吞吐量,牺牲了大部分MQ功能,如不支持重试、死信队列
消息乱序的问题
生产者发送消息导致乱序<br>
消息者消费消息导致乱序<br>
RocketMQ的数据过滤机制
基于tag和属性过滤
支持比较丰富的数据过滤语法
RocketMQ的延迟队消息机制
生产实践经验之谈<br>
基于tag区分同一topic中不同类型数据
基于消息key来定位消息是否丢失
消息零丢失方案的补充
提高消费者的吞吐量
1.增加consumer机器数量<br>
2.增加consumer的线程数量
3.开启消费者的批量消费功能
RocketMQ集群进行消息轨迹的追踪<br>
broker的配置文件里开启traceTopicEnable=true<br>
producer开启true
consumer开启true
控制台进行查看消息轨迹
1.消息中间件是什么
什么是系统同步调用<br>
什么是系统异步调用<br>
如何通过MQ使用异步调用
MQ的作用是有哪些<br>
异步化提升系统性能
系统解耦<br>
高并发削峰
3.RocketMQ简介
RocketMQ核心原理
架构原理<br>
集群化部署
海量消息分布式存储
高可用:主从架构
数据路由:NameServer<br>
NameServer
Peer集群化部署<br>
Broker无差别注册机制<br>
客户端路由机制<br>
Broker长连接与心跳感知<br>
Broker
Master-Slave同步机制
读写分离机制<br>
Master/Slave宕机后处理
Dledger主从自动切换
RocketMQ生产部署方案<br>
NameServer集群化部署
基于Dledger的Broker主从结构部署<br>
Broker与NameServer通信机制
客户端系统集群部署
核心数据模型:Topic是什么?
Topic如何分布式存储在Broker集群中
生产者与消费者如何与Broker通信
RocketMQ生产级参数调整<br>
os内核参数<br>
jvm参数
中间件核心参数
RocketMQ基础使用<br>
生产者<br>
同步发送消息<br>
异步发送消息--异步发送,回调方法接收
单向消息--不接收返回结果
消费者
Push模式消费者<br>
Pull模式消费者<br>
RocketMQ的源码解析
启动nameServer
启动broker
初始化核心配置<br>
启动Netty服务器去接收网络请求
启动核心组件<br>
启动处理请求的线程池<br>
启动执行后台定时任务的线程池<br>
将自己注册到nameserver上去
关于MQ的一些深度思考
(1)Kafka、RabbitMQ他们有类似的数据分片机制吗?他们是如何把一个逻辑上的数据集合概念(比如一个Topic)给在物理上拆分为多个数据分片的?然后拆分后的多个数据分片又是如何在物理的多台机器上分布式存储的?<br>
(2)为什么一定要让MQ实现数据分片的机制?如果不实现数据分片机制,让你来设计MQ中一个数据集合的分布式存储,你觉得好设计吗?
(3)同步刷盘和异步刷盘两种策略,分别适用于什么不同的场景呢?<br>
(4)异步刷盘可以提供超高的写入吞吐量,但是有丢失数据的风险,这个适用于什么业务场景?在你所知道的业务场景,或者工作接触过的业务场景中,有哪些场景需要超高的写入吞吐量,但是可以适度接受数据丢失?
(5)同步刷盘会大幅度降低写入吞吐量,但是可以让你的数据不丢失,你接触哪些场景,是严格要求数据务必不能丢失任何一条,但是吞吐量并没有那么高的呢?
(6)Kafka、RabbitMQ他们的broker收到消息之后是如何写入磁盘的?采用的是同步刷盘还是异步刷盘的策略?为什么?
(7)每次写入都必须有超过半数的Follower Broker都写入消息才可以算做一次写入成功,那么大家思考一个问题,这样做是不是会对Leader Broker的写入性能产生影响?是不是会降低TPS?是不是必须要在所有的场景都这么做?为什么呢?<br>
(8)一般我们获取到一批消息之后,什么时候才可以认为是处理完这批消息了?是刚拿到这批消息就算处理完吗?还是说要对这批消息执行完一大堆的数据库之类的操作,才算是处理完了?
(9)如果获取到了一批消息,还没处理完呢,结果机器就宕机了,此时会怎么样?这些消息会丢失,再也无法处理了吗?如果获取到了一批消息,已经处理完了,还买来得及提交消费进度,此时机器宕机了,会怎么样呢?
(10)消费者机器到底是跟少数几台Broker建立连接,还是跟所有Broker都建立连接?
(11)RocketMQ是支持主从架构下的读写分离的,那什么时候找Slave Broker读取呢?Kafka、RabbitMQ他们支持主从架构下的读写分离吗?支持Slave Broker的读取吗?为什么呢?<br>
(12)如果支持读写分离的话,有没有一种可能,就是出现主从数据不一致的问题?比如有的数据刚刚到Master Broker和部分SlaveBroker,但是你刚好是从那个没有写入数据的Slave Broker去读取了?
(13)消费吞吐量似乎是跟你的处理速度有很大关系,如果你消费到一批数据,处理太慢了,会导致你严重跟不上数据写入的速度,这会导致你后续几乎每次拉取数据都会从磁盘上读取,而不是os cache里读取,所以你觉得你在拉取到一批消息处理的时候,应该有哪些要点需要注意的?
0 条评论
下一页