kafka线上问题及优化

1、消息丢失情况

生产者:
设置acks=0,表示生产者不需要等待broker确认收到消息,就可以继续发送下一条消息,性能最高,但容易丢失消息。对数据丢失不敏感的场景可以考虑试用,例如报表等。
设置acks=1,表示只需要broker的leader确认收到消息,不需要所有的follower就可以继续发送下一条消息。这种情况下,如果follower还没有备份好数据,leader又恰好挂掉的时候,会丢失数据。
设置acks=-1或者all,表示leader需要等待所有的副本(min.insync.replicas配置的备份个数)全部备份完成之后才会返回,这种情况,只要有一个节点存活就不会丢失数据。但是如果min.insync.replicas配置的是1那就和acks设置为1的场景一样。
消费者:
如果消费这边配置的是自动提交,万一消费到数据还没处理完,就自动提交offset了,但是此时你consumer直接宕机了,未处理完的数据丢失了,下次也消费不到了。可以手动提交offset(一般会使用先异步提交再同步提交兜底)。

2、消息重复消费

问题原因:
生产者:发送消息如果配置了重试机制,如果出现网络抖动导致发送超时,实际broker可能已经收到消息,但是生产者认为失败了,又重新发送了一条。
消费者:如果消费者配置了自动提交,拉取了一批数据并处理之后,还没来得及提交,服务挂了,下次重启又重新拉取同一批数据重复处理
解决方案:
生产者:
为了实现发送消息的幂等,kafka引入了Producer ID(即PID)和Sequence Number。PID即生产者的id,每个新的生产者在被初始化的时候产生。Sequence Number:对于每个PID发送的每条消息的《topic,partition》都对应一个从0开始递增的序列号。在Broker端保存了这个序列号,对于接受到的消息如果缓存的序列号不小于该条消息中的序列号那么这条消息将会被丢弃。这样只可以保证同一个生产者对于同一个topic下的同一个分区发送的消息是不会重复的。
消费者:
将offset存在redis等第三方缓存组件中。

3、消息乱序

在正常场景下kafka只能保证一个topic下的同一个分区消息有序,当生产者出现消息发送失败重试时,同一个分区下的消息也无法有序。
解决方案:
1、如果某一类消息需要做顺序消息,那么在发送消息时,指定分区,消费者端,在接收到有顺序的几条消息之后,将其放入队列中,开启一个线程,从队列中一条条处理消息。
2、可以通过将topic的partition数量设置为1,将consumer group中的consumer instance数量也设置为1,但是这样会影响性能。

4、消息积压

1、线上消息数量突然激增,消费者来不及处理,导致broker积压大量消息
解决方案:这种场景可以紧急修改消费者代码,让其收到的消息分发到其他topic,这个topic设置很多分区,再启动对应数量的消费者去消费这些分区的数据。
2、代码有bug导致消费者消费一直不成功,也可能导致消息大量积压
**解决方案:**当消息消费不成功的时候,可以新增一个topic专门用来处理这种消费不成功的消息,作用类似与死信队列,先将积压的消息处理掉,在慢慢分析死信队列中消息消费不成功的原因。

5、延时队列

kafka并没有实现延时队列,但可以通过设置指定名称的Topic,再通过定时器轮询的方式实现
实现方案:先把需要做延时发送的消息发送到指定的队列中,例如topic_1s,topic_5s,topic_10s,topic_30s…,然后通过定时器进行轮询消费,查看消息是否到了指定时间,如果到了那就把消息发送到对应的业务topic中,
6、消息回溯
用consumer的offsetsForTimes、seek等方法指定从某个offset偏移的消息开始消费

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值