학습 목표

이 도메인이 묻는 것

이 섹션의 전형적인 질문 형태
질문 형태실제로 확인하는 것
"컨트롤러 5대 중 몇 대까지 잃어도 되는가?"2N+1과 과반 규칙
"프로덕션에서 권장되는 process.roles는?"역할 분리 권장, combined 모드의 한계
"랙 3개, RF=3일 때 복제 배치는?"min(랙 수, RF)개 랙에 분산
"두 데이터센터에 걸친 단일 클러스터의 문제는?"복제 지연과 권장 구성(DC별 클러스터 + 미러링)
"MM2로 복제된 토픽의 이름은?"DefaultReplicationPolicy{source}.{topic}
"컨트롤러 추가 절차를 순서대로" (list order)프로비저닝 → 기동 → 복제 확인 → add-controller

핵심 개념 요약 — 운영 관점

노드 롤 — process.roles

process.roles 3가지 조합
역할용도
broker 데이터 저장·서빙. 메타데이터 쿼럼에는 observer로만 참여 프로덕션 브로커 노드
controller 메타데이터 쿼럼의 voter. 데이터 파티션은 갖지 않음 프로덕션 컨트롤러 노드
broker,controller 둘 다 (combined 서버) 개발·소규모 환경. 중요 운영 환경에서는 권장되지 않습니다
KRaft 노드 롤 조합 — broker, controller, combined process.roles 를 broker 로 두면 토픽 데이터를 저장하고 클라이언트 요청을 처리합니다. listeners 에는 클라이언트용 리스너만 두고, controller.listener.names 와 그 보안 설정은 필요하지만 listeners 에는 넣지 않으며 controller.quorum.bootstrap.servers 로 컨트롤러 쿼럼을 찾습니다. controller 로 두면 메타데이터만 담당하고 토픽 데이터를 저장하지 않으며, controller.listener.names 는 inter.broker.listener.name 과 같은 값일 수 없고 클라이언트는 여기에 접속하지 않습니다. 권장 대수는 3대 또는 5대입니다. broker 와 controller 를 함께 두는 combined 모드는 한 프로세스가 두 역할을 겸해 리스너를 모두 두어야 하고, 컨트롤러를 브로커와 따로 재시작하거나 확장할 수 없으며 브로커 부하로부터 격리되지 않으므로 공식 문서는 중요한 운영 환경에 권장하지 않습니다. 롤은 kafka-storage.sh format 으로 포맷할 때 정해집니다. process.roles 조합 3가지 — broker · controller · combined process.roles=broker 운영 환경 기본 · 토픽 데이터를 저장하고 클라이언트 요청을 처리합니다. listeners 에는 클라이언트용 리스너만 둡니다. · controller.listener.names 와 그 보안 설정은 필요하지만 listeners 에는 넣지 않습니다. · controller.quorum.bootstrap.servers 로 컨트롤러 쿼럼을 찾아갑니다. process.roles=controller 3대 또는 5대 · 메타데이터만 담당하고 토픽 데이터는 저장하지 않습니다. listeners 에 컨트롤러 리스너를 둡니다. · controller.listener.names 는 inter.broker.listener.name 과 같은 값일 수 없습니다. · 클라이언트는 컨트롤러에 접속하지 않습니다 — 붙어도 데이터를 읽을 수 없습니다. process.roles=broker,controller 개발 · 소규모 전용 · 한 프로세스가 두 역할을 겸합니다. listeners 에 클라이언트용과 컨트롤러용을 모두 둡니다. · 컨트롤러를 브로커와 따로 재시작하거나 확장할 수 없고, 브로커 부하로부터 격리되지 않습니다. · 공식 문서는 중요한 운영 환경에는 권장하지 않습니다. 어느 조합이든 클러스터에는 controller 롤 노드가 반드시 있어야 하고, 그 수는 홀수(3 또는 5)를 권장합니다. 롤은 포맷 시점에 정해집니다 kafka-storage.sh format --standalone -c config/server.properties
노드 롤 조합 — broker 전용 / controller 전용 / combined 3가지 배치 비교

컨트롤러 쿼럼 사이징 — 3 vs 5

메타데이터 쿼럼은 Raft이므로 과반이 살아 있어야 쓰기(메타데이터 변경)가 가능합니다. 동시 장애 N건을 견디려면 컨트롤러가 2N+1대 필요합니다.

컨트롤러 수와 내결함성
컨트롤러 수 과반 견딜 수 있는 동시 장애 선택 기준
110개발 전용. 쿼럼 개념 실습용
321대부분의 프로덕션. 비용과 안전의 균형
532가용 영역 3개 이상, 유지보수 중 추가 장애까지 견뎌야 할 때
짝수(예: 4)31의미 없음 — 3대와 내결함성이 같은데 비용만 늘어납니다
컨트롤러 쿼럼과 메타데이터 로그 — Raft 복제와 스냅샷 컨트롤러 3대가 쿼럼을 이루고 그중 하나가 액티브 컨트롤러이자 Raft 리더입니다. 각 컨트롤러는 __cluster_metadata 파티션 0 의 복제본을 가지며, 쓰기는 항상 액티브 컨트롤러가 수행하고 팔로워가 복제합니다. 레코드는 과반이 복제하면 커밋됩니다. 로그가 무한정 길어지지 않도록 스냅샷으로 상태를 저장하고 앞부분을 잘라내므로 재시작 시 스냅샷과 이후 로그만 재생하면 됩니다. 브로커는 투표에 참여하지 않는 옵서버로서 메타데이터 로그만 복제해 캐시하므로 컨트롤러가 잠시 멈춰도 이미 아는 메타데이터로 읽기와 쓰기를 계속할 수 있습니다. 쿼럼 크기는 3 또는 5 를 권장하며 3대면 1대, 5대면 2대 장애까지 견딥니다. 주소는 controller.quorum.bootstrap.servers 로 지정하고 상태는 kafka-metadata-quorum.sh 로 확인합니다. 컨트롤러 쿼럼과 __cluster_metadata — 메타데이터가 복제되는 방식 컨트롤러 쿼럼 (voter) — 과반이 살아 있어야 메타데이터 쓰기가 가능합니다 controller-1 액티브 · Raft 리더 __cluster_metadata-0 1 2 3 4 5 controller-2 팔로워 (voter) __cluster_metadata-0 1 2 3 4 5 controller-3 팔로워 (voter) __cluster_metadata-0 1 2 3 4 5 쓰기는 항상 액티브 컨트롤러가 하고, 팔로워는 그 로그를 복제합니다 (Raft). 레코드는 과반 복제되면 커밋됩니다. 스냅샷 로그가 계속 길어지지 않도록 상태를 스냅샷으로 저장하고 앞부분을 잘라냅니다. 재시작 시 스냅샷 + 이후 로그만 재생하면 되므로 복구가 빠릅니다. 브로커 = 옵서버 (voter 아님) 브로커는 쿼럼 투표에 참여하지 않고 메타데이터 로그만 복제해 캐시합니다. 그래서 컨트롤러가 잠시 멈춰도 이미 아는 메타데이터로 계속 동작합니다. 쿼럼 크기는 3 또는 5 를 권장합니다 — 3대면 1대 장애, 5대면 2대 장애까지 견딥니다. 주소는 controller.quorum.bootstrap.servers 로 지정합니다 — controller.quorum.voters 는 deprecated 입니다. 상태 확인 kafka-metadata-quorum.sh --bootstrap-controller :9093 describe --status
컨트롤러 쿼럼과 메타데이터 로그 — __cluster_metadata, Raft 리더, 스냅샷의 관계

정적 쿼럼 vs 동적 쿼럼

KRaft에는 두 가지 운영 방식이 있습니다. 어느 쪽인지는 포맷 시점에 결정됩니다.

정적 쿼럼과 동적 쿼럼
구분정적 쿼럼동적 쿼럼
쓰는 설정 controller.quorum.voters모든 컨트롤러의 ID·호스트·포트를 명시 controller.quorum.bootstrap.servers. 클라이언트의 bootstrap.servers처럼 일부만 적어도 동작
컨트롤러 추가·제거 불가 가능
판별 방법 kraft.versionFinalizedVersionLevel0 또는 없음 kraft.version1 이상
도입 시점 초기 KRaft 방식 kraft.version=1 (release-version 4.1)에서 추가

랙 인식 — broker.rack

브로커에 broker.rack=my-rack-id를 붙이면 토픽 생성·수정·재배치 시 같은 파티션의 레플리카가 서로 다른 랙에 퍼집니다. 정확히는 한 파티션이 min(랙 수, replication factor)개의 랙에 걸칩니다. 클라우드에서는 가용 영역(AZ)을 랙으로 쓰는 것이 일반적입니다.

랙 수와 RF 조합의 효과
랙 수 RF 파티션이 걸치는 랙 수 한 랙 전체 장애 시
333레플리카 1개 손실. ISR 2개 유지 → min.insync.replicas=2로 쓰기 계속
232한 랙에 2개가 있을 수 있어 레플리카 2개 손실 가능
322레플리카 1개 손실. ISR 1개 → min.insync.replicas=2면 쓰기 중단

브로커 사이징과 디스크

하드웨어 판단 기준 (공식 문서 기준)
항목기준근거
메모리 대략 쓰기 처리량 × 30초를 버퍼로 잡습니다 활성 리더·라이터를 버퍼링할 만큼의 페이지 캐시가 필요합니다
디스크 디스크 처리량이 병목입니다. 개수가 많은 편이 유리합니다 공식 문서가 예로 든 구성은 7200rpm SATA 8개입니다
디스크 구성 JBOD(여러 log.dirs) 또는 RAID. 애플리케이션 로그와 데이터 디스크를 분리하세요 RAID는 디스크 간 부하 분산에 유리하지만 쓰기 처리량과 용량을 잃습니다
파일시스템 XFS 권장. 마운트 옵션 noatime XFS가 EXT4보다 Request Local Time이 낮고 변동성도 작았습니다(160ms 대 250ms+)
파일 디스크립터 최소 100000을 시작점으로 세그먼트 파일 + 연결 수만큼 필요합니다
vm.max_map_count 파티션 수에 맞춰 상향. 세그먼트 1개 = map area 2개 기본값이 65535 근처인 배포판에서 파티션을 과하게 올리면 Map failed로 죽습니다
flush 정책 기본값 유지(애플리케이션 fsync 비활성) 내구성은 복제로 확보합니다. fsync를 강제하면 지연이 늘고 디스크 사용 패턴이 나빠집니다
Java 17 · 21 · 25 완전 지원. 브로커는 최소 17 Java 8은 4.0에서 제거되었습니다. 11은 clients·streams 등 일부 모듈만
OS Linux 권장. Windows는 잘 지원되는 플랫폼이 아닙니다 공식 문서 명시

멀티 데이터센터

권장 구성은 DC마다 로컬 Kafka 클러스터를 두고, 애플리케이션은 자기 DC의 클러스터만 쓰고, 클러스터 사이를 미러링하는 것입니다. 전체 데이터가 필요한 애플리케이션을 위해 집계(aggregate) 클러스터를 따로 두고 각 DC에서 미러링해 채웁니다.

MirrorMaker 2

MM2는 Kafka Connect 프레임워크 위에 만들어진 클러스터 간 복제 도구입니다. 클러스터 내부 복제(레플리카)와는 완전히 다른 것입니다. 토픽 데이터와 설정, 컨슈머 그룹과 오프셋, ACL을 복제하고 파티셔닝을 보존합니다.

복제 흐름(replication flow) 패턴
구성흐름 표기용도
Active/PassiveA->B재해 복구 대기 클러스터
Active/ActiveA->B, B->A양방향 고가용성
집계A->K, B->K, C->K여러 DC를 한 클러스터로 모으기
팬아웃K->A, K->B, K->C중앙에서 엣지로 배포
connect-mirror-maker.properties — 최소 구성
# 클러스터 별칭 정의
clusters = us-west, us-east
us-west.bootstrap.servers = broker3-west:9092
us-east.bootstrap.servers = broker5-east:9092

# 기본 복제 대상: 모든 토픽
topics = .*

# 흐름 활성화와 흐름별 오버라이드
us-west->us-east.enabled = true
us-west->us-east.topics = orders.*, payments.*

# 워커 수보다 태스크를 넉넉히 (기본값 1은 너무 작습니다)
tasks.max = 5

# 클러스터별 클라이언트 설정 오버라이드
us-west.consumer.isolation.level = read_committed
us-east.producer.compression.type = zstd
전용 MM2 클러스터 실행
# 이 프로세스가 담당할 대상 클러스터만 지정 (대상 클러스터 근처에서 실행하는 것이 일반적)
bin/connect-mirror-maker.sh connect-mirror-maker.properties --clusters us-east

# 지정하지 않으면 설정에 정의된 모든 흐름을 이 프로세스가 담당합니다
bin/connect-mirror-maker.sh connect-mirror-maker.properties
MM2 주요 기본값 — 시험에 나오는 값들
설정기본값의미
replication.policy.class DefaultReplicationPolicy 복제된 토픽 이름을 {source}.{topic}으로 만듭니다. 구분자는 replication.policy.separator(기본 .)
replication.factor 2 대상 클러스터에 만들 복제 토픽의 RF. 기본값이 3이 아닙니다
tasks.max 1 공식 문서는 최소 2, 가능하면 더 크게 두라고 권고합니다
sync.group.offsets.enabled false 대상 클러스터의 __consumer_offsets에 오프셋을 직접 쓰는 기능. 기본은 꺼져 있습니다
emit.checkpoints.enabled true 체크포인트 토픽에 오프셋 매핑을 기록 (주기 기본 60초)
sync.topic.configs.enabled true 토픽 설정도 복제 (주기 기본 600초)
sync.topic.acls.enabled true ACL도 복제 (주기 기본 600초)
refresh.topics.interval.seconds 600 새 토픽·파티션 탐지 주기. 새 토픽이 늦게 복제되는 이유입니다
offset.lag.max 100 오프셋 동기 레코드를 새로 쓰기 전 허용하는 최대 lag
groups.exclude console-consumer-.*,connect-.*,__.* 기본적으로 제외되는 그룹 패턴
topics.exclude mm2.*\.internal,.*\.replica,__.* 내부 토픽과 이미 복제된 토픽을 제외해 순환 복제를 막습니다

필수 CLI 명령어

클러스터 프로비저닝 — 포맷 방식이 정적/동적을 결정합니다
# 클러스터 ID 생성 (전 노드가 같은 값을 씁니다)
CLUSTER_ID="$(bin/kafka-storage.sh random-uuid)"

# (권장) 첫 컨트롤러 하나로 부트스트랩한 뒤 나머지를 동적으로 추가
bin/kafka-storage.sh format --cluster-id $CLUSTER_ID --standalone \
    --config config/controller.properties

# 또는 처음부터 여러 voter 로 부트스트랩 (모든 컨트롤러에서 같은 값으로 실행)
bin/kafka-storage.sh format --cluster-id $CLUSTER_ID \
    --initial-controllers "0@controller-0:9093:$UUID0,1@controller-1:9093:$UUID1,2@controller-2:9093:$UUID2" \
    --config config/controller.properties

# 기존 클러스터에 합류할 브로커·컨트롤러
bin/kafka-storage.sh format --cluster-id $CLUSTER_ID \
    --config config/server.properties --no-initial-controllers
쿼럼 상태 확인과 기능 버전 판별
# 리더·에폭·voter·observer
bin/kafka-metadata-quorum.sh --bootstrap-server localhost:9092 describe --status

# 노드별 Lag / LastFetchTimestamp / LastCaughtUpTimestamp
bin/kafka-metadata-quorum.sh --bootstrap-server localhost:9092 describe --replication

# kraft.version 이 0 이면 정적, 1 이상이면 동적 쿼럼
bin/kafka-features.sh --bootstrap-controller localhost:9093 describe

# 기능 버전 업그레이드
bin/kafka-features.sh --bootstrap-server localhost:9092 upgrade --feature kraft.version=1
컨트롤러 멤버십 변경 (동적 쿼럼 전용)
# 추가: 프로비저닝 → 기동 → --replication 으로 따라잡았는지 확인 → add-controller
bin/kafka-metadata-quorum.sh --command-config config/controller.properties \
    --bootstrap-controller localhost:9093 add-controller

# 제거: 노드를 내리기 전에 먼저 쿼럼에서 뺀다
bin/kafka-metadata-quorum.sh --bootstrap-controller localhost:9093 remove-controller \
    --controller-id 3 --controller-directory-id <directory-id>
브로커 제거 — 재할당이 먼저입니다
# 1) cordon: 이 브로커의 로그 디렉터리를 신규 배치 대상에서 제외
bin/kafka-configs.sh --bootstrap-server localhost:9092 --alter \
    --add-config cordoned.log.dirs="*" --entity-type brokers --entity-name 1

# 2) 이 브로커의 모든 파티션을 다른 브로커로 재할당 (계획은 직접 작성)
#    절차는 Cluster Configuration 페이지 참고

# 3) 브로커 종료 후 클러스터에서 등록 해제
bin/kafka-cluster.sh unregister --bootstrap-server localhost:9092 --id 1
메타데이터 디버깅 — 컨트롤러 이상 조사 시
# 메타데이터 로그 세그먼트 디코딩
bin/kafka-dump-log.sh --cluster-metadata-decoder \
    --files metadata_log_dir/__cluster_metadata-0/00000000000000000000.log

# 스냅샷을 대화식으로 탐색
bin/kafka-metadata-shell.sh \
    --snapshot metadata_log_dir/__cluster_metadata-0/00000000000000007228-0000000001.checkpoint

반드시 외워야 할 설정값

Kafka 4.3 배포 관련 기본값
설정 기본값 의미 운영 포인트
process.roles 비어 있음 노드 역할 KRaft에서 필수 설정입니다.
node.id 비어 있음 노드 식별자 클러스터 내 유일해야 합니다. read-only.
controller.quorum.bootstrap.servers 빈 문자열 컨트롤러 탐색 주소 모든 브로커·컨트롤러가 설정해야 합니다.
controller.quorum.fetch.timeout.ms 2000 이 시간 동안 리더에서 fetch를 못 하면 새 선거를 시작 컨트롤러 노드 간 네트워크가 불안정하면 선거가 반복됩니다.
controller.quorum.election.timeout.ms 1000 선거 결론이 안 날 때 재선거까지 대기
metadata.log.dir null 메타데이터 로그 위치 미설정 시 log.dirs첫 번째를 씁니다. 전용 디스크에 두는 것이 안전합니다.
log.dirs null 데이터 디렉터리 목록 미설정 시 log.dir(기본 /tmp/kafka-logs)이 쓰입니다. /tmp는 프로덕션 금지.
broker.rack null 랙·AZ 식별자 없으면 랙 인식 배치가 동작하지 않습니다. read-only.
num.network.threads 3 네트워크 스레드 수 NetworkProcessorAvgIdlePercent가 0.3 미만이면 검토 대상입니다.
num.io.threads 8 요청 처리 스레드 수 RequestHandlerAvgIdlePercent가 0.3 미만이면 검토 대상입니다.
num.recovery.threads.per.data.dir 2 기동 시 로그 복구 스레드 비정상 종료 후 기동이 오래 걸리면 올립니다.
queued.max.requests 500 요청 큐 깊이 큐가 차면 네트워크 스레드가 블록됩니다.
socket.request.max.bytes 104857600
(100 MiB)
단일 요청 최대 크기
connections.max.idle.ms 600000
(10분)
유휴 연결 종료

장애 시나리오와 대응

시나리오 1 — 컨트롤러 과반을 잃었다

  1. 증상: 토픽 생성·삭제·설정 변경이 모두 타임아웃. 기존 파티션의 읽기·쓰기는 한동안 계속됩니다.
  2. kafka-metadata-quorum.sh --bootstrap-controller ... describe --status로 현재 voter와 리더를 확인합니다.
  3. 브로커도 못 붙는 상황이면 --bootstrap-controller로 컨트롤러에 직접 조회합니다.
  4. 과반을 복구하는 것이 유일한 정답입니다. 내려간 컨트롤러를 다시 올립니다.
  5. 디스크가 날아간 컨트롤러를 새로 넣을 때는 포맷 전에 describe --replication으로 과반이 커밋된 데이터를 갖고 있는지 확인합니다. 빈 로그 디렉터리로 과반이 기동하면 커밋된 데이터가 빠진 리더가 뽑힐 수 있습니다.

시나리오 2 — 컨트롤러를 3대에서 5대로 늘려야 한다

이 절차가 list order 유형으로 자주 나옵니다. 순서를 바꾸면 쿼럼이 위험해집니다.

  1. kafka-features.sh describe동적 쿼럼(kraft.version 1 이상)인지 확인합니다. 정적이면 먼저 업그레이드해야 합니다.
  2. 새 컨트롤러 노드를 --no-initial-controllers로 포맷합니다.
  3. 새 컨트롤러를 기동합니다. 이 시점에는 아직 voter가 아니라 observer입니다.
  4. describe --replication으로 새 노드가 리더를 따라잡았는지 확인합니다.
  5. 따라잡은 뒤 add-controller쿼럼에 편입합니다.
  6. 한 대씩 반복합니다. 여러 대를 동시에 넣으면 과반 계산이 흔들립니다.

제거는 순서가 반대입니다. remove-controller를 먼저 실행하고 그 다음에 노드를 내립니다. 노드를 먼저 내리면 쿼럼은 그 노드를 여전히 voter로 세면서 과반 계산에 포함합니다.

시나리오 3 — AZ 한 곳이 죽자 일부 토픽이 쓰기 불가가 되었다

  1. 랙 인식이 켜져 있었는지 확인합니다. broker.rack이 없으면 배치가 랙을 고려하지 않았습니다.
  2. broker.rack이 있어도 랙 인식은 배치 시점에만 적용됩니다. 나중에 broker.rack을 붙였다면 기존 파티션 배치는 바뀌지 않습니다.
  3. kafka-topics.sh --describe로 문제 토픽의 레플리카가 어느 브로커에 있는지 확인합니다.
  4. 랙을 고려한 배치로 되돌리려면 파티션 재할당을 명시적으로 실행해야 합니다.
  5. 랙마다 브로커 수가 다르면 배치가 불균등해지므로, 그 기회에 랙별 브로커 수를 맞춥니다.

시나리오 4 — MM2 복제가 계속 뒤처진다

  1. tasks.max가 기본값 1인지 확인합니다. 공식 권고는 최소 2, 가능하면 더 크게입니다.
  2. 복제 토픽의 파티션 수를 확인합니다. 태스크는 토픽-파티션 단위로 나뉩니다.
  3. WAN이라면 socket.send.buffer.bytes·socket.receive.buffer.bytes를 대역폭·지연 곱에 맞춰 올립니다.
  4. 대상 클러스터 쪽 프로듀서 압축({target}.producer.compression.type)으로 전송량을 줄입니다.
  5. 새로 만든 토픽이 늦게 복제된다면 refresh.topics.interval.seconds(기본 600)를 확인합니다. 탐지 주기 문제입니다.

자주 나오는 함정

관련 케이스 스터디

KRaft 구조의 배경은 3장 KRaft와 클러스터 메타데이터, 업그레이드 경로와 레거시 대응은 부록, MM2 실습은 예제 11에 있습니다. 구성 변경 절차는 Cluster Configuration과 이어집니다.

4.3 업그레이드 경로 — 이미 KRaft, 낮은 KRaft, ZooKeeper 모드의 세 가지 경우 경로 A 는 이미 KRaft 이고 버전이 3.3.x 에서 4.2.x 사이인 경우로, 브로커를 한 대씩 롤링 재시작해 소프트웨어를 올린 뒤 동작과 성능을 확인하고 마지막에 kafka-features.sh upgrade --release-version 4.3 으로 메타데이터 버전을 올립니다. 4.3 은 메타데이터 변경이 있어 이 단계 뒤에는 다운그레이드가 불가능합니다. 경로 B 는 KRaft 이지만 3.3.x 보다 낮은 경우로 공식 문서는 3.9.x 를 먼저 거치도록 권합니다. 소프트웨어뿐 아니라 메타데이터 버전도 최소 3.3 이어야 합니다. 경로 C 는 아직 ZooKeeper 모드인 경우로 3.9 로 올린 뒤 KRaft 컨트롤러 쿼럼을 띄우고 zookeeper.metadata.migration.enable 을 true 로 두어 마이그레이션을 완료해야 합니다. 3.9 가 마지막 브리지 릴리스이므로 여기서 끝내야 하며 4.0 이상에는 ZooKeeper 경로가 없습니다. 공통 원칙으로 클라이언트를 브로커보다 먼저 올리지 않으며 4.0 이후 브로커는 2.1 이상 클라이언트만 지원합니다. 4.3 으로 가는 업그레이드 경로 — 지금 상태에 따라 셋 중 하나입니다 A. 이미 KRaft · 3.3.x ~ 4.2.x 현재 클러스터 브로커 롤링 재시작 동작·성능 확인 kafka-features.sh upgrade 소프트웨어를 한 대씩 올린 뒤 마지막에 메타데이터 버전을 올립니다. bin/kafka-features.sh --bootstrap-server :9092 upgrade --release-version 4.3 4.3 은 메타데이터 변경이 있어 이 단계 뒤에는 다운그레이드가 불가능합니다. B. KRaft 이지만 3.3.x 보다 낮음 현재 클러스터 3.9.x 로 먼저 4.3 롤링 업그레이드 kafka-features.sh upgrade 공식 문서는 3.3.x 미만 KRaft 클러스터는 3.9.x 를 경유하도록 권합니다. 메타데이터 버전도 최소 3.3 이어야 합니다 — 소프트웨어만 올려서는 부족합니다. C. 아직 ZooKeeper 모드 ZK 모드 클러스터 3.9 로 업그레이드 KRaft 마이그레이션 4.3 롤링 업그레이드 3.9 가 마지막 브리지 릴리스이므로 여기서 마이그레이션을 끝내야 합니다. KRaft 컨트롤러 쿼럼을 먼저 띄우고 zookeeper.metadata.migration.enable=true 로 시작합니다 마이그레이션이 끝난 뒤에야 4.x 로 올릴 수 있습니다. 4.0 이상에는 ZooKeeper 경로가 없습니다. 공통 원칙: 클라이언트는 브로커보다 먼저 올리지 않습니다. 4.0 이후 브로커는 2.1 이상 클라이언트만 지원합니다. 메타데이터 버전을 올리는 마지막 단계는 되돌릴 수 없는 경우가 많습니다 — 충분히 관찰한 뒤 실행합니다.
업그레이드 경로 — 구버전에서 4.x로 올라가는 단계와 최소 경유 버전

미니 퀴즈

쿼럼 사이징 계산과 절차 배열이 중심입니다.

공식 문서 출처