백엔드 데이터 인프라 101편. Kafka Multi-tenancy — 여러 팀·서비스가 같은 cluster 공유. Topic Naming Convention·Producer/Consumer Quota·ACL 분리·Resource Limit·Tenant Isolation 패턴까지 풀어쓴 학습 노트.
이 글은 백엔드 데이터 인프라 시리즈 130편 중 101편이에요. 100편 까지 모니터링을 잡았다면, 이번 101편은 조직 규모 운영의 핵심인 Multi-tenancy(여러 사용자가 한 시스템을 공유) 차례예요. 여러 팀·서비스가 같은 Kafka cluster 를 함께 쓸 때 어떤 표준 패턴이 필요한지 정리할게요.
Multi-tenancy가 어렵게 느껴지는 이유
회사가 커지면 팀마다 별도 cluster 를 두는 건 비현실적이에요. 하나의 cluster 를 안전하게 공유하는 방법이 필요한데, 다음 4가지 영역이 한꺼번에 얽혀요.
첫째, Naming 으로 어떤 topic 이 어느 팀 소속인지 식별해야 해요.
둘째, Quota(자원 사용량 제한) 로 한 팀이 cluster 자원을 독점하지 못하게 막아야 해요.
셋째, ACL(Access Control List, 접근 권한 목록) 로 다른 팀 topic 에 접근하지 못하게 통제해요.
넷째, Isolation 정도 — 완전 격리할지 부분 공유할지 결정해야 해요.
이 글에서 Multi-tenancy 의 4가지 영역과 실무 패턴을 풀어볼게요.
1. Topic Naming Convention
가장 단순하면서 가장 중요한 영역이에요. 컨벤션이 없으면 카오스가 와요.
권장 패턴
{env}.{team}.{domain}.{event-type}[.v{version}]
예제:
prod.order-team.orders.created
prod.order-team.orders.completed
prod.payment-team.payments.received
prod.payment-team.payments.refunded
dev.user-team.users.signup.v2
요소:
{env}—prod·staging·dev{team}— 팀 식별자 (order-team){domain}— 도메인 영역 (orders·payments){event-type}— 이벤트 종류 (created·completed){version}— 스키마 진화 시
여기서 시험 함정이 하나 있어요 — Topic 이름은 한 번 정하면 바꾸기 매우 어렵습니다. Topic rename 명령이 따로 없어서, 새 topic 을 만들고 producer/consumer 를 이전하는 복잡한 마이그레이션이 필요해요. 그래서 처음에 컨벤션을 신중히 잡아야 해요.
다른 패턴
- Confluent 권장:
{ENV}.{COMPANY}.{TEAM}.{DOMAIN}(Pascal case) - 이벤트 중심:
{event}_{source}_{schema-version}(OrderCreated_OrderService_v1) - Slack 의 예:
{tier}.{source}.{event}(tier1.checkout.payment-success)
회사 규모·문화에 맞게 하나로 고정해서 가져가는 게 좋아요.
2. Producer Quota — 처리량 제한
한 팀의 producer 가 cluster 전체 처리량을 독점하지 못하게 막는 장치예요.
적용 단위
- per user (ACL 환경)
- per client.id
- per (user, client.id)
설정
# 특정 사용자에 quota 적용 (15 MB/s)
$ kafka-configs.sh --bootstrap-server localhost:9092 \
--alter --add-config 'producer_byte_rate=15728640' \
--entity-type users --entity-name app-user
# client.id 기반
$ kafka-configs.sh --bootstrap-server localhost:9092 \
--alter --add-config 'producer_byte_rate=15728640' \
--entity-type clients --entity-name order-producer
# default (모든 사용자)
$ kafka-configs.sh --bootstrap-server localhost:9092 \
--alter --add-config 'producer_byte_rate=10485760' \
--entity-type users --entity-default
동작 — Throttling
Throttling(요청 속도를 강제로 늦추는 동작) 은 quota 를 넘은 클라이언트의 응답에 broker 가 throttle delay 를 끼워 보내는 방식으로 일어나요. Producer client 는 그만큼 기다렸다 다시 보내요.
quota: 10 MB/s
producer 가 20 MB/s 시도
→ broker 가 throttle_time_ms 50% delay 응답
→ producer 가 자동으로 속도 절반으로 조정
거부가 아니라 속도 제한이라서 메시지 손실은 없어요.
Spring Boot Producer 에 client.id
spring:
kafka:
producer:
client-id: ${spring.application.name}
애플리케이션마다 별도 client.id 를 쓰면 별도 quota 를 걸 수 있어요.
3. Consumer Quota
같은 패턴으로 fetch 처리량을 제한해요.
$ kafka-configs.sh --bootstrap-server localhost:9092 \
--alter --add-config 'consumer_byte_rate=20971520' \
--entity-type users --entity-name analytics-user
대량 batch consumer (예를 들어 ML 학습용) 는 일반 consumer 와 분리된 quota 를 받게 두는 게 좋아요.
4. Request Quota — CPU 제한
위 두 quota 는 network bandwidth 를 다뤘다면, Request Quota 는 broker 의 CPU 사용률을 제한해요.
$ kafka-configs.sh --bootstrap-server localhost:9092 \
--alter --add-config 'request_percentage=50' \
--entity-type users --entity-name app-user
50 은 broker CPU 의 50% 한계를 뜻하고, 0~100 (%) 범위로 잡아요.
소수의 nasty client 가 broker CPU 를 독점하는 사고를 막아 줘요.
5. Quota 조회
$ kafka-configs.sh --bootstrap-server localhost:9092 \
--describe --entity-type users --entity-name app-user
Configs for user-principal 'app-user' are
producer_byte_rate=15728640
consumer_byte_rate=20971520
request_percentage=30
6. ACL 분리 — Team 단위
116편에서 ACL 을 깊이 다뤘는데, Multi-tenancy 의 핵심 패턴은 이거예요.
# order-team 만 prod.order-team.* 에 read/write
$ kafka-acls.sh --bootstrap-server localhost:9092 \
--add --allow-principal User:order-team-app \
--operation All \
--topic 'prod.order-team.' --resource-pattern-type PREFIXED
# payment-team 은 prod.order-team 에 read-only (옵션)
$ kafka-acls.sh --bootstrap-server localhost:9092 \
--add --allow-principal User:payment-team-app \
--operation Read \
--topic 'prod.order-team.orders.completed' --resource-pattern-type LITERAL
PREFIXED resource pattern(접두사가 일치하는 모든 리소스에 한꺼번에 권한) 으로 잡으면 접두사가 맞는 모든 topic 에 권한이 걸려서, 새 topic 을 추가해도 ACL 을 다시 손볼 필요가 없어요.
7. Tenant Isolation 수준
Level 1: Shared Cluster (가장 흔함)
[order-team] ─┐
[payment-team] ├─→ Single Kafka Cluster
[user-team] ─┘
비용이 낮고 운영 부담도 낮은 대신 격리도 낮아요.
Level 2: 부분 격리 — 별도 broker pool
[order-team, payment-team] → Broker Group A (5 brokers)
[user-team, analytics-team] → Broker Group B (3 brokers)
같은 cluster 안이지만 partition 을 특정 broker 에만 배치해요. Rack-aware replica placement 를 활용하면 돼요.
Level 3: 완전 격리 — 별도 cluster
[order-team] → Kafka Cluster A
[payment-team] → Kafka Cluster B
[analytics] → Kafka Cluster C
비용·운영 부담이 올라가는 대신 장애·security·성능을 모두 떼어낼 수 있어요.
대규모 환경에서는 중요한 영역만 별도 cluster 로 빼고 나머지는 공유로 가는 Hybrid 구성을 많이 써요.
8. Resource Limit — Cluster 보호
Topic 수 제한
기본은 무제한이에요. 너무 많은 topic 을 만들면 broker 의 메모리와 파일 디스크립터가 폭증해요.
운영에서는 수동 review 와 ticketing process 를 같이 둬요. 어느 팀이 topic 을 만들면 SRE 가 승인하는 식이죠.
Partition 수 제한
비슷한 이슈예요. partition 이 1만 개를 넘어가면 controller 가 부담을 받아요.
Topic Configuration Limit
특정 설정에 최댓값을 걸어요.
# server.properties
log.retention.bytes.max=1099511627776 # 1TB max per partition
회사 단위 quota 를 운영하는 방식이에요.
9. Naming + ACL + Quota 통합 패턴
운영 표준은 다음 흐름이에요.
# 1. 새 팀 onboarding
TEAM=order-team
ENV=prod
# 2. SASL user 생성
$ kafka-configs.sh --bootstrap-server localhost:9092 \
--alter --add-config 'SCRAM-SHA-512=[iterations=8192,password=...]' \
--entity-type users --entity-name ${TEAM}-app
# 3. ACL 부여 (PREFIXED)
$ kafka-acls.sh --bootstrap-server localhost:9092 \
--add --allow-principal User:${TEAM}-app \
--operation All \
--topic "${ENV}.${TEAM}." --resource-pattern-type PREFIXED
# 4. Consumer Group ACL
$ kafka-acls.sh --bootstrap-server localhost:9092 \
--add --allow-principal User:${TEAM}-app \
--operation All \
--group "${ENV}.${TEAM}." --resource-pattern-type PREFIXED
# 5. Quota 부여
$ kafka-configs.sh --bootstrap-server localhost:9092 \
--alter --add-config 'producer_byte_rate=20971520,consumer_byte_rate=20971520,request_percentage=30' \
--entity-type users --entity-name ${TEAM}-app
SASL(Simple Authentication and Security Layer, 사용자 인증 프로토콜) 사용자 생성 → ACL → Quota 까지 이어지는 흐름을 스크립트로 묶으면 표준 onboarding 을 자동화할 수 있어요.
10. 모니터링 — Per-Tenant
JMX(Java Management Extensions, 자바 애플리케이션 모니터링용 표준) 메트릭이 client.id 와 user 별로 쪼개져 나와요.
kafka.server:type=Produce,user=order-team-app,client-id=order-service-1
kafka.server:type=Fetch,user=order-team-app,client-id=order-worker-1
Grafana 대시보드에서 팀별 throughput 과 error rate 를 따로 볼 수 있어요.
11. 자주 일어나는 운영 사고
1. Quota 없이 새 producer 폭주
신규 팀 onboarding 때 quota 를 빠뜨리면 한 producer 가 cluster 전체를 차지해요. 그래서 표준 onboarding 스크립트를 꼭 갖춰야 해요.
2. Naming 컨벤션 위반
임의로 topic 을 만들기 시작하면 카오스로 가요. auto.create.topics.enable=false 와 ACL 로 차단해 둬야 해요.
3. ACL 너무 풀어 줌
귀찮다고 모든 팀에 모든 권한을 주면 Multi-tenancy 의 의미가 없어져요. 최소 권한 원칙을 지키는 게 기본이에요.
4. Quota 너무 낮음
Throttle 이 폭증하면 정상 트래픽까지 영향을 받아요. 합리적인 quota 를 잡고, 바꿀 때도 점진적으로 가야 해요.
5. Topic 수 폭증
환경·팀·이벤트마다 topic 을 만들다 보면 수만 개까지 늘어날 수 있어요. 주기적으로 cleanup 을 돌려야 해요.
12. Confluent / SaaS 의 Multi-tenancy
Confluent Cloud, AWS MSK, Azure Event Hubs 같은 SaaS 는 multi-tenant 가 기본 운영 모델이에요. 전용 cluster 로 쓸지 공유 cluster 로 쓸지 옵션을 골라요.
- Dedicated cluster = 비용 ↑, 완전 격리
- Standard (shared underlay) = 비용 ↓, 약간 격리
시험 직전 한 번 더 — Kafka Multi-tenancy 함정 압축 노트
- 4가지 영역 = Naming · Quota · ACL · Isolation 수준
- Naming Convention =
{env}.{team}.{domain}.{event-type}[.v{N}] - Topic rename 불가 → 처음 컨벤션 신중
- Producer Quota =
producer_byte_rate(per user·client.id) - Consumer Quota =
consumer_byte_rate - Request Quota =
request_percentage(CPU 제한) - Quota 초과 = throttling (delay, 거부 X)
- 적용 단위 = user·client.id·(user, client.id)·default
- 조회 =
kafka-configs.sh --describe --entity-type users - ACL 분리 =
--resource-pattern-type PREFIXED로 접두사 권한 - 새 topic 추가 시 ACL 추가 불필요 (PREFIXED 매칭)
- Tenant Isolation 3 Level — Shared (가장 흔함) · 부분 격리 (broker pool) · 완전 격리 (별도 cluster)
- 대규모 = Hybrid (중요 영역만 별도 + 나머지 공유)
- Resource Limit = topic 수·partition 수 (수동 review + ticketing)
- 표준 onboarding 패턴 = SASL user 생성 + ACL (PREFIXED) + Quota 설정 스크립트화
- 모니터링 = JMX 가 user·client.id 별 분해 → Grafana 대시보드 팀별
- 함정 — Quota 없는 onboarding 으로 cluster 차지
- 함정 — Naming 컨벤션 위반 카오스
- 함정 — ACL 너무 풀어 줌
- 함정 — Quota 너무 낮음
- 함정 — Topic 수 폭증
- SaaS (Confluent Cloud·MSK·Event Hubs) = multi-tenant 가 기본
공식 문서: Kafka Multi-tenancy 에서 자세한 패턴을 확인할 수 있어요.
시리즈 다른 편 (앞뒤 글 모음)
이전 글:
- 96편 — Kafka Producer 설정 20가지 (Batching · Retries · Idempotence)
- 97편 — Kafka Consumer 설정 25가지 (Group · Commit · Fetch)
- 98편 — Kafka Admin Client 설정 (간결 정리)
- 99편 — Kafka 운영 기본 (Topic·Partition·Reassign·Rolling Restart)
- 100편 — Kafka Monitoring (JMX 메트릭 30가지)
다음 글: