백엔드 데이터 인프라 129편 — Kafka Streams 운영 (Security · Manage · Reset)

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

백엔드 데이터 인프라 129편. Kafka Streams 운영 — SASL_SSL 설정, Internal topic 직접 관리·tuning, kafka-streams-application-reset.sh 로 state 재시작, deploy 전략, version upgrade, 자주 발생하는 운영 사고 패턴까지 풀어쓴 학습 노트. Part 5-10 Streams 마무리.

📚 백엔드 데이터 인프라 · 129편 — Kafka Streams 운영 (Security · Manage · Reset)

이 글은 백엔드 데이터 인프라 시리즈 130편 중 129편이에요. Part 5-10 Kafka Streams 의 마지막 글. 127·128편 까지 IQ·Testing 을 잡았다면, 이번 129편은 Production 운영 — Security·Internal Topics·App Reset·Deploy·Upgrade.

1. Security 설정

113~116편 보안 종합 + Streams 특화:

spring:
  kafka:
    streams:
      application-id: my-streams-app
      properties:
        # SASL_SSL
        security.protocol: SASL_SSL
        sasl.mechanism: SCRAM-SHA-512
        sasl.jaas.config: >
          org.apache.kafka.common.security.scram.ScramLoginModule required
          username="${KAFKA_STREAMS_USER}"
          password="${KAFKA_STREAMS_PASSWORD}";

        # SSL
        ssl.truststore.location: /etc/kafka/ssl/truststore.jks
        ssl.truststore.password: ${TRUSTSTORE_PASSWORD}

        # Internal topic 들도 같은 설정
        producer.security.protocol: SASL_SSL
        producer.sasl.mechanism: SCRAM-SHA-512
        producer.sasl.jaas.config: ${KAFKA_JAAS}
        producer.ssl.truststore.location: /etc/kafka/ssl/truststore.jks

        consumer.security.protocol: SASL_SSL
        consumer.sasl.mechanism: SCRAM-SHA-512
        consumer.sasl.jaas.config: ${KAFKA_JAAS}
        consumer.ssl.truststore.location: /etc/kafka/ssl/truststore.jks

여기서 시험 함정이 하나 있어요 — Streams 가 내부적으로 producer + consumer + admin 모두 사용. 각자 보안 config 명시 필수.

2. ACL 요구사항

ACL(권한 제어 목록)로 Streams app 의 user 에게 줘야 하는 권한:

# Input/output topic
$ kafka-acls.sh --add --allow-principal User:my-streams-user \
    --operation Read --topic input-topic \
    --operation Write --topic output-topic \
    --operation Describe --topic input-topic --topic output-topic

# Internal topics (PREFIXED)
$ kafka-acls.sh --add --allow-principal User:my-streams-user \
    --operation All \
    --topic "my-streams-app-" --resource-pattern-type PREFIXED \
    --group "my-streams-app" \
    --transactional-id "my-streams-app" --resource-pattern-type PREFIXED

# Cluster (IdempotentWrite for EOS)
$ kafka-acls.sh --add --allow-principal User:my-streams-user \
    --operation IdempotentWrite --cluster

application.id prefix 로 PREFIXED ACL 을 걸면 internal topic 권한이 자동으로 따라붙어요. 참고로 EOS(exactly-once semantics, 정확히 한 번 처리)에는 cluster 의 IdempotentWrite 가 필요해요.

3. Internal Topic 직접 관리

Streams 가 자동 생성:

  • <app-id>-<store-name>-changelog (state store backup)
  • <app-id>-<store-name>-repartition (groupBy 후 재partition)

기본 설정 자동:

  • RF = replication.factor (Streams config)
  • Partition = input topic 과 동일
  • cleanup.policy=compact (changelog) / delete (repartition)

운영 권장 — 미리 생성

자동 생성에 의존하지 않고 미리 생성:

$ kafka-topics.sh --create --topic my-streams-app-word-counts-changelog \
    --bootstrap-server localhost:9092 \
    --partitions 8 --replication-factor 3 \
    --config cleanup.policy=compact \
    --config segment.bytes=104857600

장점 — retention·compaction·segment 명시 제어.

Streams 설정 영향

spring:
  kafka:
    streams:
      properties:
        replication.factor: 3
        topic.replication.factor: 3
        min.insync.replicas: 2

        # Internal topic 의 cleanup
        # changelog 는 자동 compact
        # repartition 은 자동 delete (짧은 retention)

4. App Reset Tool

$ kafka-streams-application-reset.sh \
    --bootstrap-server localhost:9092 \
    --application-id my-streams-app \
    --input-topics input-topic \
    --intermediate-topics ... \
    --to-earliest \
    --execute

수행 동작:

  • Consumer group offset reset = --to-earliest (처음부터) 또는 --to-datetime
  • Internal topic 삭제 (repartition 등) + 재생성
  • Local state store 삭제 (옵션)

Step-by-Step

# 1. App 종료
$ kubectl scale deployment my-streams-app --replicas=0

# 2. Reset (dry-run 먼저)
$ kafka-streams-application-reset.sh ... --dry-run
$ kafka-streams-application-reset.sh ... --execute

# 3. Local state 삭제 (각 instance 에서)
$ rm -rf /var/kafka-streams-state/my-streams-app/

# 4. App 재시작
$ kubectl scale deployment my-streams-app --replicas=N

언제 Reset?

  • 로직 변경 + 재처리 필요
  • State corruption 복구
  • 새 환경 deploy + clean start
  • 테스트 후 정리

여기서 정말 중요한 자리 — Reset 전 반드시 app 정지. 실행 중에 돌리면 일관성이 깨져요.

5. Deploy 전략

Rolling Update

# Kubernetes
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1

한 instance 씩 교체해요. num.standby.replicas ≥ 1 에 Cooperative rebalance 를 더하면 무중단이 됩니다.

Blue-Green Deploy (어려움)

Streams 는 같은 application.id 끼리 cluster 를 공유해요. Blue-Green 으로 가려면 다른 application.id 가 되고, 그러면 state 를 새로 빌드해야 합니다.

대신 Rolling update 가 표준.

Canary

소수 instance 만 새 버전. 위험 — state·partition 분담이 두 버전에 걸침. 일반적으로 Streams 는 canary 어려움.

6. Version Upgrade

spring:
  kafka:
    streams:
      properties:
        upgrade.from: "3.5"      # 옛 버전에서 새 버전으로 upgrade

upgrade.from 에 옛 버전을 명시해 두고, 한 차례 rolling restart 한 뒤에 제거합니다.

Major Version Upgrade 절차

1. 모든 instance 가 v3.5
2. `upgrade.from=3.5` 추가 + 새 버전 (v4.0) 으로 rolling restart
3. 모두 v4.0 으로 안정 확인
4. `upgrade.from` 제거 + 다시 rolling restart

7. Manage Internal Topics

Changelog topic 의 Compaction Lag

log.cleaner.dedupe.buffer.size=104857600
log.cleaner.threads=4

Broker 측 cleaner thread 설정이에요. state store 가 커질수록 cleaner 부담도 같이 늘어요.

Retention 조정

$ kafka-configs.sh --alter --entity-type topics \
    --entity-name my-streams-app-store-changelog \
    --add-config "min.cleanable.dirty.ratio=0.1,segment.bytes=104857600"

update 가 잦은 환경이면 compaction 도 더 aggressive 하게 가져가요.

8. 자주 발생하는 운영 사고

Issue 1: Consumer lag 폭증

확인:

$ kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
    --describe --group my-streams-app

원인:

  • Stream thread 부족 → num.stream.threads 늘림
  • Processing latency 큰 외부 호출
  • State store rebuild

대응:

  • Instance 추가
  • num.stream.threads 늘림
  • Standby replicas 늘림

Issue 2: State restore 너무 김

대량 changelog 처리 = 수 시간 가능. 대응:

  • num.standby.replicas ≥ 1 미리 설정
  • changelog topic의 compaction 자주
  • State store cache 키움

Issue 3: Rebalance 폭증

원인:

  • max.poll.interval.ms 초과
  • Pod 자주 재시작
  • GC pause

대응:

  • 87편 rebalance 패턴 + Static Membership
  • group.instance.id 설정
  • GC tuning

Issue 4: Internal topic 폭증

원인:

  • 잘못된 application.id (oldapp + newapp 혼재)
  • Reset 안 한 채 새 app 배포

대응:

  • App Reset Tool
  • Internal topic 수동 삭제

Issue 5: EOS 성능 하강

원인:

  • transaction commit 빈도 높음

대응:

  • commit.interval.ms 늘림 (100 → 1000)
  • Production exception handler 자주 호출 시 root cause 해결

9. 모니터링 — 운영 핵심 메트릭

JMX(Java 관리 확장):

메트릭 목표
stream-thread-metrics:process-rate 일정 throughput
stream-task-metrics:commit-rate 1초당 1+
Consumer lag < 1000 (실시간 환경)
state-store:put-rate 일정
state-restoration:restore-rate 재시작 시만 활성
record-error-rate 0

Grafana 대시보드 (공개 dashboard 활용).

10. Production Checklist

배포 전:

  • [ ] application.id cluster unique
  • [ ] EOS V2 활성 (processing.guarantee=exactly_once_v2)
  • [ ] num.standby.replicas ≥ 1
  • [ ] Replication factor 3 + min.insync 2
  • [ ] Error handlers 명시 (Uncaught·Deserialization·Production)
  • [ ] State dir 영구 경로 (/var/...)
  • [ ] SASL_SSL + ACL
  • [ ] group.instance.id (Static Membership)
  • [ ] Internal topics RF 3
  • [ ] Monitoring·alerting (JMX·Grafana)
  • [ ] Health check (/actuator/health)
  • [ ] App Reset 절차 문서화

Part 5-10 Streams 마무리

9편 (121~129):

  • 121 Intro — 정체성·KStream/KTable
  • 122 Quickstart — WordCount hands-on
  • 123 Core Concepts — Topology·Task·Thread·Partition
  • 124 Write & Run — Spring Boot·Error Handler·운영
  • 125 DSL — filter·map·groupBy·join·window
  • 126 Processor API — Low-level·Punctuator·State Store
  • 127 Stateful + IQ — Interactive Queries·HTTP endpoint
  • 128 Testing — TopologyTestDriver·EmbeddedKafka
  • 129 운영 — Security·Manage·Reset·Deploy

Kafka Streams 의 모든 영역. 입문부터 운영까지.

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

  • Security = SASL_SSL + SCRAM-SHA-512, producer/consumer/admin 모두 설정
  • ACL = input/output Topic + Internal topics (PREFIXED) + Group + TransactionalId + Cluster (IdempotentWrite for EOS)
  • Internal Topics = <app-id>-<store>-changelog/repartition 자동
  • 운영 권장 = 미리 생성 (retention·compaction 명시)
  • replication.factor: 3 + min.insync.replicas: 2
  • App Reset Tool = kafka-streams-application-reset.sh
  • 동작 = consumer group offset reset + internal topic 삭제·재생성 + local state 삭제 (옵션)
  • 반드시 app 정지 후 실행
  • Rolling Update = num.standby.replicas ≥ 1 + Cooperative rebalance
  • Blue-Green X (application.id 같으면 state 공유)
  • Canary 어려움
  • Version Upgrade = upgrade.from 추가 + 새 버전 rolling restart + 제거 + 다시 rolling
  • 자주 사고 — Consumer lag·State restore 길음·Rebalance storm·Internal topic 폭증·EOS 성능
  • Production Checklist — application.id unique·EOS V2·standby ≥ 1·RF 3·Error handlers·state dir 영구·SASL_SSL·ACL·group.instance.id·Internal RF 3·monitoring·health check
  • 모니터링 — process-rate·commit-rate·consumer lag·state put-rate·restore-rate·error-rate
  • Part 5-10 Streams 9편 = Intro·Quickstart·Core Concepts·Write/Run·DSL·Processor·Stateful/IQ·Testing·운영

공식 문서: Kafka Streams Manage Streams Application 에서 자세한 운영 사양을 확인할 수 있어요.

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

이전 글:

다음 글:

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

답글 남기기

error: Content is protected !!