Kafka 핵심 개념부터 실무에서 놓치기 쉬운 주의사항까지

궁금하면 500원·2024년 7월 16일

MSA&아키텍처

목록 보기
12/47

Kafka 실시간 데이터 스트리밍의 심장

Apache Kafka는 단순한 메시지 큐를 넘어, 대규모 데이터 스트리밍과 실시간 처리를 위해 설계된 분산 이벤트 스트리밍 플랫폼입니다.
쉽게 말해 데이터라는 '이벤트'가 발생했을 때, 이를 안전하게 적재하고 필요한 곳으로 빠르게 전달하는 중추 역할을 합니다.

1. 토픽과 파티션

토픽

Kafka에서 데이터가 저장되는 논리적인 단위입니다.
파일 시스템의 '폴더'와 유사하며, 프로듀서는 특정 토픽에 데이터를 밀어넣고, 컨슈머는 원하는 토픽을 구독하여 데이터를 가져갑니다.

파티션

토픽을 물리적으로 나눈 최소 저장 단위입니다.

  • 병렬 처리의 핵심: 파티션이 여러 개일수록 여러 컨슈머가 동시에 데이터를 처리할 수 있어 성능이 비약적으로 향상됩니다.
  • 분산 저장: 여러 브로커에 파티션을 분산시켜 저장함으로써 한 서버가 다운되어도 데이터 유실을 방지합니다.

주의할 점: 순서 보장 문제
Kafka는 파티션 내부에서만 메시지 순서를 보장합니다.
만약 토픽에 파티션이 3개라면, 전체 데이터의 소비 순서는 프로듀서가 보낸 순서와 다를 수 있습니다.
순서가 절대적으로 중요하다면 메시지 키를 활용해 특정 파티션에만 데이터를 몰아넣거나, 단일 파티션을 사용해야 합니다.


2. 프로듀서: 데이터의 공급자

프로듀서는 우체통에 편지를 넣는 우체부처럼, 생성된 데이터를 Kafka 브로커로 전송합니다.

  • 메시지 키 활용: 키를 지정하면 해시 알고리즘에 의해 특정 파티션으로 데이터가 고정됩니다.
    예를 들어 user_id를 키로 쓰면 특정 사용자의 이벤트는 항상 같은 파티션에 쌓여 순서가 유지됩니다.

데이터 유실과 "Hot Partition"

  1. Hot Partition: 특정 키에 데이터가 몰릴 경우, 특정 파티션만 과부하가 걸려 전체 시스템 성능이 저하될 수 있습니다.
  2. 트랜잭션 불일치: 작성해주신 코드처럼 DB 저장과 Kafka 전송이 별도로 일어날 때 문제가 생깁니다.
@Async
fun publishEvent(event: UserCreatedEvent) {
    // DB 트랜잭션은 성공했지만, 여기서 네트워크 장애가 발생한다면?
    // 혹은 서비스가 갑자기 종료된다면? -> 데이터 누락 발생!
    kafkaPublisher.send("user-topic", event.userId.toString(), event)
}
  • Solution: 이를 방지하기 위해 Transactional Outbox Pattern을 사용하거나, DB 트랜잭션과 Kafka 발행을 하나로 묶는 Kafka 트랜잭션 기능을 고려해야 합니다.

3. 컨슈머 데이터의 소비자

컨슈머는 토픽의 파티션으로부터 데이터를 Pull 방식으로 가져와 처리합니다.

  • 컨슈머 그룹: 여러 컨슈머를 하나의 그룹으로 묶으면, Kafka가 자동으로 파티션을 컨슈머들에게 분배합니다.
    이를 통해 대용량 데이터를 병렬로 빠르게 처리할 수 있습니다.

중복 처리와 오프셋

  1. 멱등성 확보: 네트워크 일시 오류로 프로듀서가 같은 메시지를 두 번 보낼 수 있습니다. 컨슈머는 동일한 메시지를 여러 번 받아도 문제가 없도록 설계해야 합니다
    (예: DB의 Unique Key 활용).

  2. 커밋 시점의 딜레마:

  • Auto Commit: 데이터를 가져오자마자 처리 성공 여부와 상관없이 읽었다고 표시합니다. 처리 중 에러가 나면 데이터가 유실될 수 있습니다.

  • Manual Commit: 처리가 완전히 끝난 뒤에 "다 읽었음"을 알립니다.
    처리 중 에러가 나면 재시도할 수 있지만, 중복 처리가 발생할 가능성이 높습니다.


4. 왜 Kafka를 써야 할까?

단순한 API 호출 대신 Kafka를 사용하는 이유는 결합도를 낮추고 시스템 안정성을 높이기 위함입니다.

비교 항목전통적인 API호출Kafka 기반 이벤트 스트리밍
의존성호출 대상 서버가 떠 있어야 함상대 서버 상태와 상관없이 발행 가능
응답성결과가 올 때까지 대기발행 후 즉시 다음 작업 수행
확장성수신 서버 부하 시 직접 타격컨슈머만 늘려서 처리량 조절 가능

회원가입 시나리오

  1. Member 서비스: 회원 정보를 DB에 저장하고 UserCreated 이벤트를 Kafka에 던집니다.
  2. Coupon 서비스: 해당 이벤트를 구독하여 쿠폰을 발급합니다.
  3. Mail 서비스: 해당 이벤트를 구독하여 환영 메일을 보냅니다.
  • 장점: 메일 서버가 점검 중이라도 Kafka에 이벤트가 쌓여 있으므로, 점검이 끝나면 자동으로 메일이 발송됩니다. 회원가입 로직이 메일 서버의 장애에 영향을 받지 않습니다.

💡 마치며

Kafka를 처음 접했을 때는 단순히 "빠른 메시지 전달 도구"라고만 생각했습니다.
하지만 학습을 깊게 진행할수록 '성능'과 '신뢰성' 사이의 정교한 트레이드오프를 끊임없이 고민해야 하는 플랫폼이라는 점을 깨달았습니다.

특히 파티션 설계를 어떻게 하느냐에 따라 처리 속도가 수십 배 차이 날 수도 있지만, 동시에 순서 보장이라는 까다로운 숙제를 해결해야 한다는 점이 흥미로웠습니다.
또한, 단순한 API 호출보다 시스템 간의 결합도를 낮춰주지만, 그만큼 인프라 관리의 복잡도와 분산 시스템 특유의 예외 처리에 더 많은 신경을 써야 한다는 것을 배웠습니다.

profile
에러가 나도 괜찮아 — 그건 내가 배우고 있다는 증거야.

0개의 댓글