카프카 재조정을 정말로 이해하고 있습니까?

소개하다

오늘은 주로 카프카의 리밸런싱에 대해 나누겠습니다. 카프카에서 리밸런싱은 매우 중요한 개념입니다. 리밸런싱으로 인해 많은 문제가 발생할 수 있습니다. 주어질 것이다.

로드 밸런싱

밸런싱에 대해 이야기하기 전에 로드 밸런싱에 대해 알아보겠습니다. 로드 밸런싱은 요청을 여러 운영 단위로 분산시키는 것입니다. 쉽게 말해서 여러 서버에 요청을 분산하여 단일 서버의 부담을 줄이고 처리량을 향상시키는 것입니다. 여러 가지 방법이 있습니다. 다음은 nginx의 로드 밸런싱으로 클라이언트가 nginx에 요청하면 nginx는 특정 로드 밸런싱 알고리즘에 따라 다른 서버로 요청을 전달합니다.

요청이 어떤 머신에 있어야 하는지는 우리가 사용하는 로드 밸런싱 전략에 따라 다르며, 선택에 따라 랜덤, 폴링, LFU, LRU 등과 같은 많은 로드 밸런싱 전략이 있습니다.

재조정 아이콘

로드 밸런싱은 위에서 언급했지만 실제로는 밸런싱과 동일합니다.Kafka에서는 소비자 그룹이 주제 아래 파티션을 어떻게 소비하고 이러한 파티션을 어떻게 소비하는지 고려할 가치가 있습니다.Kafka는 을 제공하며 어떤 소비자 分区分配器가 해당 파티션을 사용합니다.

아래 그림과 같이 소비자 그룹에는 두 명의 소비자가 있으며 각각 두 개의 파티션을 소비합니다.

이때 소비자를 추가하면 再均衡작업이 트리거되고 Kafka가 다시 할당합니다.할당 후 다음과 같이 보일 수 있습니다.C2는 파티션-3, 파티션-4의 원래 소비에서 파티션만 소비하도록 변경합니다. 2, 파티션-4는 c3가 소비하도록 합니다.

위에서 우리는 Kafka의 재조정이 실제로 소비자와 파티션 간의 해당 관계를 조정하는 것임을 알 수 있습니다.일반적으로 소비자와 파티션 간의 소비 관계가 가능한 한 균형을 이루어 특정 소비자가 높은 부하 , 특정 소비자의 부하가 매우 낮고 리소스를 합리적으로 사용할 수 없습니다.

리밸런싱 조건

再均衡产生的条件就是有消费者加入或者退出,加入和退出的方式有很多,有一些是主动因素,有一些是被动因素,比如我们主动增加一个消费者,这时候就会发生再均衡,我们停掉一个消费者,那么这时候也发生再均衡,还有当消费者和 broker 之间由于长时间没有心跳,那么消费者就被提出,这时候也会发生再均衡,某个主题下的分区数量发生变化,也会发生再均衡,还有其他的一些因素,就不展开了,不过我们应该尽量避免再均衡

再均衡期间消费者是读取不了任何消息,因为这段时间会对分区进行重新分配,所以 之前消费者与分区之间的对应关系已经不存在,需要进行重新分配,所以会出现短暂不可用现象。

主动因素导致消费者的加入和离开是无法避免的,当数据量比较大时,可能需要增加消费者来分担压力,提高吞吐量,所以这时候就需要人为去添加消费者了,这时候发生再均衡是可预见的,但是被动导致再均衡就不可预见了,下面我们从一些参数和原理来说明一下,尽量避免再均衡。

相关参数

在 kafka 中,分区的分配和分区分配器PartitionAssignor有关,在底层实现中,是通过协调器Coordinator来协调消费者和分区的,分为消费者端的消费者协调器ConsumerCoordinator和 Broker 端的组协调器GroupCoordinator

Broker 端参数

  • group.max.session.timeout.ms:消费者会话的最大超时时间。如果消费者在这个时间内没有发送心跳 GroupCoordinator,那么它会被认为已经失效,会被踢出消费组。

  • group.min.session.timeout.ms:消费者会话的最小超时时间。如果消费者在这个时间内没有发送心跳 GroupCoordinator,那么它会被认为已经失效,会被踢出消费组。

  • group.initial.rebalance.delay.ms:消费者组启动时,等待多长时间再进行 rebalance。这个参数可以让消费者有时间加入消费者组。

consumer 端参数

  • session.timeout.ms:消费者会话的超时时间。如果一个消费者在这个时间内没有发送心跳到组协调器 GroupCoordinator,那么被认为它已经失效了,就会将其踢出消费者组。如果这个值设置过小,那么就会比较消耗资源,但是能够快速的发现 ConsumerCoordinator 是否还“存活”,然后进行 rebalance,如果设置过大,那么就会导致长时间没有收到心跳,可能 ConsumerCoordinator 已经“挂了”一段时间,没有及时进行 rebalance。

  • heartbeat.interval.ms:消费者发送心跳的时间间隔。心跳是消费者与 GroupCoordinator 之间维持会话的机制,如果一个消费者在这个时间间隔内没有发送心跳,那么 GroupCoordinator 认为它已经失效,然后将其踢出,如果这个值设置过大,那么一个消费者失效时,可能需要等待很长时间才能触发 rebalance,如果过小那么就会比较消耗资源。

  • max.poll.interval.ms:消费者处理消息的最大时间间隔。如果消费者在这个时间内没有消费完消息导致不能 poll 消息,那么它将被认为已经失效,将被踢出消费者组,这个值默认为 5 分钟。

heartbeat.interval.ms 的值一定要比 session.timeout.ms 小,官网建议是 1/3,比如 heartbeat.interval.ms 为 5s,那么 session.timeout.ms 为 15s,这样的话在这个时间会话内能收到三次心跳,不过这两个的值也要在 Broker 端 group.max.session.timeout.ms(5min)和 group.min.session.timeout.ms(6s)的区间之间。

分配器

消费者和分区之间进行分配是由分配器来完成的,当消费者加入和离开时触发 reabalance,然后会使用分配器从新对分区和消费者进行分配,kafka 有一个分配器接口ConsumerPartitionAssignor,它的下面有一个抽象类AbstractPartitionAssignor,如果我们需要自定义分配器,那么集成抽象类AbstractPartitionAssignor即可,kafka 默认提供了好几种分配器,如 RoundRobinAssignor,RangeAssignor,StickyAssignor,CooperativeStickyAssignor,kafka 默认使用 RangeAssignor。

如下,我创建了一个名称为 musk 的主题,分区数为 4,然后创建一个消费者,那么这时因为只有一个消费者,所以四个分区都划给了它。

此时我又加入一个消费者,因为加入消费者后会触发 rebalance,所以这时候就会对分区重新进行分配,分配后如下,每个消费者划分了两个分区。

对于分配器,kafka 自带的已经能够满足我们大多时候的需求,因为我们在使用多个消费者的时候,其实就是为了让分区被均分给消费组内的消费者,以达到压力的分担。

总结

从上面我们对 rebalance 进行一些介绍,对 rebalance 产生的原因进行说明,对消费者协调器和组协调器进行了解,对一些参数进行详解,还有通过测试 rebalance 来更加直观说明 rebalance,rebalance 的触发有很多方式,不过我们应该尽量去避免它的发生,对于分区的修改,应该尽量在一开始规划好,不要后续去修改分区,对于其他引起 rebalance 的因素,也应该将其概率降到最低。

今天的分享就到这里,感谢你的观看,我们下期见,如果文中有说得不合理或者不正确的地方,希望你能进行指点

추천

출처juejin.im/post/7215478156949487672