한 Kafka 클러스터의 토픽을 다른 서버로 옮기려고 로그 디렉터리를 통째로 복사했더니 브로커가 뜨지 않는다.
kafka.common.InconsistentClusterIdException: The Cluster ID 2SFhiN7CSk6fHCd43-AY3A
doesn't match stored clusterId Some(9fTRkQhZTCK7AdQhxZ7lLQ) in meta.properties.
The broker is trying to join the wrong cluster. Configured zookeeper.connect may be wrong.
브로커의 로그 디렉터리에는 meta.properties 라는 파일이 있고, 그 안에 이 데이터가 속한 클러스터의 ID 와 브로커 ID 가 적혀 있다.
cat /var/lib/kafka/data/meta.properties
cluster.id=9fTRkQhZTCK7AdQhxZ7lLQ
broker.id=1
version=0
브로커는 기동할 때 이 값과 컨트롤러(ZooKeeper 또는 KRaft 쿼럼)가 알고 있는 클러스터 ID 를 대조한다. 다르면 "다른 클러스터의 데이터" 로 판단해 거부한다. 잘못된 클러스터에 데이터를 섞지 않게 하는 안전장치다.
따라서 데이터 디렉터리 복사는 토픽 이전 수단이 아니다. 같은 클러스터를 다른 장비로 통째로 옮기는 경우에만 성립한다.
클러스터 사이 복제의 표준 수단이다. 토픽 데이터뿐 아니라 설정·ACL·컨슈머 그룹 오프셋까지 따라간다. 운영 중에도 돌릴 수 있어 무중단 이전에 쓴다.
clusters = src, dst
src.bootstrap.servers = old-broker1:9092,old-broker2:9092
dst.bootstrap.servers = new-broker1:9092,new-broker2:9092
src->dst.enabled = true
src->dst.topics = .*
sync.topic.configs.enabled = true
sync.group.offsets.enabled = true
emit.checkpoints.enabled = true
replication.factor = 3
$KAFKA_HOME/bin/connect-mirror-maker.sh mm2.properties
기본 설정에서는 대상 쪽 토픽 이름에 원본 클러스터 별칭이 접두사로 붙는다(src.orders). 이름을 그대로 두려면 replication.policy.class 를 IdentityReplicationPolicy 로 바꾼다. 다만 양방향 복제에서는 순환 위험이 있으니 단방향일 때만 쓴다.
건수가 적고 순서 보장이 덜 중요하다면 간단히 끝낼 수 있다.
kafka-console-consumer.sh --bootstrap-server old-broker1:9092 \
--topic orders --from-beginning --timeout-ms 30000 > orders.txt
kafka-console-producer.sh --bootstrap-server new-broker1:9092 \
--topic orders < orders.txt
키와 파티션 배치는 유지되지 않는다. 키가 중요하면 --property print.key=true --property key.separator=$'\t' 를 양쪽에 맞춰 준다.
데이터가 필요 없고 구조만 재현하면 되는 경우다.
kafka-topics.sh --bootstrap-server old:9092 --describe > topics.txt
kafka-topics.sh --bootstrap-server new:9092 --create --topic orders \
--partitions 12 --replication-factor 3 \
--config retention.ms=604800000 --config cleanup.policy=delete
새 클러스터를 새로 만들려던 것이라면 복사해 온 데이터 디렉터리를 비운다. 기존 데이터가 지워지므로 옮길 데이터가 있는지 먼저 확인한다.
sudo systemctl stop kafka
sudo mv /var/lib/kafka/data /var/lib/kafka/data.bak
sudo mkdir -p /var/lib/kafka/data && sudo chown kafka:kafka /var/lib/kafka/data
sudo systemctl start kafka
같은 클러스터인데 ID 가 어긋난 경우라면 ZooKeeper 쪽 값을 확인한다. 브로커가 엉뚱한 ZooKeeper 체인루트를 보고 있는 것이 원인일 수 있다.
zookeeper-shell.sh zk1:2181 get /kafka/cluster/id
grep zookeeper.connect /etc/kafka/server.properties
zookeeper.connect 끝의 체인루트(/kafka)가 다르면 완전히 다른 클러스터가 된다. 옛 클러스터의 값을 그대로 가져다 쓰면 이 오류를 만난다.
KRaft 모드라면 클러스터 ID 는 포맷 단계에서 정해진다.
kafka-storage.sh random-uuid
kafka-storage.sh format -t <클러스터ID> -c /etc/kafka/server.properties
meta.properties 의 cluster.id 를 손으로 고쳐 맞추는 방법이 인터넷에 돌아다니지만, 데이터가 실제로 그 클러스터의 것이 아니라면 파티션 메타데이터가 어긋나 나중에 더 어려운 문제가 된다. 새 클러스터라면 비우는 쪽이 맞다.
이전 후에는 컨슈머 그룹 오프셋을 확인한다. MirrorMaker 2 의 오프셋 동기화를 켜지 않았다면 컨슈머가 처음부터 다시 읽는다.
kafka-consumer-groups.sh --bootstrap-server new:9092 --describe --group app-group
zookeeper.connect 를 비롯한 기동 설정.