作为消息中间件,削峰
topic 消息的分类
partition 分区
offset 分区里的位置,从0开始。
副本 leader,follower
生产者产生消息后,发送到broker,不同的消息存放的不同的topic里面,同一topic下面会有好几个分区,在同一分区内的消息是有序的,用offset记录当前分区消费的位置。不同分区内的消息是无序的。消息会写到leader里面,再把数据同步到follower里面。同一个topic的partition可以在不同的broker里面。一个分区只能被一个消费者消费。可以将消费者分组,同一个消费者组里的消费模式是队列模式,A消费了,B就不会消费。不同消费者组的消费者消费模式为发布订阅模式,每一个消费者组都可以订阅到消息,有消息来就分发给不同的消费者组。
本质原因是生产者生产速度过快,消费者速度过慢。
解决办法是:
如果说是生产者生产数据过快,可以隔一段时间发送一批数据到broker,调整该时间。在消费者端则有可能是消息处理速度慢,慢的原因则可能是业务处理慢,尽量减少业务逻辑的处理,只存表,另起一个线程去做复杂业务的处理。也可能是表被上了行锁,表锁等,检查业务SQL对表的更新,插入等语句是否有造成大量的锁竞争。
成因1:broker 或 consumer宕机了,没有及时将offset提交到broker,导致消息重复下发。
解决方案:1.保存库表的时候设置主键,重复数据数据库拒绝录入。2.使用Redis中间件,将消费过的数据存入Redis,每次判断是否有消费过。
成因2:reblance的问题。如果consumer端在默认的5分钟内没有处理完这一批消息,就会触发kafka的reblance机制,导致提交offset失败。在reblance后,consumer会自动从没有提交之前的位置进行消费。
解决方案:设置每次拉取下来的数据量少一点。调整消费端处理的超时时间。提高消费端的处理能力。
成因1:消息丢失有producer发送失败。producer发送消息是异步发送的
解决方法:1.该成同步发送,实时知道发送消息的结果。2.添加异步发送回调函数监听消息发送的结果,对发送失败的做重试。3.producer自动重试参数retries.
成因2:broker leader节点宕机或者网络超时时,数据未及时同步到follower节点,或者producer仍旧在往老的master里面写数据。导致从follower节点选举产生的leader节点中不包含该数据,旧leader节点恢复通信后,发生脑裂现象,由于新的leader的epoch ID更大,会使用新的leader作为leader,旧leader会降级未follwer,旧的leader数据会被新的leader数据覆盖,导致数据丢失。
解决方法:在producer发送时设置一个参数acks=1(只需要一个副本确认了就给producer发送成功确认).acks=0(不需要等待副本确认就可以给producer发送成功)acks=-1(需要所有的副本确认才能给producer发送成功)
成因3:consumer消费失败。如数据库问题存储失败,业务处理异常等。
成因:一个topic下面有好几个分区,每个分区的数据都是有序的,但跨分区则是无序的。
解决方法:
1.自定义消息落到分区的路由算法。消息落到分区是根据消息的key进行取模,落到不同的分区里面,按照先后顺序进行存储。按照这个特性,自定义一个路由算法,把指定的key都发送到一个分区里面,然后指定某个消费者专门去消费某个分区的数据。
2.有些consumer的设计会采用异步线程的方式来处理数据,这样也可能会出现一个数据的无序性消费。可以先把数据保存到阻塞队列里面,再用异步线程来消费阻塞队列里面的数据。
造成问题:kafka在进行reblance时,会阻塞读写。
成因:
group里增加了consumer数量
consumer消费超时
topic内增加了partition数量
group增加了topic数量
可以理解为把未消费的消息重新分配到其它分区上面,可以被其它消费者给消费