Kafka高级篇

28

Kafka集群中的Controller、Rebalance、HW

Controller

集群中谁来当Controller?Broker在启动时,会向ZK特定节点下注册临时序号节点,获得最小序号的Broker充当Controller的角色。

Controller主要负责下面几件事:

  • 当某个分区的Leader挂掉,Controller负责从ISR集合中选择出一个新的Leader。
  • 当集群中Broker新增或减少,Controller会将信息同步给其他Broker。
  • 当集群中的分区新增或减少,Controller会将信息同步给其他Broker。

Rebalance机制

前提:消费者没有指定Topic分区。
触发条件:当消费组中的消费者和分区的关系发生变化时触发
Rebalance机制会改变消费者消费哪个分区。
在触发Rebalance机制前,消费者消费哪个分区有三种策略:

  1. range:通过公式计算消费者消费哪个分区,0号消费者消费第0-i分区,1号消费i+1-n分区。大体上是平均的。
  2. 轮询:轮着来,类似约瑟夫环。
  3. 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不保证消息全局的顺序性,但是可以保证消息的分区顺序性,只要消费者将消息发送到同一个分区中,消息会被顺序消费。

如何解决消息积压问题?

生产者生产速度过快或者消费者消费速度过慢,也即消费者和生产者的速度不对等会造成消息积压问题,可以综合下面的方式来解决该问题。

  1. 优化消费者配置,比如拉取batch大小、拉取间隔配置。
  2. 增加消费者,增加消费者可以提高消息的消费速度。
  3. 提高消费者的处理能力,如使用多线程、异步处理等方式。
  4. 增加Topic分区,增加分区后,可以提高消费者的并行处理能力,从而加快消息的消费速度。
  5. 限流,在生产端设置限流策略,比如设置生产者的发送速率、设置批量发送大小等。