Fork me on Gitee

kafka集群中的Controller、rebalance和HW

kafka集群中的Controller、rebalance和HW

1. Controller

集群中谁会来充当controoler?

每个broker启动时会向zk创建一个临时序号节点,获得的序号最小的那个broker将会作为集群中的controller。主要负责

  • 主副本选举
  • 管理分区状态机
  • 管理副本状态机
  • 管理多种类型监听器

2. Rebalance 机制

发生的前提是 消费组中的消费者没有指明分区来消费

触发的前提是消费组中的消费者和分区的关系发生变化的时候

  • 组成员的个数发生变化时。比如有新的consumer实例加入该消费组或离开
  • 订阅的topic个数发生变化。
  • 订阅topic的分区数发生变化。

分区分配策略:在reablance之间,分区有三种分配策略

  • range: 根据公式计算得到每个消费者消费哪几个分区
  • 轮询: 轮流消费
  • sticky: 粘性策略,如果需要rebalance,会在之前已分配的基础上进行调整,不会改变之前的分配情况。如果这个策略没有开,那么就进行全部重新分配。

3. HW和LEO

HW俗称高水位(High Watermark)的缩写,取一个partition对应的ISR中最小的LEO(log-end-offset)作为HW,Consumer最多只能消费到HW所在的位置。另外每个replica都有HW,leader和follower各自负责更新自己的HW的状态。对于Leader新写入的消息,consumer不能立即消费,leader会等待该消息被所有ISR中的replica同步后更新HW,此时消息才能被comsumer消费。这样就保证了如果Leader所在的broker失效,新的消息依然可以从新选举的leader中获取。

4. Kafka 线上问题优化

4.1 如何防止消息丢失

  • 发送方:ack是1或者-1/all, 可以防止消息丢失,如果要做到99.9999%,ack设置为all,把min.insync.replicas配置为分区备份数。
  • 消费方:把自动提交改为手动提交。

4.2 如何防止消息的重复消费

在防止消息丢失的方案中,如果生产者发送完消息后,因为网络抖动,没有收到ack,但实际上broker已经收到了。此时生产者会进行重试,于是broker就会收到多条相同的消息,而造成消费者的重复消费。

怎么解决:

  • 生产者关闭重试,会造成丢消息(不建议)
  • 消费者解决费幂等性问题

4.3 如何做到顺序消费

  • 一个Topic(主题)只创建一个partition(分区),生产者的所有数据都发到了一个partition,消费者只能有一个消费者

4.4 消息积压场景

原因消息的消费者消费速度远赶不上生产者的生产消息的速度,导致kafka中有大量的数据没有被消费。随着没有被消费的数据堆积越来越多,消费者寻址的性能会越来越差,最后导致整个kafka对外提供的服务的性能很差,从而造成其他服务也访问速度变慢,造成服务雪崩。

解决方案:

  • 在消费者中,充分使用多线程,利用机器的性能进行消费消息。
  • 创建多个消费组,多个消费者,部署到其他机器上,一起消费,从而提升消费者的消费能力。
posted @ 2021-11-17 09:19  shine-rainbow  阅读(154)  评论(0编辑  收藏  举报