
AI 요약
작은 서비스에서 결제와 알림처럼 서로 알아야 할 것이 늘어나면 복잡해지므로 Kafka로 이벤트를 중앙에 남기고 각 서비스가 필요한 이벤트만 구독하게 하는 구조를 설명합니다. 핵심은 토픽·파티션·오프셋·컨슈머 그룹을 통해 병렬성과 순서, 재처리 지점을 관리하고, Kafka가 메시지 전달을 넘어 이벤트를 저장해 여러 서비스가 독립적으로 활용할 수 있게 해준다는 점입니다.
Kafka를 공부하면서 나중에 또 볼 수 있게 정리하려고 한다.
예시를 주문이 생성되면 결제가 필요하고, 결제가 끝나면 알림을 보내야 한다고 해보자.
처음에는 다음과 같이 구현할 수 있다.
작은 시스템에서는 괜찮다. 하지만 서비스가 늘어나면 주문 서비스가 결제, 알림 서비스의 존재를 모두 알아야 한다.
알림 서비스가 잠시 장애가 나면 주문 처리까지 영향을 받을 수도 있다. 다른 서비스를 새로 추가할 때마다 주문 서비스의 코드를 수정해야 할 수도 있다.
Kafka를 사용하면 흐름이 달라진다.
결제 서비스는 “누가 이 메시지를 처리하는지”를 몰라도 된다. 결제가 성공했다는 사실만 Kafka에 남기면 된다.
이때 Kafka는 결제나 알림을 직접 처리하는 프로그램이 아니다. Kafka는 이벤트를 저장하고 전달하는 중간 시스템이고, 실제 업무는 메시지를 읽은 각 컨슈머가 수행한다.
Kafka 공식 문서도 토픽을 여러 프로듀서와 컨슈머가 사용할 수 있는 이벤트 로그로 설명한다. 이벤트는 컨슈머가 읽었다고 바로 사라지지 않고, 설정된 보존 기간 동안 남아 있다.
Apache Kafka 공식 문서
Kafka를 단순하게 그리면 다음과 같다.
각 단어는 다음을 의미한다.
| 개념 | 의미 |
|---|---|
| Broker | Kafka 서버. 메시지를 저장하고 전달함 |
| Topic | 이벤트를 분류하는 이름 |
| Producer | Kafka에 메시지를 보내는 애플리케이션 |
| Consumer | Kafka에서 메시지를 읽는 애플리케이션 |
이제 하나씩 살펴보자.
토픽은 이벤트를 분류하는 논리적인 이름이다. 실제 이벤트는 브로커가 해당 토픽의 파티션에 저장한다.
01order-created02payment-succeeded결제가 성공하면 payment-succeeded 토픽에 이벤트를 기록할 수 있다.
01payment-succeeded02 03order-101 결제 성공04order-102 결제 성공05order-103 결제 성공토픽은 내부적으로 파티션이라는 저장 단위로 나뉜다.
01payment-succeeded02 03Partition 004 offset 0: order-101 결제 성공05 offset 1: order-103 결제 성공06 07Partition 108 offset 0: order-102 결제 성공파티션을 여러 개로 나누는 이유는 처리량과 병렬성 때문이다.
01Partition 0 → Consumer 102Partition 1 → Consumer 203Partition 2 → Consumer 3다만 Kafka는 전체 토픽의 순서를 보장하지 않는다. 하나의 파티션 안에서만 순서를 보장한다.
주문별 순서가 중요하다면 orderId를 메시지 key로 사용한다.
01order-101 → Partition 002order-101 → Partition 003order-101 → Partition 0그러면 같은 주문의 이벤트를 같은 파티션에 저장해 순서를 유지할 수 있다.
오프셋은 파티션 안에서 메시지의 위치를 나타내는 번호다.
01Partition 002 03offset 0: 주문 생성04offset 1: 결제 성공05offset 2: 배송 시작오프셋은 토픽 전체에서 하나씩 증가하는 번호가 아니다. 파티션마다 별도로 존재한다.
01Partition 0의 offset 002Partition 1의 offset 0컨슈머는 자신이 어디까지 읽었는지를 오프셋으로 관리한다.
01현재까지 처리한 위치: offset 102다음에 읽을 위치: offset 2애플리케이션이 재시작하면 저장된 오프셋을 기준으로 이어서 읽을 수 있다. 새로운 컨슈머 그룹은 자신만의 읽은 위치가 없기 때문에 과거 메시지부터 다시 읽을 수도 있다.
컨슈머 그룹은 메시지를 처리하는 팀의 이름이다.
같은 그룹 안의 컨슈머들은 파티션을 나누어 할당받아 메시지를 처리한다.
01order-service 그룹02 ├─ Consumer A03 └─ Consumer B반대로 그룹이 다르면 같은 메시지를 각각 읽는다.
01payment-succeeded02 ├─ order-service 그룹 → 주문 상태 변경03 └─ notification 그룹 → 알림 발송정리하면 다음과 같다.
01같은 Consumer Group02→ 메시지를 나누어 처리03 04다른 Consumer Group05→ 같은 메시지를 각각 처리이 구조 덕분에 하나의 결제 성공 이벤트를 여러 서비스가 독립적으로 사용할 수 있다.
다음 다섯 가지를 기억하자.
Producer가 Topic 이름을 지정해 Broker에 이벤트를 보낸다.
Broker가 해당 Topic의 Partition에 이벤트를 저장한다.
Consumer Group이 Partition의 메시지를 읽는다.
Offset이 Consumer의 읽은 위치를 기억한다.
Kafka는 단순히 메시지를 전달하는 도구가 아니다. 이벤트를 저장해두고, 여러 서비스가 각자의 목적에 맞게 읽고 처리할 수 있게 해주는 이벤트 스트리밍 플랫폼이다.