如何减少分区Kafka主题的数量?

时间:2017-08-04 03:37:58

标签: apache-kafka

我在Kafka上创建了一个包含4个分区的主题。 (设置默认number.partition = 4) 现在我想将此主题的数字分区更改为3。 我试试吧 ./bin/kafka-topics.sh --alter --zookeeper localhost:2181 --topic my-topic --partitions 3 但没有变化。它仍然有4个分区。 有人知道吗?

5 个答案:

答案 0 :(得分:13)

您不能只删除分区,因为这会导致数据丢失,并且剩余数据的密钥也不会正确分发,因此新消息不会被引导到与具有相同密钥的旧现有消息相同的分区。 / p>

由于上述原因,Kafka不支持减少现有主题的分区计数。

您可以做的是创建一个包含3个分区的新主题,然后编写一个小程序(或使用现有的复制工具)将数据从旧的4分区主题复制到新的3分区主题。这样,您将通过同一个分区程序运行所有内容,并且所有键控消息将最终出现在正确的分区中。一旦您满意,数据全部被复制,然后删除原始的4分区主题。

如果必须保留与原始主题相同的主题名称,则只需使用原始名称创建新主题,从重新分区的主题中复制数据,然后删除该临时重新分区主题。

答案 1 :(得分:13)

Apache Kafka不支持减少分区号。您应该将主题视为一个整体,分区是扩展性能的一种方式。因此,发送到主题的所有数据都会流向所有分区并删除其中一个分区意味着数据丢失。

答案 2 :(得分:6)

我不购买上述所有答案。 “删除分区导致数据丢失”是一个模糊的答案。减少分区数在分布式系统中并不是什么新鲜事,事实上很多系统都支持它。如果你能负担得起重新平衡整个存储系统的开销,同时保持数据的一致性,那么减少分区并不是不可能的事情。

在我看来,Kafka不支持减少分区数的真正原因是由于Kafka的一个重要属性:Kafka保证了每个分区内消息的顺序,但不保证分区之间的消息顺序(但这是可能的)。此排序属性在许多用例中至关重要。在删除其中一个分区的原因中,在保留顺序的同时将被删除分区中的消息重新分发到其他分区是不可能的,因为无法保证分区之间的排序。无论您如何分布已删除分区中的数据,您都将破坏您分布到的任何分区的顺序保证属性。如果 Kafka 不关心每个分区内的消息顺序,那么可以很容易地支持减少分区数。

答案 3 :(得分:2)

不支持减少分区号。

答案 4 :(得分:0)

您可以使用创建独立的Java程序来实现相同目的,即使用AdminUtils增加和减少分区和复制。

导入org.I0Itec.zkclient.ZkClient;

导入kafka.admin.AdminUtils;

import kafka.utils.ZKStringSerializer $;

导入kafka.utils.ZkUtils;

导入scala.collection.Seq;

导入scala.collection.Map;

public PartitionCreator(String zkhost, String topicName, int partitions, int replifactor) {
    ZkClient zkClient = new ZkClient(zkhost, 30000, 30000, ZKStringSerializer$.MODULE$);
    zkUtils = ZkUtils.apply(zkClient, false);

    this.topicName = topicName;
    this.partitions = partitions;
    this.replifactor = replifactor;
}

public void createPartion() {

    AdminUtils.createTopic(zkUtils, topicName, partitions, replifactor, new Properties());
    System.out.println("created/updated topic..");
}

注意:如果主题不可用,createTopic()在内部更新主题。