カフカのリバランスを本当に理解していますか

導入

今日は主に Kafka のリバランスを共有します. Kafka では, リバランスは非常に重要な概念です. 多くの問題はリバランスによって引き起こされる可能性があります. リバランスはリバランスです. 名前が示すように, リバランスは再び負荷分散です. 以下 リバランスの詳細な説明与えられます。

負荷分散

バランシングについて話す前に, ロード バランシングについて話しましょう. ロード バランシングとは, リクエストを異なるオペレーティング ユニットに分散することです. 簡単に言うと, リクエストを異なるサーバーに分散して、単一のサーバーへのプレッシャーを軽減し、スループットを向上させることです. 多くの方法があります.以下は、nginx の負荷分散です. クライアントが nginx にリクエストを送信すると、nginx は特定の負荷分散アルゴリズムに従って、そのリクエストを別のサーバーに転送します.

どのマシンにリクエストを送信するかは、使用する負荷分散戦略に依存します.選択に応じて、ランダム、ポーリング、LFU、LRU など、多くの負荷分散戦略があります。

リバランス アイコン

ロード バランシングについては上記で説明しましたが、実際にはバランシングと同じです. In Kafka, how a consumer group consumers partitions under a topic and how to convert these partitions are useful. Kafka は を提供し、どのコンシューマーが必要かを調整でき分区分配器ますそれらのパーティションを消費します。

次の図に示すように、コンシューマー グループには 2 つのコンシューマーがあり、それぞれが 2 つのパーティションを消費します。

この時点でコンシューマーを追加すると再均衡、操作がトリガーされ、Kafka が再割り当てされます. 割り当て後、次のようになります. C2 は、2 つのパーティション partition-3, partition-4 の元の消費から、パーティションのみを消費するように変更します - 2、partition-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