Option "[replication-factor]" can't be used with option"[alter]"
It is funny that you can change number of partitions on the fly (which is often hugely destructive action when done in runtime), but cannot increase replication factor, which should be transparent. But remember, it is 0.10, not 10.0... Please see here for enhancement request https://issues.apache.org/jira/browse/KAFKA-1543
If you have a lot of partitions, using kafka-reassign-partitions to generate the json file required by Łukasz Dumiszewski's answer (and the official documentation) can be a timesaver. Here is an example of replicating a 64 partition topic from 1 to 2 servers without having to specify all the partitions:
Łukasz Dumiszewski's answer is correct but manually generating that file is a bit hard.
Luckily there are some easy ways to achieve what @Łukasz Dumiszewski said.
If you are using kafka-managertool, from version 2.0.0.2 you can change the replication factor in Generate Partition Assignment section in a topic view. Then you should click on Reassign Partitions to apply the generated partition assignment (if you select a different replication factor, you will get a warning but you can click on Force Reassign afterward).
If you have ruby installed you can use this helper script
If you prefer nodejs you can generate the file with this gist too.
# 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
Note that the Kafka API that kafkactl is using for this is only available for Kafka ≥ 2.4.0.
then in the next step we need to identify brokers list where we need to sync our replicas and it requires topic rebalance to do this create a json file and define all the ISR brokers and topic
This script will generate the JSON for kafka-reassign-partitions.sh and feed it into that script to increase the replication factor. The new set of replicas will:
Keep the current replicas
Add new unique brokers (this will prevent unneeded data migrations)
This script was tested with 2.8.0 Kafka scripts. Only the variables at the top of the file will need modified.
#!/bin/bash
KAFKA_BIN="./bin"
KAFKA_CONNECTION_ARGS="--bootstrap-server localhost:9094"
broker_ids="1,2,3"
topic="topic_foobar"
new_replication_factor=3 # New replication factor
reassignment_file="./reassignment.json"
#~~~~ Don't change anything after this line ~~~~#
# Generate a list of "partition|replicas"
topic_data="$("$KAFKA_BIN/kafka-topics.sh" $KAFKA_CONNECTION_ARGS --describe --topic "$topic" | tail -n +2 | sed -E 's/.*Partition:\s+([0-9]+).*Replicas:\s+([0-9,]+).*/\1|\2/g')"
partition_count=$(echo "$topic_data" | wc -l)
echo '{
"version": 1,
"partitions": [' > "$reassignment_file"
log_dirs="$(yes '"any"' | head -n $new_replication_factor | sed -e ':a;N;$!ba;s/\n/,/g')"
obj_sep=","
while read -r partition_data; do
partition=$(echo "$partition_data" | cut -d '|' -f 1)
replicas=$(echo "$partition_data" | cut -d '|' -f 2)
# Randomize the replicas (using this list as a queue)
random_replicas="$(echo $broker_ids | tr "," "\n" | shuf)"
# Loop until the replicas has desired RF - 1 commas
while [ "$(echo "$replicas" | tr -dc , | wc -c)" != $((new_replication_factor-1)) ]; do
# Pick the next replica, add it to the list if it isn't already there, otherwise advance the queue
next_replica="$(echo "$random_replicas" | head -1)"
if [[ $replicas != *$next_replica* ]]; then
replicas="$replicas,$next_replica"
else
random_replicas="$(echo "$random_replicas" | tail -n +2)"
fi
done
# Don't add a comma on the last object
if [ "$((partition_count-1))" == "$partition" ]; then obj_sep=""; fi
echo ' {
"topic": "'"$topic"'",
"partition": '"$partition"',
"replicas": ['"$replicas"'],
"log_dirs": ['"$log_dirs"']
}'$obj_sep >> "$reassignment_file"
done < <(echo "$topic_data")
echo ' ]
}' >> "$reassignment_file"
cat "$reassignment_file"
read -p "Apply the above reassignment? (Ctrl-C to exit): "
"$KAFKA_BIN/kafka-reassign-partitions.sh" $KAFKA_CONNECTION_ARGS --execute --reassignment-json-file "$reassignment_file"