美文网首页
【kafka】kafka 扩分区方式的不用,导致分区分布不一样

【kafka】kafka 扩分区方式的不用,导致分区分布不一样

作者: Bogon | 来源:发表于2024-08-22 11:50 被阅读0次

    在使用kafka时,创建topic,对某个topic进行扩分区的操作,想必大家肯定都使用过。尤其是集群进行扩容时,对流量较大的topic进行扩分区操作。一般而言,期望的效果是:新扩的分区分布到新的broker节点上,这样才能达到均衡流量分摊broker压力。

    然而,我们在实际使用过程中发现,在一种场景下,原生的代码逻辑中,对topic分区进行扩容后,新增的分区并没有分配到新的节点上,即新增的分区和老的分区仍旧位于扩容前的broker节点上,导致这个节点压力反而变大,引发生产者发送超时等问题。

    在具有3个broker的集群环境中,分别通过自带脚本(kafka-topics.sh)和adminClient的接口创建一个分区数为2、副本因子为1的topic,然后再扩容到3分区,此后查看topic分区的分布情况。

    通过接口操作的情况如下所示:


    image.png

    通过脚本操作的情况如下所示:

    $  kafka-topics.sh  --zookeeper  127.0.0.1:2181  --topic  test  --alter  --partitions  16
    
    Image_20240823112859.png

    从图中可以直观的看到通过接口创建的topic,在扩容分区后,新增的2号分区的leader与老的1号分区的leader位于同一个broker节点上,而不是像脚本操作的一样,3个分区的leader分别位于3个broker节点上。

    两种操作方式的区别

    由于扩分区的操作都是一样的,那为什么不同的创建的方式,在进行扩容后就有了不同的结果呢?我们还是先来看下两种创建topic方式的逻辑。

    对于通过脚本创建topic的处理逻辑为:

    • 通过zk客户端获取当前集群的所有broker

    • 根据topic创建的参数,进行topic分区副本的分配

    • 通过zk客户端,将topic分区副本信息写入zookeeper

    kafka broker的controller监听zk并感知其变化,然后根据分区副本的分布情况向对应broker发送请求完成topic分区的创建。

    对于通过接口创建topic的处理逻辑为:

    • 客户端向broker发送CREATE_TOPIC的请求

    • broker接收到请求后,从元数据缓存中获取当前集群的所有broker

    • 根据topic创建的参数,进行topic分区副本的分配

    • 通过zk客户端,将topic分区副本信息写入zookeeper

    • kafka broker的controller监听zk并感知其变化,然后根据分区副本的分布情况向对应broker发送请求完成topic分区的创建

    两种方式本质上的处理都是一样的,即进行topic分区副本的分配,并将这个信息写入zookeeper,然后由controller完成真正的创建逻辑。只不过一个是在客户端侧完成,一个是向broker发送请求,在broker侧完成。

    既然两种创建topic的方式,其处理逻辑是一样的,那怎么进行扩分区操作后,就不一样了呢?

    我们再来看下扩分区的处理逻辑。
    其流程其实和创建topic是一样的,先获取集群所有broker的信息,然后对新增的分区进行broker的分配,最后将完整信息写入zookeeper,broker的controller监听感知信息的变化后,向对应的broker节点发送请求完成分区的新增动作。

    broker侧在处理创建topic的请求时,brokerList是直接从元数据缓存中获取的,而这个元数据缓存是根据controller来更新的。

    controller被选举出来后首次初始化时触发的元数据更新,无法保证broker的有序,同样,随着broker可能的上下线引起的元数据更新也无法保证broker的有序。

    本文通过分析集群扩容,同时对topic进行扩分区操作,新扩的分区没有分布到新的broker节点上这一问题现象进行分析,最后发现是由于创建topic时broker列表没有按ID排序,而扩分区操作时broker列表又是按ID排序,两次操作时的broker列表顺序不一致导致出现该问题。

    另外,在分析过程中,我们发现kafka-topics.sh脚本可以是指定--zookeeper参数,或者是--bootstrap-server参数。如果指定--bootstrap-server参数的话,等同于通过调用接口完成相关逻辑,也就是会遇到上面提到的问题。

    相关文章

      网友评论

          本文标题:【kafka】kafka 扩分区方式的不用,导致分区分布不一样

          本文链接:https://www.haomeiwen.com/subject/itnikjtx.html