消息队列
为什么用?
解耦,削峰,异步
基本模型
生产者 -> MQ -> 消费者
Kafka 十万级/s 适用于大数据领域实时计算,日志采集,
ActiveMQ 万/s , RabbitMQ 万/s , RocketMQ 十万/s
造成问题及解决
1.系统可用性降低 (MQ发生故障,全崩了)
2.MQ重复发送消息 重复消费问题 MQ丢消息问题 MQ发送消息顺序错乱
3.不一致性,MQ给客户端显示执行成功,结果在服务器一端执行失败了,导致不一致
MQ高可用问题:
RabbitMQ 普通集群模式,一个机器,多个节点 消费者随机找到一个MQ节点消费,该进程会去找其他MQ节点的数据同步过来,返还给消费者。 集群内部存在大量数据传输。一旦其中一个节点挂了,数据就没了。
RabbitMQ 镜像集群模式,每个节点的数据都会同步到其他全部节点,保证了每个节点都有全部数据,数据量过大同步困难
Kafka高可用框架:
同一数据存在不同机器上,每一份数据leader 都同步副本数据在一台机器上作为follower作为备份
消息重复消费问题:
Kafka重复消费问题:生产者生产的数据进入到kafka后都会为每一条数据标识一个offset值,消费者消费到该数据后,把offset值提交给zookeeper用来记录offset,再传回kafka证明消息已经消费完毕。
如果消费者消费完准备提交offset,还未提交就挂了,重启后不再提交到zookeeper,导致kafka以为该消息还没消费,继续发送给消费者导致重复消费。
解决办法:消费者程序做幂等性来保证
消息丢失问题:
Kafka
1.消费者到broker: 消费者把消息发送到broker主节点,并且同步到从节点后返回ack,消费者做try catch处理是否重复发送
2.broker到消费者: 关闭kafka自动提交offset,改成手动提交offset,在代码中消费到数据并完完全全彻底处理完数据后才提交offset
配置kafka四个参数
参数1:topic的relacation必须大于1(必须有多个follower)
参数2:min_insync.replicas必须大于1(必须至少有一个follower与自己保持联系)
参数3:asKs=all 要求必须生产者的数据发送到leader,并且同步到全部follower才算一次发送成功
参数4:retries=max 如果未同步到全部follower一直重试
消费大量积压问题
原因:一般是消费者挂掉导致大量消息积压在MQ
解决:临时创建一个topic,多开几倍的partition。原来的消费者更改逻辑 消费到的数据发到新topic上,多开几个消费者同时消费新的topic。
消费顺序出错问题
原因;把应该保证顺序的多条消息分散发给多个消费者,再从多个消费者整合到一起导致消息顺序错乱。
解决:把需要保证顺序的多条消息写入同一个消费者。
Kafka中写入到一个partition中的数据一定是有顺序的。
Kafka为啥这么快,性能这么高?
1.顺序写入
每个partation只能append追加,顺序IO写到磁盘而不是随机IO,避免了寻址时间
2.sendfile零拷贝读取
利用DMA技术从磁盘拷贝到内核缓冲区,内核缓冲区通过管道连接socket缓冲区,socket缓冲区拷贝到网卡上
消息队列推拉模式