MQ常问的问题-rabbitMQ和kafka

MQ的优点:

解耦:如果不用mq,系统之间各种调用,很复杂,需要依赖被调用方的jar包,需要考虑新假如接口,系统宕机,调用超时等情况,但是使用mq之后,调用方不用再假如代码,而且只需要将消息发送到mq中,其他的不用关心。

异步:要延时场景。就是一个系统如果同步调用,会耗时很长,但是是如果改成异步的,比如说a系统可以发送3个消息到对应的3个队列中,那么这三个队列相当于是并行进行。

削峰:高峰期请求量太大,直接打到系统,可能会造成下游的被调用方或者是数据库直接死掉,那么就需要把请都放到mq中,然后又下游服务或者是数据库每秒最大处理速度进行处理。而积压下来的消息再高分期过了之后再慢慢的消化掉。

 

MQ的缺点:

加入mq的复杂性增加了,可用性差了。其实我们在写程序的时候,应该遵循一个标准,在合理的设计的时候,尽量不引入第三方框架,因为引入之后,系统的复杂性在原来的基础上是增加的,所以,需要保证mq的高可用,消息的不丢失,不重复,顺序性等等问题。

一致性问题。系统a用mq调用其他的系统bcd,但是如果bcd其中有一个系统出问题,那么就会导致后台执行失败,但可能返回给客户的是正确的。

 

mq的高可用:

rabbitmq有俩种高可用模式,一种是普通的模式,比如说3太机器,我们创建的queue会随机在一台机器上存在,在这台机器上会保存queue的元数据和消息数据。但是其他俩台机器只会保存他的元素据,当有请求发送到其他俩太机器的时候,机器会从存在消息数据的机器上获取数据,并且返回,那么这里其实存在问题,数据传输占用的网络带宽,实例机器挂掉,导致集群不能使用,和磁盘空间满了的情况。

rabbitmq另一种模式叫做镜像模式,还是3台机器,但是每一台 机器中都保存者完整数据的镜像,每次访问任意一台机器,就可以,省区了网络开销。但他的集群模型任然不是分布式的,因为如果磁盘满了的话,是没法做出有效解决的。 镜像模式模式的设置在rabbitmq的管理界面中设置,就是设置队列同步数据的机器台数策略,是全部同步。

kafka的分布式高可用:

 

kafka的消息类型可以用topic的分类,比如说订单的消息作为一个topic,并且为这个topic分配了3个broker,每一个broker就是一个kafka的实例,每台broker上作为一个topic的partition,叫做partition的副本,并且为了保证高可用,给每个partition副本设置一个replica的副本,主副本和raplica的消息是一执的,可以说主的副本的relica组成了领导者和追随者的结构,这里无论是消息的写入和消费者的消费都是从主partition完成的,raplica只是作为他的一个消息备份。当一个主partition挂掉之后,kafka会从其他的replica中选举出副本。

而一条消息从生产者生产出来,只能进入一个topic的一个partion中,且他在partition中的顺序永offset来标识。

 

mq中存在重复数据(或者保证消息消费的幂等性):

kafka中,每一条消息的在partition中中都有唯一的offset的,消费者消费也是按照offset的顺序进行消费的,且消费者每次在消费了一批消息的时候,会将offset序号返回给zk,kafka从zk中就可以知道消费者消费到哪里了,但是这里有一个问题,就是假如消费者在消费了几条消息后,没来的急将offset回传给zk,那么下次重启之后,就会造成kafka重复的将消息发送给消费者,早着消息重复。所以,要保证幂等性。总体思路就是,每次将消息存储到一个都可以访问到的公共区域,然后每条消息进来之后都会询问在公共区域是否存在同样的消息,如果存在,说明这条消息重复了,那么就不能消费;基于此,我们可以将消息存储到map中,redis中,或者数据库中,利用唯一键来标识。

 

消息丢失:

rabbitmq中,导致消息丢失的地方总共有三处,第一处是生产者发送给rabbimq过程中丢失;第二处是rabbitmq在服务器中丢失;第三种是rabbitmq发送给消费者造成数据丢失;

第一处丢失,俩种对策,第一种,按照rabbitmq的事务来处理,发送消息之前开启事务,同步等待消息反馈,如果报错,执行rollback,并且再次发送消息;第二种,将channel设置成为confirm模式,如果消息发送成功,会异步回调ack方法,如果失败会回调nack方法;

第二处丢失,是需要将消息在服务器做持久化。第一种是需要将queue设置为持久化(drable为true),那么rabbitmq会将队列的元素据做持久化,然后需要将deliveryMode设置为2,rabbitmq会将消息数据持久化到磁盘空间,保证服务器宕机之后重启,会重新加载磁盘的数据。

第三处丢失,其实只有一种可能,就是把消费者反馈rabbitmq的机制设置为autoACK了。原因就是rabbitmq将消息发送到消费者,消费者自动返回给rabbitmq消费成功,但是在消费者处理消息过程中宕机了,那么就会造成数据丢失,所以,其实就需要将autoACK关闭,然后再消息消费完成后,执行手动ack;

kafka中:同样有三处,原理是一样的额,第三处,如果kafka的消费者消息丢失了,那么其实也需要将自动反馈zk的机制关闭,然后设置为手动关闭。

第二处,kafka服务器会丢失。原因可能即使消息发送到了patition,但是没有同步到replica的时候,partition挂掉了,造成数据丢失。对于此,kafka中需要设置4个参数,topic的replicatioin.factor至少为大于1,保证副本数; 设置min.insync.replicas大于1,保证至少有一个raplica和partitioin保持数据同步; 再producer端设置acks=all,标识所有的副本同时数据成功之后,生产者才认为是消息发送成功; 再producer设置retries设置为一个很大的值,保证给如果同步不成功,生产者会重复发送很多次的消息,保证重试次数。

 

消息的顺序性:

rabbitmq保证需要有序处理的处理进入到容易个消费者中即可;

 

mq延迟过期怎么解决,消费队列满了,或者队列中有几百万的消息:

消息有积压了,怎么办? 简单俩说,就是加机器加速消费,等消费队额差不多了,把机器撤了;这几个机器的增加,不仅仅是需要增加mq服务器,也需要增加消费者;第一将原来的消费者修改一下,把消息重发到一个新建的临时mq中,然后增加消费者对这个新建的mq的消息进行消费,等到消息积压下去之后,再把新增的机器撤走,把代码该回去;

但是假如设置了过期时间?这个一般不推荐设置,但是如果出现了,那么丢失的数据,就只能再线下将数据找出来,然后重新发送到mq中进行消费。

 

kafka基础知识:

topic: 主题;可以根据业务划分,每个业务分为一个主题。

实例时Broker:

高可用Replication:

副本Replica:Leader Replica: Follower Replica:代替master-slave;

 

生产者想领导副本写,消费者从领导者副本读;追随者副本不提供服务,只是追随领导者副本,完整内容复制;

分区Partitioning: 一个topic可以分为多个分区,分区从0开始;每个分区是有序的消息日志;生产者的消息只能被发到一个分区中。每个分区可以有若干个副本,其中一个是领导者副本,剩下的都是追随者副本;消息在每一个分区的位置叫做位移(有的地方叫做便宜量)offset,也是从0开始;

 

kafka分层:

第一层主题层;每个主题层可以有m个分区,每个分区有n个副本;

第二层是分区层;每个分区n个副本;这些副本中只能有一个是领导者副本,其他都是追随者副本;

第三层是消息层;在副本中,每个消息又对应该的位移。

客户端只能和分区中的领导者副本做交互;

 

kafka的持久化:

kafka的持久化利用日志来实现,且只提供追加写的方式(append-only),可减少io操作;

 

kafka磁盘大小选择:

每条消息预估大小;

每天新增消息预估数量;

数据留存时间;

备份份数;

消息大小 * 预估条数 - 》 换算成Gb * 1.1 * 备份份数 * 预留时间 * 0.75

 

消息缩影数等等 占 所需 大小的 10%;

消息压缩率是 0.75;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值