백엔드 데이터 인프라 99편 — Kafka 운영 기본 (Topic·Partition·Reassign·Rolling Restart)

2026-05-17백엔드 데이터 인프라

백엔드 데이터 인프라 99편. Kafka 운영 기본 — Topic 생성·수정·삭제, Partition 추가, Partition Reassignment 로 broker 추가·제거, Preferred Leader Election, Rolling Restart, Graceful Shutdown 같은 DevOps 일상 명령을 풀어쓴 학습 노트.

📚 백엔드 데이터 인프라 · 99편 — Kafka 운영 기본 (Topic·Partition·Reassign·Rolling Restart)

이 글은 백엔드 데이터 인프라 시리즈 130편 중 99편이에요. Part 5-4 Configuration 까지 설정 영역을 잡았다면, 이번 99편부터는 Part 5-5 — Operations (6편) 입니다. 첫 글은 Kafka 일상 운영 — Topic(메시지 묶음 단위) 생성부터 Broker(Kafka 서버 한 대) 추가·제거까지 살펴봐요.

Kafka 운영이 어렵게 느껴지는 이유

Kafka 운영은 분산 시스템에서 가장 손이 많이 가는 영역이에요. 도구가 많고 시나리오가 풍부해서 그렇습니다.

첫째, CLI(명령줄 도구) 개수가 30개를 넘어요. kafka-topics·kafka-configs·kafka-reassign-partitions·kafka-consumer-groups·kafka-acls·kafka-storage·kafka-leader-election·... 어느 걸 언제 쓰는지가 첫 관문입니다.

둘째, Partition Reassignment(파티션 재할당) 의 복잡성입니다. broker 를 추가하면 기존 partition 일부를 새 broker 로 옮겨야 하는데, 대량 데이터 이동과 네트워크 부담을 같이 관리해야 해요.

셋째, Rolling Restart(무중단 순차 재시작) 의 정확성이에요. broker 를 한 대씩 재시작하면서 Replication(복제본 동기화) 을 유지하고 Leader(파티션의 쓰기 담당) 재선출을 최소화해야 합니다.

이 글에서 일상 운영 다섯 가지 영역을 한 번에 정리할게요.

1. Topic 운영

생성

$ kafka-topics.sh --bootstrap-server localhost:9092 \
    --create --topic orders \
    --partitions 20 --replication-factor 3 \
    --config retention.ms=604800000

옵션 권장:

  • --partitions = 처음에 충분히 잡아두기 (늘리기만 가능, 줄이기는 안 됨)
  • --replication-factor 3 = 운영 환경 표준
  • --config = topic 별 retention·compression 같은 설정

목록·정보

# 목록
$ kafka-topics.sh --bootstrap-server localhost:9092 --list

# 상세
$ kafka-topics.sh --bootstrap-server localhost:9092 --describe --topic orders

# Under-replicated partitions (운영 모니터링)
$ kafka-topics.sh --bootstrap-server localhost:9092 --describe \
    --under-replicated-partitions

Partition 추가

$ kafka-topics.sh --bootstrap-server localhost:9092 \
    --alter --topic orders --partitions 40

여기서 시험 함정이 하나 있어요 — partition 을 추가해도 기존 메시지는 원래 partition 에 그대로 남아요. 새 메시지부터 재해시되기 때문에 key 기반 순서 보장이 깨질 수 있어서 신중히 다뤄야 합니다.

Config 변경

# 추가/변경
$ kafka-configs.sh --bootstrap-server localhost:9092 \
    --entity-type topics --entity-name orders \
    --alter --add-config "retention.ms=172800000,compression.type=zstd"

# 제거 (default 로)
$ kafka-configs.sh --bootstrap-server localhost:9092 \
    --entity-type topics --entity-name orders \
    --alter --delete-config "retention.ms"

삭제

$ kafka-topics.sh --bootstrap-server localhost:9092 \
    --delete --topic orders

비동기입니다. 실제 삭제는 broker 가 백그라운드에서 처리해요.

2. Consumer Group 운영

그룹 목록

$ kafka-consumer-groups.sh --bootstrap-server localhost:9092 --list

그룹 상태·lag

$ kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
    --describe --group order-workers

GROUP          TOPIC    PARTITION  CURRENT-OFFSET  LOG-END-OFFSET  LAG  CONSUMER-ID
order-workers  orders   0          1234            1240            6    consumer-1-...
order-workers  orders   1          5678            5680            2    consumer-2-...

운영에서 가장 자주 보는 명령이에요. LAG(소비 지연 메시지 수) 가 운영 모니터링의 핵심입니다.

Offset Reset

# 처음부터
$ kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
    --group order-workers --topic orders \
    --reset-offsets --to-earliest --execute

# 끝으로
$ kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
    --group order-workers --topic orders \
    --reset-offsets --to-latest --execute

# 특정 시간
$ kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
    --group order-workers --topic orders \
    --reset-offsets --to-datetime 2026-05-17T00:00:00.000 --execute

# 특정 offset
$ kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
    --group order-workers --topic orders --partition 0 \
    --reset-offsets --to-offset 12345 --execute

운영에서 손에 꼽는 강력한 도구예요. bug 후 재처리나 사고 구간 skip 에 씁니다. 실행 전에 --dry-run 으로 한 번 미리 확인하는 게 안전해요.

그룹 삭제

$ kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
    --delete --group old-workers

활성 consumer 가 있으면 거부됩니다. 모든 consumer 를 종료한 뒤에 실행해야 해요.

3. Partition Reassignment — Broker 추가·제거

시나리오 — Broker 1, 2, 3 → Broker 4 추가

기존 partition 은 Broker 1~3 에만 분포해 있어요. Broker 4 를 추가했다면 기존 partition 일부를 4 로 옮겨야 의미가 있습니다.

Step 1: 현재 partition 분포 확인

# 이전 명령 결과
$ kafka-topics.sh --describe --topic orders
Topic: orders  Partition: 0  Leader: 1  Replicas: 1,2,3  Isr: 1,2,3
Topic: orders  Partition: 1  Leader: 2  Replicas: 2,3,1  Isr: 2,3,1
Topic: orders  Partition: 2  Leader: 3  Replicas: 3,1,2  Isr: 3,1,2

Step 2: Reassignment JSON 생성

topics-to-move.json:

{
  "topics": [{"topic": "orders"}],
  "version": 1
}

자동 생성:

$ kafka-reassign-partitions.sh --bootstrap-server localhost:9092 \
    --topics-to-move-json-file topics-to-move.json \
    --broker-list "1,2,3,4" \
    --generate

Current partition replica assignment
{...}

Proposed partition reassignment configuration
{
  "version":1,
  "partitions":[
    {"topic":"orders","partition":0,"replicas":[4,2,3]},
    ...
  ]
}

Step 3: 실행

reassignment.json 저장 후:

$ kafka-reassign-partitions.sh --bootstrap-server localhost:9092 \
    --reassignment-json-file reassignment.json \
    --execute

여기서부터 대량 데이터 이동이 시작됩니다.

Step 4: 진행 확인

$ kafka-reassign-partitions.sh --bootstrap-server localhost:9092 \
    --reassignment-json-file reassignment.json \
    --verify

Reassignment of partition X is still in progress 또는 complete 가 떠요.

Throttling — 네트워크 부담 제한

대량 이동은 cluster 네트워크와 디스크를 한꺼번에 잡아먹어요. Throttle(전송 속도 제한) 로 막아둡니다.

$ kafka-reassign-partitions.sh --bootstrap-server localhost:9092 \
    --reassignment-json-file reassignment.json \
    --execute --throttle 50000000   # 50 MB/s

운영 환경에서는 필수예요. 안 걸어두면 정상 트래픽이 같이 흔들립니다.

완료 후 throttle 제거:

$ kafka-reassign-partitions.sh --bootstrap-server localhost:9092 \
    --reassignment-json-file reassignment.json \
    --verify   # 자동으로 throttle 제거

4. Preferred Leader Election

문제

Reassignment 후나 broker 재시작 후에 Leader 가 특정 broker 한 곳에 몰리면서 부하가 한쪽으로 쏠릴 때가 있어요.

Topic 생성 시 각 partition 의 첫 replica 가 preferred leader(선호 리더) 로 지정돼요. 정상 운영이라면 이 preferred leader 가 실제 leader 로 자연스럽게 잡혀 있는 상태가 맞습니다.

명령

# 모든 topic 의 preferred leader election
$ kafka-leader-election.sh --bootstrap-server localhost:9092 \
    --election-type preferred --all-topic-partitions

# 특정 topic
$ kafka-leader-election.sh --bootstrap-server localhost:9092 \
    --election-type preferred --topic orders

Auto Leader Rebalance

# server.properties
auto.leader.rebalance.enable=true
leader.imbalance.per.broker.percentage=10
leader.imbalance.check.interval.seconds=300

true (기본) 로 두면 preferred leader 가 자동으로 회복돼요. 대부분 환경에서 이걸로 충분합니다.

5. Rolling Restart — 무중단 재시작

시나리오

설정 변경·security patch·버전 upgrade 같은 작업에서 모든 broker 를 재시작해야 할 때가 와요. 한 번에 다 재시작하면 서비스가 끊기니까 하나씩 순차로 갑니다.

Step 1: Broker 한 대씩

# Broker 1 종료 (graceful)
$ ssh broker-1
$ kafka-server-stop.sh

# 또는 systemd 사용 시
$ sudo systemctl stop kafka

# 재시작
$ kafka-server-start.sh -daemon config/server.properties

# 또는
$ sudo systemctl start kafka

Step 2: 다음 broker 전 확인

# Under-replicated partitions = 0 인지
$ kafka-topics.sh --bootstrap-server localhost:9092 --describe \
    --under-replicated-partitions

--under-replicated-partitions 가 0 으로 떨어졌을 때만 다음 broker 로 넘어가요. 안 그러면 데이터 손실 위험이 따라옵니다.

Step 3: 반복

3 broker cluster 면 3 번 반복이에요. broker 사이에 Replication 이 회복될 시간을 충분히 줘야 합니다.

Graceful Shutdown — 자동 leadership transfer

# server.properties
controlled.shutdown.enable=true             # 기본
controlled.shutdown.max.retries=3

true 면 종료 직전에 leadership 을 다른 replica 로 넘겨줘요. 클라이언트가 받는 영향이 최소화됩니다.

여기가 정말 중요해요 — 항상 controlled shutdown 사용. kill -9 같은 hard kill 은 unclean leader election(동기화 안 된 복제본이 리더가 되는 사고) 위험과 ISR(In-Sync Replicas, 동기화된 복제본 집합) 깨짐을 같이 부릅니다.

6. 자주 쓰는 도구 모음

도구 용도
kafka-topics.sh Topic CRUD
kafka-configs.sh Topic/Broker config
kafka-consumer-groups.sh Consumer group 상태·offset
kafka-reassign-partitions.sh Partition 재할당
kafka-leader-election.sh Leader 재선출
kafka-acls.sh ACL 관리
kafka-storage.sh KRaft 저장소 포맷
kafka-server-start.sh·kafka-server-stop.sh Broker 제어
kafka-console-producer.sh·kafka-console-consumer.sh 디버깅용 메시지 송수신
kafka-dump-log.sh Log segment 분석
kafka-broker-api-versions.sh Broker API 버전 확인
kafka-features.sh Cluster feature 관리
kafka-cluster.sh Cluster 정보

자동화 — Cruise Control

규모가 커지면 수동 reassignment 부담이 빠르게 늘어나요. 그래서 등장한 게 Cruise Control (LinkedIn 오픈소스) 입니다. 자동 partition balancing·dead broker replacement·rolling restart 같은 영역을 묶어서 처리해줘요.

- Broker 추가 → 자동 reassignment 제안 + 실행
- Goal-based optimization (CPU·디스크·네트워크 균형)
- Anomaly detection (lag·throughput drop)

운영 부담이 크게 줄어들어서 broker 수십~수백 대 환경에서는 사실상 표준처럼 쓰입니다.

한계·실무 함정

1. Partition 추가 = key 순서 깨짐

위에서 강조한 부분입니다. 비즈니스 영향을 한 번 평가한 다음에 들어가요.

2. Reassignment 없이 broker 추가

새 broker 가 partition 없이 idle 로 남아요. 반드시 reassignment 까지 같이 돌립니다.

3. Throttle 없이 reassignment

정상 트래픽 영향이 폭증해요. 항상 throttle.

4. Rolling Restart 시 under-replicated 무시

데이터 손실 위험이 생깁니다. 반드시 0 확인 후 진행.

5. Hard kill

controlled.shutdown 을 우회하면 unclean leader election 위험을 끌어옵니다.

6. auto.create.topics.enable=true + 운영

오타 topic 이 폭증해요. 운영 환경 false (94편).

시험 직전 한 번 더 — Kafka 운영 기본 함정 압축 노트

  • Topic 운영 = kafka-topics.sh 로 CRUD + kafka-configs.sh 로 config
  • 생성 권장 = --partitions 충분히 + --replication-factor 3
  • Partition 추가 = 가능, 줄이기 X
  • 추가 시 = 기존 메시지 partition 그대로, key 순서 깨질 수 있음
  • Consumer Group = kafka-consumer-groups.sh --describe 로 LAG 모니터링
  • Offset Reset = --reset-offsets --to-earliest/latest/datetime/offset
  • --dry-run 으로 미리 확인
  • 활성 consumer 있으면 그룹 삭제 거부
  • Partition Reassignment 4단계 = 현재 확인 → JSON 생성 (--generate) → 실행 (--execute --throttle) → 진행 확인 (--verify)
  • Throttle 필수 — 운영 환경에서 안 하면 트래픽 영향
  • Preferred Leader Election = kafka-leader-election.sh 또는 auto.leader.rebalance.enable=true (기본)
  • Rolling Restart — 한 broker 씩 + --under-replicated-partitions = 0 확인 후 다음
  • controlled.shutdown.enable=true (기본) — graceful shutdown, kill -9 절대 금지
  • 도구 모음 = kafka-topics·configs·consumer-groups·reassign-partitions·leader-election·acls·storage·dump-log·features·cluster
  • 대규모 자동화 = Cruise Control (LinkedIn)
  • 자동 balancing·dead broker replacement·anomaly detection
  • 함정 — partition 추가 = key 순서 깨짐
  • 함정 — reassignment 없는 broker 추가 = idle broker
  • 함정 — throttle 없는 reassignment = 트래픽 영향
  • 함정 — under-replicated 무시한 rolling restart = 데이터 손실
  • 함정 — hard kill = unclean leader election 위험

공식 문서: Kafka Operations 에서 자세한 사양과 시나리오를 확인할 수 있어요.

시리즈 다른 편 (앞뒤 글 모음)

이전 글:

다음 글:

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

답글 남기기

error: Content is protected !!