三大优点:
1.架构解耦
2.流量控制
3.异步处理
缺点:
1.消息丢失
2.消息重复
3.消息乱序
4.消息堆积
kafka如何解决这些问题
1.消息丢失。
日志场景,偶尔某条消息丢失也没关系。要求消息一定不丢失,从三个方面设置:
a.生产者端,必须等消息的成功确认。kafka端有ack=all选项。
b.broker端,消息落盘再回复成功。而且replica数一定要大于1,保证每个分区有多个副本.
c.消费者端,必须要等消息处理完毕再提交。
2.消息重复
消息重复的问题是由于生产者端可能由于某种原因没有收到broker端的成功确认,然后重复发送消息导致的。
如果生产者端不要求消息不丢失,那么只发送不管发送结果,就不会产生消息重复问题。
要保证消息不丢失,broker端必定会产生消息重复问题。
要避免这个问题,只能从消费者端解决。简而言之,就是保证消费端消费的幂等性。
保证消费端的消费幂等性,有如下几个方法:
1.每个消息给一个全局id,消费端消费后将id写到redis。每次消费时需要先去redis查一遍全局消息id
2.mysql插入数据,先查一下主键。有就update。
3.数据库设置唯一键。
3.消息乱序
kafka多分区之间数据可能是不是有序的。只有单个分区内的数据可以保证唯一性。
要保证唯一数据有序,唯一的办法只能是单topic单分区。生产端发送数据的时候指定key,这样数据就会被发送到同一个分区。
消费者端分两个步骤:消费+处理。一般处理比较耗时。我们可以采用一个线程专门消费,然后对clientId进行哈希,将消息分别哈希到N个内存消息队列,每个内存消息队列再用一个线程去处理。4C32G的机器,一般可以达到1000的qps。
4.消息挤压
消息挤压的原因无非是消费能力与生产能力不匹配。
先从业务逻辑上优化,能批量执行的,则先批量执行。优化后还是没法提高,只能水平扩容。
假如没消费完,mq快爆炸了,那么可以先用一个服务将消息快速消费后存放到一个临时的mq,然后再慢慢消费。