redis、kafka、RabbitMQ、RocketMQ 消息中间键
1、redis、kafka 消息中间键的作用、优点
解藕、异步、削峰
2、缺点
系统可用性降低。解决方案,try catch 捕捉异常,数据库操作,进行兜底。搭建集群。
提高复杂度。例如:消息重复;消息丢失(主要集中在RabbitMQ);消息顺序(多线程抢资源。如何解决?kafka/RocketMQ:单个消费、一个主题下。)
一致性问题。A和B系统写成功了,C系统没有成功。分布式事务,RocketMQ 提供了。其他的用seta。redis Lua脚本来做原子性。
3、比对一下,常用的 MQ!!!RabbitMQ、Kafka、RocketMQ
性能角度(单台):Rabbit 1.2W、Kafka 100w、Rocket 10W
集群拓展支持:Rabbit 集群很弱(确保高可用 不能拓展性能)、Kafka 和 Rocket 天生分布式 动态支持拓展
功能:Rabbitmq 比较丰富(死信消息、延迟消息) 、Kafka 比较弱,RocketMQ 比较丰富(死信、延迟、消息回溯、消息的过滤)
Rabbitmq 基于主从模式做集群,RocketMQ、Kafka基于分布式做集群
4、为啥性能这么高?
6、消息丢失场景,如何解决?
在生产的时候丢失、消费的时候丢失、宕机的时候没有主从拷贝丢失
怎么丢失的?
生产者:网络异常波动未能生产成功;远程服务宕机未能接收成功(一句话概括:没生产成功;生产成功了,服务端没接收到。)
broker:数据没有持久化,宕机,重启数据丢失;未能及时同步消息
消费者:网络异常波动,未能从服务端拉取成功消息;消费者宕机,消费者未能正常消费
生产的时候丢失:事务回滚机制,确保提交成功。但是是同步阻塞,效率性能低。RabbitMQ 的异步confirm机制,如果RabbitMQ接受到这个消息,写入磁盘,给生产者返回ack。
宕机的时候,RabbitMQ数据丢失:开启数据持久化。Kafka topic保证至少2个副本;每个领导者leader 必须有一个跟随者follower跟自己保持联系;消息写入所有副本。
消费者数据丢失:RabbitMQ关闭自动ack,手动进行ack。Kafka 关闭自动offset,手动提交offset。
7、kafka 架构
可以设置多个topic,每个topic 下可以有多个分区, 每个分区是一个有序队列,数据进到队列,会分配一个有序的 offset。一台kafka服务就是一个broker,一个broker 可以容纳多个topic,
broker 接收到生产者的发送消息,并向生产者发送确认消息,消费者消费成功后,给broker发送确认消息,broker更新偏移量,以便下次从正确的位置进行消费。
ZooKeeper 协调kafka 组件之间的协作,例如主从晋升。后来引入Controller,承担ZooKeeper的部分功能,简化Kafka 集群的部署和管理。
8、kafka的工作流程
9、RabbitMQ 的设计架构
生产者生产消息,建立长链接,链接到broker 服务,交换机将消息发送给队列,消费者拉取数据进行消费,消费成功后将数据删除。
10、RabbitMQ 解决消息丢失的机制
生产者:comfirm消息确认机制。生产者生产消息后,exchange 将消息放入绑定的queue,返回ack给生产者。只要这个环节没有完成,就返回nack。
RabbitMQ:数据持久化,存储到磁盘。如果有需要就开启数据持久化,应用场景不在意消息丢失,可以关闭,因为开启会影响性能。
消费者:ACK机制。消费者成功消费,发送ack给RabbitMQ,RabbitMQ 将消费的消息进行删除,如果消费者消费成功了但是因为异常没有成功通知Rabbit,会出现重复消费,此时要把成功消费和通知删除放在同一事务中。
11、RabbitMQ 怎么确保消息不被重复消费
生产者:接口幂等性
消费者:消费完成没来得及发送ack给RabbitMQ
RabbitMQ:接收到ack,还没来的及删除,挂掉
解决方案
数据库唯一约束。对于RabbitMQ,到达数据库层面才能被限制住,性能效率低。
乐观锁,版本号。对于RabbitMQ,队列中有相同版本号的有很多,只能成功消费一次,剩下的无法被消费。
redis 的setnx + 过期时间
12、Rabbit 如何解决消息堆积
出现的原因
生产的速度远大于消费的速度;消费者出现异常或者业务复杂,导致消费时间过长;队列容量太小。
解决
控制生产与消费的速度;负载均衡,提高消费能力;优化消费者代码;控制消费者一次性取的数据;将无法处理的消息放在死信队列,防止阻塞;大消息分割片段处理
13、redis 的过期策略、内存淘汰机制
有定期过期、惰性过期。定期过期,每隔一段时间,清理过期的数据。惰性过期,只有访问的时候才判断是否过期,不访问即使过期也不删除。
如果定期和惰性过期,都没有删除过期的数据,大量数据堆积,导致内存溢出。
内存淘汰机制,内存不足时,主动删除一些数据,释放空间。
淘汰机制的策略:选不常使用的;选快要过期的;从过期数据中,随机删除
14、什么是redis 的哨兵机制
搭建了redis的主从集群,master 挂了,需要从slever 中选一个当master。redis 哨兵的作用 就是自动恢复主从故障。
原理是,心跳机制,检测集群ping ,是否挂了
15、redis 的数据持久化方案
RDB(redis data base)内存快照,全量备份。性能高,但是宕机,会丢失最近一次修改的的数据。触发方式:手动触发、自动触发。手动触发save, 阻塞redis进程,直到持久化数据完成;bgsave 主进程创建子进程,由子进程完成数据数据持久化,阻塞时间短。自动触发,shutdown 命令将redis 服务关闭,会触发自动备份。
redis默认开启的是RDB持久化
AOF(append only file)增量日志。存的是命令,数据更加完整可靠,缺点文件大,redis重启,数据恢复慢。
混合持久化:RDB+AOF
16、rabbitMQ 交换机的类型:定向、广播、话题(类似于定向,区别可以支持通配符)
17、rabbitMQ中,如何保证生产者的可靠性
生产者重连
由于网络波动,与MQ没有一次性连接成功,配置重试机制。
生产者确认
生产者将消息投递到交换机,交换机没有成功路由到队列,会返回错误信息,然后返回ack。这种情况一般是交换机与队列没有绑定正确。
生产者将消息投递到交换机,交换机成功路由到队列,给生产者发送ack
生产者将消息投递到交换机,交换机成功路由到队列,如果设置数据持久化,就持久化完成后,给生产者发送ack
18、rabbitMQ中,如何保证MQ的可靠性
MQ 宕机,内存中的消息会丢失;MQ内存空间有限,当消费者消费过慢,导致消息积压,引发MQ阻塞。
数据持久化:配置消息持久化、交换机持久化、队列持久化
什么是pageout?MQ消息过多达到内存阈值,会转移到磁盘进行保存。大量的 Pageout 操作会使系统花费更多时间在数据的内存与磁盘交换上,从而降低了消息的处理速度和吞吐量,由于 Pageout 导致系统性能下降,生产者需要更长时间才能得到消息发送成功的确认响应,消费者也会延迟。没有配置持久化,大部分数据会存在内存,达到阈值,会将数据转移到磁盘,会出现pageout;
配置了数据持久化,数据一开始在磁盘与内存的数量差不多,然后逐渐内存变少,磁盘增多,减少pageout 的发生。
方法二:惰性队列
3.6版本引入惰性队列。大部分直接写入磁盘,在页面上的表现是,直接写到paged out,不卡的原因做了磁盘IO优化。
19、rabbitMQ中,如何保证消费者的可靠性
消费者确认机制。消费者消费成功,给rabbitMQ发消息,rabbitMQ进行删除,消费失败,发送失败消息,rabbitMQ会再次发送消息。
消费者失败处理。消费失败,rabbitMQ会重新发送,会陷入循环,配置重试机制,重试后还是失败要么重新入列、要么删除、要么放入新的队列,交由人工处理。
业务幂等性。加消息唯一ID,将消费成功的ID存入数据库,再次消费时,查看该消费是否在数据库,如果在则为重复消费。
21、延迟消息的实现
死信交换机。绑定一个正常交换机,不绑定消费,设置时间,达到一定时间没人消费,进入死信交换机,给死信交换机绑定消费者。实现延迟消费。
延迟消息插件。是对交换机做的改造,消息投递给交换机,交换机设置时间,时间到了,再将消息投递给队列。适合时间短的延迟场景,不适合并发+延迟长的场景,cpu占用高。
取消超时订单
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!