消息队列学习
2022-06-14 23:03:20 0 举报
问题分析
作者其他创作
大纲/内容
A接受请求到返回结果25ms,对用户而言25毫秒直接返回结果,爽
broker 1partition1follower->leader
borker进程就是kafaka在每一台机器上启动的一个自己的进程
消费者
如何解决RabbitMQ消息顺序消费
queue
如果没有高可用机制保障,如果有问题(假设第二台机器宕机,将会有1/3的数据丢失),做不到高可用
partition2
borker进程
2.哪个需要数据自己到MQ中去消费
1.缺点一在RabbitMQ中会有大量的积压数据2.缺点二:几乎没有什么可用性,如果queue所在的节点宕机,queue数据丢失,没有办法消费
数据2
数据3
broker 1partition1 follower
数据1
MQ队列
partition1
假设RabbitMQ集群有3台机器,每台机器都启动了一个进程,作为集群的一个节点
原来3个消费者1小时才可以解决几百万条数据积压,扩容30个临时消费者10分钟就可以搞定
数据库
数据2
queue元数据
topic partition2副本2
用户
r-s3
r-m2
算一笔账:每秒积压3000条消息,一分钟积压18万,一小时积压1000万条消息,A系统处理需要处理1.2小时
A系统
一台机器
使用接口异步化接口调用
1.产生一条数据,发送消息到MQ中
消费者1
RabbitMQ(进阶实例)独立部署在一台机器上
Kafaka
绝对不行
数据1,offset=152
内存队列1
2.系统考虑的问题变多,导致系统复杂性变高
thread
Kafaka消息丢失场景
对于数据1和数据2,实际上消费了两次,就会出现消息重复消费
消息1
B系统
生产者
RabbitMQ节点
D系统
高可用:任何一个节点宕机了,其他节点还包含queue的完整数据,别的consumer还可以到其他节点消费数据
Kafaka重复消费的事情
RabbitMQ消息丢失解决方案1.将queue设置为持久化的,这样可以保障queue元数据持久化,但不会持久化Queue里面的数据2.发送消息时将消息的deliverMode设置为2,这是将消息持久化,此时消息才会将消息持久化到磁盘上去
MySQL
2.大量请求涌入系统中,高峰期每秒访问5000次
RabbitMQ可能存在顺序不一致情况
假如消费者被重新启动,消费者会找到kafaka,把上次消费记录的下一条记录发给我
消费者30
通知你消息1已接受
broker 1partition1leader
r-s2
1.中午高峰期100万用户,大量操作每秒5000个请求
数据3,offset=154
包含数据2
RabbitMQ的普通模式集群原理解析
调用接口
r-m3
生产这只能往leader写数据
事务同步的会导致生产者发送消息同步阻塞等待消息发送成功或失败会导致生产者发送消息吞吐量下降
MQ
3.消费者消费到了这条消息还没来得及处理就挂掉了,结果RabbitMQ以为消费者完了
C系统
包含数据1
3.如果新系统需要数据自己到MQ中去消费
r-m1
RabbitMQ
使用MQ系统解耦
消费者消费完数据准备提交offset但还没提交时发生重启,此时offset并没有提交,kafaka并不知道已经消费了offset=153的那条数据了
数据1,id=1
没有使用MQ之前系统依赖严重
在生产者那里提供一个回调的借口public void ack(String message){}public void nack(String message){//再次重发一次消息}
topic partition2副本1
autoAck
channel.confirm发送消息然后就OK了
架构中引入MQ可能存在的问题
解决方案一:channel.txselecttry{//发送消息}catch(){channel.txRollback//再次尝试发送}finally{channel.txCommit}
如果MySQL被打死,系统将崩溃,用户将没办法使用系统
3.一致性问题,向系统A发送请求,本来只有当ABCD都成功才能返回
topic partition1副本1
5.C系统本地耗时450ms
消费者不是消费完一条记录就提交offset,而是定时定期提交offset
5.哪怕是最高峰时系统也不会挂掉
3.系统直接基于MySQL,大量请求涌入MySQL,每秒预计执行5000条SQL
如何保证MQ消息不丢失
数据4
2.将5000请求写入MQ中
4.B系统本地耗时300ms
使用MQ进行削峰
partition3
partition30
1.中午高峰期有大量用户(100万用户),通过浏览器进行大量操作
4.如果系统不需要数据取消对MQ消费即可
queue2
用MQ削峰
写入一个partition是有顺序的
生产者在topic生产了3条数据
变为follower
r-s1
解决办法相同ID的key放入一个队列中
消费者从kafaka消费时,按照这个顺序消费
queue3
物理网卡
E系统
消费者从partition中取出的数据一定是有序的
缺点:不是分布式的,如果queue数据量过大,大到机器容量无法容纳,该怎么办?
3.A系统组多每秒只能处理2000个请求,因为MySQL的QPS为2000
没用MQ系统在高峰期被打死
5.系统压根不考虑数据发送给谁;不需要维护代码;不需要考率是否调用成功;失败超时
消费者会提交数据,就是告诉kafaka以消费到offset=153这条数据
zookeeper
说明:一般MySQL每秒扛到2000个请求就差不多了,如果请求直接到5000的话可能直接会把MySQL打死
内存setid=1
1.系统可用性降低
3.每个系统从自己对应的MQ队列中消费相应的消息,消息队列中提取参数,执行相应操作
肯定消费者多线程要并发处理,消费者4核8线程,单机最多每秒处理上前条消息
8.所有高峰期一过,A系统就会对积压的消息处理掉
queue元数据和实际数据一条数据一条数据一条数据
高可用架构已经出来了,一台机器宕机,会从其他follower中选取一台出来作为leader
1.几百万条消息积压2.消息积压导致MQ导致磁盘满了,将消息写入临时MQ增加partition为原来10倍对于消费者也增加10倍3.消息积压(设置过期时间),导致消息丢失,重新导一份数据
解决RabbitMQ消费顺序存在顺序不一致情况
topic partition1副本2
磁盘
2.RabbitMQ在接收到消息后暂存到内存里,结果消费者还没来得及消费RabbitMQ就挂掉了
kafaka
结果:ABC都执行成功了D执行失败,结果给用户返回的是成狗,但后台逻辑差一点完成
选举数据1为leader
如何解决Kafaka消息顺序消费
包含数据3
4.系统每秒在MQ中拉取2000个请求,不超过自己的最大处理极限
消费者只能从leader消费数据
如何保证MQ重复消费的幂等性
本台机器+Boker进程就可以认为是kafaka上的一个节点
Kafaka高可用架构
写入数据到leader时会将数据同步到follower
7.消息积压是正常的,高峰期过后,每秒请求数量可能就50个请求进入MQ,但A系统还会每秒处理2000的速度在处理
解决方案二:1.先把channel设置为confirm的状态2.发送消息3.发送完消息就不用管了4.如果RabbitMQ接收到这条消息成功,就会回调生产者本地接口,通知消息发送成功5.如果RabbitMQ接受消息报错,就会回调生产者本地接口,通知消息发送失败,要求再次发送
生产者保证消息不丢失一般采用confirm机制,异步处理,发送消息不会产生阻塞,可以直接发送下一个消息,吞吐量会比较高
每个节点都有queue的完整镜像,包含queue的全部数据所有这种集群模式叫镜像集群模式,开启镜像集群模式
1.写消息的过程中,没到RabbitMQ,网络传输的过程中消息丢失,或者消息到了RabbitMQ内部出错消息没保存下来
数据2,offset=153
queue1
快速处理消息积压
解决方案:将相关联的数据放在一个queue
4.但是过了高峰期后,下午进入低峰期仅有1万用户访问,每秒访问50次左右,对整个系统没有任何压力
6.MQ高峰时每秒会写入5000个请求,结果只有2000个请求出去,就会导致中午高峰期(1小时)有几十万甚至几百万消息积压在MQ
zk记录着当前消费者消费到offset=几的这条记录
6.D系统本地耗时500ms
0 条评论
下一页