Kafka高级篇
Kafka集群中的Controller、Rebalance、HW
Controller
集群中谁来当Controller?Broker在启动时,会向ZK特定节点下注册临时序号节点,获得最小序号的Broker充当Controller的角色。
Controller主要负责下面几件事:
- 当某个分区的Leader挂掉,Controller负责从ISR集合中选择出一个新的Leader。
- 当集群中Broker新增或减少,Controller会将信息同步给其他Broker。
- 当集群中的分区新增或减少,Controller会将信息同步给其他Broker。
Rebalance机制
前提:消费者没有指定Topic分区。
触发条件:当消费组中的消费者和分区的关系发生变化时触发
Rebalance机制会改变消费者消费哪个分区。
在触发Rebalance机制前,消费者消费哪个分区有三种策略:
range
:通过公式计算消费者消费哪个分区,0号消费者消费第0-i分区,1号消费i+1-n分区。大体上是平均的。轮询
:轮着来,类似约瑟夫环。sticky
:在触发了Rebalance之后,在原有消费分区的基础上进行调整。
HW和LEO
HW全称是High Water,LEO的全称是Log end offset。
HW记录的也是一个偏移量,不过该偏移量具有特殊的含义,它表示当前分区的消费者可以消费的最大偏移量。它的值的变化是分区副本决定的,如果所有的ISR副本都同步完成了下一条记录,则HW的值才会后移。通常HW的值等于所有ISR中最小的LEO值。
LEO表示副本收到的最后一条记录的偏移量。本质也是一个偏移量。HW可达到的最大值为LEO。
也就是说,并不是Leader收到消息后立马就可以发给消费者去消费,而是有个HW限制,得等到所有ISR副本都同步完成后,HW后移之后,消费者才可以拉取新消息。这样保证了如果Leader挂掉后,仍然可以从新Leader中消费该消息。
Kafka线上问题优化
如何防止消息丢失?
生产者: 设置同步发送,并且设置ack=1或all,同时设置min.insync.replices
>=2
消费者:设置手动确认
如何防止消费重复消费?
消息被重复接收,问题有很多种,可能是网络波动、生产者重试机制引起等。如果关闭掉生产者的重试机制可能会导致消息丢失问题,反而得不偿失。因此我们可以在消费端来解决这个问题。
对于幂等性的业务,重复消费不会出问题,但对于非幂等性的业务就需要进行额外处理。
一般常用的手段有:
- 分布式锁,可以通过Redission或者ZK来实现。一般在处理期间加锁,并进行一些判断,检查是否是首次消费,处理后解锁。
如何保证消息被顺序消费?
Kafka不保证消息全局的顺序性,但是可以保证消息的分区顺序性,只要消费者将消息发送到同一个分区中,消息会被顺序消费。
如何解决消息积压问题?
生产者生产速度过快或者消费者消费速度过慢,也即消费者和生产者的速度不对等会造成消息积压问题,可以综合下面的方式来解决该问题。
- 优化消费者配置,比如拉取batch大小、拉取间隔配置。
- 增加消费者,增加消费者可以提高消息的消费速度。
- 提高消费者的处理能力,如使用多线程、异步处理等方式。
- 增加Topic分区,增加分区后,可以提高消费者的并行处理能力,从而加快消息的消费速度。
- 限流,在生产端设置限流策略,比如设置生产者的发送速率、设置批量发送大小等。