如何更改Kafka主题的副本数?


73

生产者或管理员创建Kafka主题后,如何更改该主题的副本数?

Answers:


12

编辑:我被证明是错误的-请检查 ŁukaszDumiszewski的出色回答。

现在,我将保留原来的答案以供完善。



我认为你不能。通常情况是

./kafka-topics.sh --zookeeper本地主机:2181-更改--topic test2-复制因子3

但它说

选项“ [replication-factor]”不能与选项“ [alter]”一起使用

有趣的是,您可以动态更改分区数(在运行时完成时,这通常是破坏性很大的动作),但不能增加复制因子,而复制因子应该是透明的。但是请记住,它是0.10,而不是10.0 ...请参阅此处获取增强请求https://issues.apache.org/jira/browse/KAFKA-1543


感谢您及时的答复,您的意思是没有必要,或者在Kafka运行时中更改副本是不寻常的,对吧?或者,如果我想更改它,可以将补丁安装在您粘贴的链接中,对吗?
GuruPo

1
我认为该补丁不是开箱即用的-它是一年前针对版本进行的。最重要的是,它不是动态工作的-它只是更改元数据,因此据我了解,您需要重新启动整个集群才能使其生效。如果您要关闭整个系统,则删除和重新创建主题可能会更容易。至于真正的解决方案-在系统运行时添加副本,我认为没有人对此进行任何工作,并且添加副本当然需要一定的努力(但是使用当前体系结构应该可以实现)。
Artur Biesiadowski

136

要增加给定主题的副本数量,您必须:

1.在自定义重新分配json文件中指定额外的副本

例如,您可以创建cremental-replication-factor.json并将其放入其中:

{"version":1,
  "partitions":[
     {"topic":"signals","partition":0,"replicas":[0,1,2]},
     {"topic":"signals","partition":1,"replicas":[0,1,2]},
     {"topic":"signals","partition":2,"replicas":[0,1,2]}
]}

2.将文件与kafka-reassign-partitions工具的--execute选项一起使用

[或kafka - reassign - partitions.sh-取决于kafka软件包]

例如:

$ kafka-reassign-partitions --zookeeper localhost:2181 --reassignment-json-file increase-replication-factor.json --execute

3.使用kafka-topics工具验证复制因子

[或kafka-topics.sh-取决于kafka软件包]

 $ kafka-topics --zookeeper localhost:2181 --topic signals --describe

Topic:signals   PartitionCount:3    ReplicationFactor:3 Configs:retention.ms=1000000000
Topic: signals  Partition: 0    Leader: 2   Replicas: 0,1,2 Isr: 2,0,1
Topic: signals  Partition: 1    Leader: 2   Replicas: 0,1,2 Isr: 2,0,1
Topic: signals  Partition: 2    Leader: 2   Replicas: 0,1,2 Isr: 2,0,1

另请参阅:官方文档中描述如何增加复制因子的部分


以编程方式在哪里设置复制因子...即消费者方还是生产方
BdEngineer

8
Kafka-reassign-partitions可以通过指定要生成的分区建议重新分配 --generate--topics到布展JSON文件,但是文件并没有解释的内容以及:{ "topics": [ { "topic": "YOUR_TOPIC_NAME_1" }, { "topic": "YOUR_TOPIC_NAME_2" } ], "version": 1 } 然后,命令如下kafka-reassign-partitions.sh --zookeeper #.#.#.#:2181,#.#.#.#:2181,#.#.#.#:2181 --broker-list #,#,# --topics-to-move-json-file reassignment.topics.json --generate
andyfeller

2
步骤2是否kafka-reassign-partitions会导致任何停机时间?我有一些主题的复制因子为1(默认值,创建时忘了指定),我想知道我的生产者在重新分配分区时是否会出错。
mmrobins

如何自动执行此操作?第一步迫使我根据现有经纪人,分区的数量来手工制作。
Beatrice

@beatrice当前在Kafka中,主题管理是半手动过程。您可以使用./kafka-topics.sh –zookeeper zkhost:9092 --describe获得有关分区的信息,对于代理信息,请使用zookeeper-shell.sh zkhost:9092 ls / brokers / ids
c0der512'0

7

ŁukaszDumiszewski的回答是正确的,但是手动生成该文件有些困难。幸运的是,有一些简单的方法可以实现@ŁukaszDumiszewski所说的。

  • 如果您使用的是kafka-manager tool,从版本开始,2.0.0.2您可以Generate Partition Assignment在主题视图的部分中更改复制因子。然后,您应单击Reassign Partitions以应用生成的分区分配(如果您选择其他复制因子,则会收到警告,但您可以Force Reassign随后单击)。

  • 如果您已安装ruby,则可以使用此帮助程序脚本

  • 如果您喜欢nodejs,则可以使用 要点。

1
这对我来说是最简单的方法,因为我有一个正在运行的Kafka管理器实例。值得一提的是,您必须两次“强制重新分配”:收到警告后,必须单击“尝试强制运行”链接,这将使您返回主题概述屏幕。现在将有一个修改后的按钮“ Force reassign partitions”,它将起到神奇的作用。感谢您的提示!
pederpansen

3

如果要更改所有主题的复制因子,此脚本可能会为您提供帮助:

#!/bin/bash

topics=`kafka-topics --list --zookeeper zookeeper:2181`

while read -r line; do lines+=("$line"); done <<<"$topics"
echo '{"version":1,
  "partitions":[' > tmp.json
for t in $topics; do 
    if [ "${t}" == "${lines[-1]}" ]; then
        echo "    {\"topic\":\"${t}\",\"partition\":0,\"replicas\":[0,1,2]}" >> tmp.json
    else
        echo "    {\"topic\":\"${t}\",\"partition\":0,\"replicas\":[0,1,2]}," >> tmp.json
    fi
done

echo '  ]
}' >> tmp.json

kafka-reassign-partitions --zookeeper zookeeper:2181 --reassignment-json-file tmp.json --execute

您能否解释为什么这应该起作用?请在此答案中添加一些细节,以便有类似问题的人也可以使用它!谢谢!
CreyD

当我发现团队中的开发人员创建的主题没有副本时,便编写了此脚本。我们没有使用很多分区。并非所有人都知道默认的Kafka将复制因子设置为1。高容错能力是群集的主要要求。
ДмитрийШепелев

为什么这不起作用?脚本获取所有主题。形成json。并应用它。
ДмитрийШепелев

这不是很安全,因为它假设您只有3个大小均等的经纪人,而且它们已经平均分配了
OneCricketeer

2
从脚本文本中不是很明显吗?网络管理员的第一条规则是不要运行晦涩的脚本。)))如果我没有3个相同大小的代理,该如何说群集为高可用性?我知道我的剧本不是灵丹妙药。但是在我的情况下,他帮助了我。如果情况不同,则可以根据需要修复我的脚本或使用其他脚本。
ДмитрийШепелев

1

如果您有很多分区,使用kafka-reassign-partitionsŁukaszDumiszewski的答案(和官方文档)所需的json文件生成可能会节省很多时间。这是一个从1到2个服务器复制64个分区主题的示例,而不必指定所有分区:

expand_topic=TestTopic
current_server=111
new_servers=111,222
echo '{"topics": [{"topic":"'${expand_topic}'"}], "version":1}' > /tmp/topics-to-expand.json
/bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --topics-to-move-json-file /tmp/topics-to-expand.json --broker-list "${current_server}" --generate | tail -1 | sed s/\\[${current_server}\\]/\[${new_servers}\]/g | tee /tmp/topic-expand-plan.json
/bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --reassignment-json-file /tmp/topic-expand-plan.json --execute
/bin/kafka-topics.sh --zookeeper localhost:2181 --describe --topic ${expand_topic}

输出:

Topic:TestTopic PartitionCount:64   ReplicationFactor:2 Configs:retention.ms=6048000
    Topic: TestTopic    Partition: 0    Leader: 111 Replicas: 111,222   Isr: 111,222
    Topic: TestTopic    Partition: 1    Leader: 111 Replicas: 111,222   Isr: 111,222
    ....

1

@Дмитрий-Шепелев的脚本化答案未包含针对具有多个分区的主题的解决方案。此更新的版本可以:

#!/bin/bash

brokerids="1,2,3"
topics=`kafka-topics --list --zookeeper zookeeper:2181`

while read -r line; do lines+=("$line"); done <<<"$topics"
echo '{"version":1,
  "partitions":['
for t in $topics; do
    sep=","
    pcount=$(kafka-topics --describe --zookeeper zookeeper:2181 --topic $t | awk '{print $2}' | uniq -c |awk 'NR==2{print $1}')
    for i in $(seq 0 $[pcount - 1]); do
        if [ "${t}" == "${lines[-1]}" ] && [ "$[pcount - 1]" == "$i" ]; then sep=""; fi
        randombrokers=$(echo "$brokerids" | sed -r 's/,/ /g' | tr " " "\n" | shuf | tr  "\n" "," | head -c -1)
        echo "    {\"topic\":\"${t}\",\"partition\":${i},\"replicas\":[${randombrokers}]}$sep"
    done
done

echo '  ]
}'

注意:它还会随机分配代理,并为每个分区选择两个副本。因此,请确保在脚本中正确定义了代理ID。

执行如下:

$ ./reassign.sh > reassign.json
$ kafka-reassign-partitions --zookeeper zookeeper:2181 --reassignment-json-file reassign.json --execute

1

您也可以为此使用kafkactl

# first run with --validate-only to see what kafkactl will do
kafkactl alter topic my-topic --replication-factor 2 --validate-only

# then do the replica reassignment
kafkactl alter topic my-topic --replication-factor 2

请注意,kafkactl为此使用的Kafka API仅适用于Kafka≥2.4.0。

免责声明:我是这个项目的贡献者


确实,这似乎是一个很好的工具。是否允许增加和减少副本的数量?我来自stackoverflow.com/a/65571902/2148953,所以也许这就是答案从我的问题需要OP
阿伦

是的,可以使用此增加或减少副本的数量
Dirk

你应该回答这个问题,我会deffinitely给予好评它
阿伦

0

1.将所有主题复制到json文件

#!/bin/bash
topics=`kafka-topics.sh --zookeeper localhost:2181 --list`

while read -r line; do lines+=("$line"); done <<<"$topics"
echo '{"version":1,
 "topics":['
 for t in $topics; do
     echo -e '     { "topic":' \"$t\" '},'
done

echo '  ]
}'

bash alltopics.sh > alltopics.json

2.运行kafka-reassign-partitions.sh生成重新平衡的文件

kafka-reassign-partitions.sh --zookeeper localhost:2181 --broker-list "0,1,2" --generate --topics-to-move-json-file alltopics.json > reassign.json

3.清理reassign.json文件,其中包含现有值和建议值

4.运行kafka-reassign-partitions.sh重新平衡主题

kafka-reassign-partitions.sh --zookeeper localhost:2181 --reassignment-json-file reassign.json --execute

-2

要增加给定主题的副本数量,您必须:

1.使用以下命令为现有主题指定额外的分区(让我们说从2增加到3)

bin/kafktopics.sh --zookeeper localhost:2181 --alter --topic topic-to-increase --partitions 3

2.在自定义重新分配json文件中指定额外的副本

例如,您可以创建cremental-replication-factor.json并将其放入其中:

{"version":1,
  "partitions":[
     {"topic":"topic-to-increase","partition":0,"replicas":[0,1,2]},
     {"topic":"topic-to-increase","partition":1,"replicas":[0,1,2]},
     {"topic":"topic-to-increase","partition":2,"replicas":[0,1,2]}
]}

3.将文件与kafka-reassign-partitions工具的--execute选项一起使用

bin/kafka-reassign-partitions --zookeeper localhost:2181 --reassignment-json-file increase-replication-factor.json --execute

4.使用kafka-topics工具验证复制因子

bin/kafka-topics --zookeeper localhost:2181 --topic topic-to-increase --describe

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.