Kafka 토픽의 키(key) 설정

GarionNachal·2026년 1월 25일

kafka

목록 보기
17/23

Kafka에서 키(key) 는 단순한 “식별자”가 아니라, (1) 어떤 파티션에 저장될지(2) 그 파티션 내부에서 순서가 어떻게 보장될지를 결정하는 핵심 설계 포인트입니다. 같은 키는 같은 파티션으로 라우팅되므로, 키 전략을 잘못 잡으면 핫 파티션(쏠림), 처리량 병목, 확장 시 재파티셔닝 비용이 크게 발생합니다. Source


목차

  1. 키가 실제로 하는 일
  2. 키 전략을 정하기 전에 답해야 할 질문
  3. 대표 키 전략 6가지
  4. Java Producer에서 키 적용 패턴
  5. MSK 관점(운영/확장)에서의 키 설계 체크리스트
  6. 실전 추천 레시피
  7. 참고 자료

키가 실제로 하는 일

1) “같은 키 → 같은 파티션” (정렬/순서 보장 단위)

Kafka는 키를 해시해서 특정 파티션을 선택합니다. 그 결과 같은 키로 보낸 레코드들은 같은 파티션에 들어가고, 소비 시에도 그 파티션 내부 순서가 유지됩니다(단, “전체 토픽” 단위 순서는 보장되지 않음). Source

2) 기본 파티셔닝은 murmur2 해시 + mod

Java 클라이언트의 기본 파티셔너는 (키가 있을 때) 32-bit murmur2 해시를 만들고 파티션 수로 mod 해서 파티션을 결정합니다. Source

즉, 파티션 수가 바뀌면(파티션 추가) 키→파티션 매핑이 대거 재배치될 수 있습니다.


키 전략을 정하기 전에 답해야 할 질문

키를 고르기 전에 아래 3가지를 먼저 확정하는 게 안전합니다.

1) 순서 보장이 필요한 “범위”가 무엇인가?

  • 주문 단위? (orderId)
  • 사용자 단위? (userId)
  • 계좌 단위? (accountId)
  • 전역 순서? (가능하지만 거의 항상 비용이 큼: 파티션 1개로 수렴)

2) 처리량/병렬성이 얼마나 필요한가?

  • 파티션 수는 병렬성을 의미하지만, 키가 특정 값에 몰리면 병렬성은 무너집니다(핫 파티션).

3) “쏠림(스큐)”을 얼마나 허용할 수 있나?

  • 상위 1% 키가 50% 트래픽을 만드는 패턴(예: 유명 셀러, 대형 고객, 특정 디바이스)은 매우 흔합니다.

대표 키 전략 6가지

전략 A. 엔티티 ID 키 (가장 흔함)

  • 예: userId, orderId, accountId
  • 장점: 해당 엔티티 단위 순서가 깔끔
  • 단점: 상위 엔티티가 트래픽을 독점하면 핫 파티션

Kafka 키가 “관련 메시지를 같은 파티션으로 모아 순서를 보장”한다는 점 때문에 가장 기본 전략입니다. Source


전략 B. 복합 키(Composite Key)

  • 예: tenantId:userId, storeId:orderId
  • 장점: 멀티테넌시/도메인 경계를 깔끔히 분리하면서도 엔티티 순서 확보
  • 단점: 키 설계가 복잡해지고, 조인/집계 시 기준이 흔들릴 수 있음

전략 C. “샤딩된 키” (핫 키 완화용)

  • 예: orderId#0..N, userId#bucket
  • 목적: 한 엔티티에 트래픽이 몰리는 것을 인위적으로 분산
  • trade-off: 엔티티 단위 “완전한 순서”는 깨질 수 있음(혹은 애플리케이션이 재정렬/집계를 해야 함)

“순서”와 “처리량”을 동시에 잡을 수 없는 경우가 많아서, 이 전략은 중급 이상에서 매우 자주 씁니다.


전략 D. 시간 기반 키(비추천이 많은데, 특정 경우 유효)

  • 예: yyyyMMddHH 같은 시간 키
  • 장점: 특정 시간대 배치/집계가 쉬움
  • 단점: 시간대별로 트래픽이 몰리면 핫 파티션, 시간 경계에서 파티션 이동 발생 가능

전략 E. null 키(키 없음)

키가 없으면 파티션에 고르게 분산(라운드로빈/스티키 계열 동작)되어 처리량에 유리하지만, 관련 메시지 순서/그룹핑 보장이 약해집니다. Source

MSK 운영 관점에서도 “키 없이 분산되는 트래픽”은 스케일 아웃에 유리할 수 있습니다(단, 소비 로직이 순서를 요구하지 않아야). Source


전략 F. 커스텀 파티셔너(정말 필요할 때만)

기본 파티셔너가 murmur2 기반이라는 점을 이해하고도, 도메인 요구(특정 파티션 고정, 특정 라우팅 룰 등) 때문에 커스텀을 씁니다. 다만 운영 복잡도가 올라가고, producer 다양성(다른 언어/라이브러리)까지 고려해야 합니다. Source


Java Producer에서 키 적용 패턴

1) 가장 기본: String 키 사용

ProducerRecord<String, String> record =
    new ProducerRecord<>("orders", orderId, payloadJson);

producer.send(record);
  • orderId가 같으면 같은 파티션으로 라우팅됩니다. Source

2) “핫 키” 완화: 샤딩된 키

int shard = Math.floorMod(orderId.hashCode(), 16); // 16-way shard
String key = orderId + "#" + shard;

ProducerRecord<String, String> record =
    new ProducerRecord<>("orders", key, payloadJson);
producer.send(record);
  • 순서 요구를 “orderId 전체”가 아니라 “orderId#shard 단위”로 낮추는 대신 처리량을 확보합니다.

MSK 관점(운영/확장)에서의 키 설계 체크리스트

1) “파티션 수 = 병렬성”이지만, 키 스큐가 있으면 무의미

MSK에서 브로커/파티션을 늘려도, 특정 키가 한 파티션을 독점하면 해당 파티션의 리더 브로커 CPU가 먼저 차고 지연이 발생합니다. MSK는 CPU 60% 이하 유지 등을 권장하며, 부하 분산(파티션/브로커 밸런싱)이 운영 안정성에 중요합니다. Source

2) 파티션이 너무 많아도 운영 리스크

MSK 문서에서도 브로커 사이즈별 “권장 파티션 수(리더+팔로워 포함)” 가이드가 있으며, 파티션 과다 시 업데이트/메트릭 누락 등의 문제가 생길 수 있음을 명시합니다. Source

3) 파티션 추가(스케일 아웃) 시 키→파티션 매핑 변화

기본 파티셔닝이 hash(key) % partitionCount이기 때문에, 파티션 수 변경은 대규모 재매핑을 유발할 수 있습니다. Source


실전 추천 레시피

레시피 1) “주문 이벤트” 스트림

  • 순서: 주문(orderId) 단위로 필요
  • 추천 키: orderId
  • 주의: 특정 주문이 초고트래픽(드물지만 가능)이면 orderId#shard로 전환 고려

레시피 2) 멀티테넌트 SaaS 이벤트

  • 순서: tenant 단위 or tenant+user 단위
  • 추천 키: tenantId:userId (또는 tenantId:entityId)
  • 장점: 테넌트 격리 + 엔티티 순서 확보

레시피 3) “순서 중요하지 않음 / 최대 처리량”

  • 추천: null 키(키 없음)
  • 전제: 소비 로직이 out-of-order를 허용해야 함
    키가 없을 때 분산은 처리량에 유리하지만, 관련 메시지 순서/그룹핑을 잃습니다. Source

글 중간에 넣을 이미지(출처 포함)

아래 이미지는 본문 중간에 그대로 삽입해서 쓰기 좋습니다.

1) Kafka 파티션 개념(다이어그램)
What are partitions? | Kafka 101
Source

2) Kafka Keys/Ordering 관련 시각자료(키-파티션-순서 맥락)
Kafka Keys, Partitions and Message Ordering
Source


참고 자료

  • Kafka message key 개념 및 효과(같은 키→같은 파티션, 순서 보장) Confluent
  • Kafka partition key/해시/스큐 등 설계 포인트 Confluent
  • Java 기본 파티셔너(32-bit murmur2 + mod) The Internals of Apache Kafka
  • MSK 운영 베스트 프랙티스(파티션/브로커 사이징, CPU, 운영 제약) AWS Docs
profile
AI를 꿈꾸는 BackEnd개발자

0개의 댓글