
1. 단순 저장 방식의 문제점
먼저, 전통적인 방식으로 DB나 레디스(Redis)에 바로 저장하는 시스템의 한계를 짚고 넘어가겠습니다.
- 발행 서비스 과부하: 쿠폰을 발행하는 서비스는 쿠폰을 생성함과 동시에 DB에 저장하는 역할을 합니다. 만약 이벤트 등으로 수십만 명이 동시에 쿠폰을 요청하면, 발행 서비스는 물론 DB까지 엄청난 부하가 걸리게 되죠. 이로 인해 시스템이 느려지거나 멈출 수도 있습니다.
- 데이터 유실 가능성: 만약 DB에 접속 장애가 발생하거나 쓰기 작업이 실패하면, 쿠폰 발행 요청은 성공했지만 실제로는 데이터가 저장되지 않는 문제가 발생할 수 있습니다. 이는 사용자에게 큰 불편을 초래하고 신뢰도를 떨어뜨립니다.
- 동시성 문제: 한 명의 사용자가 여러 개의 쿠폰 발급 버튼을 연달아 누르거나, 시스템 오류로 인해 동시에 여러 요청이 들어올 경우, 데이터가 꼬이거나 중복으로 저장될 수 있는 **동시성 문제(Concurrency Issue)**가 발생할 수 있습니다.
2. 카프카 컨슈머를 이용한 저장의 이점
이러한 문제점을 해결하기 위해 메시지 큐의 대표 주자인 카프카를 도입하면, 발행 서비스와 저장 서비스를 분리하여 시스템의 유연성과 안정성을 극대화할 수 있습니다.
1) 시스템 부하 분산 및 발행 서비스의 응답 속도 향상
가장 큰 이점은 발행 서비스가 DB에 직접 접근하지 않아도 된다는 것입니다. 발행 서비스는 단순히 쿠폰 정보를 담은 메시지를 카프카에 보내는 역할만 수행합니다. 카프카는 초당 수십만 건의 메시지를 처리할 수 있을 만큼 빠르기 때문에, 발행 서비스는 DB 부하와 상관없이 매우 빠른 속도로 요청을 처리할 수 있습니다.
발행 서비스는 이제 "쿠폰을 발급하고 저장하는" 역할에서 "쿠폰 발급 요청을 카프카에 전달하는" 역할로 바뀌는 거죠. 저장 작업은 이제 카프카의 컨슈머가 담당합니다.
2) 안정적인 데이터 처리
카프카는 메시지를 큐에 저장하기 때문에, 컨슈머가 메시지를 읽어와서 DB에 저장하는 작업이 실패하더라도 메시지는 사라지지 않습니다. 컨슈머는 실패한 작업을 나중에 다시 시도할 수 있어요. 또한, DB에 장애가 발생하더라도 발행 서비스는 계속해서 카프카에 메시지를 쌓아둘 수 있고, DB가 복구되면 컨슈머가 쌓여있던 메시지를 순차적으로 처리하게 됩니다. 이처럼 데이터 유실을 방지하고 시스템의 안정성을 높일 수 있습니다.
3) 동시성 문제 해결과 병렬 처리
카프카는 **파티션(Partition)**이라는 개념을 통해 동시성 문제를 해결하고 시스템의 처리량(Throughput)을 높입니다.
- 파티션의 순차 처리: 카프카의 토픽은 여러 개의 파티션으로 나눌 수 있고, 각 파티션은 메시지가 추가된 순서를 보장합니다. 한 파티션에 할당된 메시지는 단 하나의 컨슈머만 처리할 수 있습니다. 즉, 한 파티션 내에서는 동시성 문제가 발생하지 않아요.
- 키(Key)를 이용한 동시성 제어: 카프카에 메시지를 보낼 때 **키(Key)**를 지정할 수 있습니다. 같은 키를 가진 메시지는 항상 같은 파티션으로 전송됩니다. 예를 들어, 사용자 ID를 키로 설정하면, 특정 사용자의 모든 쿠폰 발급 요청은 같은 파티션에 들어가 순차적으로 처리됩니다. 이는 한 사용자에 대한 데이터 정합성(Consistency)을 보장하면서도, 다른 사용자의 요청은 다른 파티션에서 병렬로 처리되어 전체 처리 속도는 빨라집니다.
3. 카프카 토픽의 데이터 형태 (스키마)
추가로, 카프카 토픽은 데이터의 형태(스키마)를 강제하지 않는다는 것도 알아두면 좋습니다. 프로듀서와 컨슈머가 바이트 배열(Byte Array) 형태로 데이터를 주고받으며, 데이터의 직렬화(Serialization)와 역직렬화(Deserialization)는 각자 알아서 처리합니다.
하지만 실제 운영 환경에서는 데이터의 일관성을 위해 **스키마 레지스트리(Schema Registry)**를 사용하기도 합니다. 이는 토픽별로 스키마를 중앙에서 관리하여 프로듀서와 컨슈머가 정해진 형태의 데이터를 사용하도록 돕습니다.
마무리하며
결론적으로, 카프카 컨슈머를 이용해 쿠폰을 저장하는 방식은 단순히 데이터를 저장하는 것 이상의 가치를 제공합니다. 시스템의 부하 분산, 안정성 향상, 그리고 동시성 문제 해결이라는 세 마리 토끼를 모두 잡을 수 있기 때문입니다. 이제는 단순한 저장을 넘어, 견고하고 확장성 있는 시스템을 구축하는 것이 중요해진 시대죠.
이러한 기술적 선택이 여러분의 개발 여정에 도움이 되기를 바랍니다!
'데이터베이스 > Kafka' 카테고리의 다른 글
| JsonDeserializer vs ObjectMapper: Kafka에서 왜 JsonDeserializer를 쓸까? (0) | 2025.08.30 |
|---|---|
| Kafka의 Rate Limiting: 클러스터의 안정성을 위한 필수 기능 (0) | 2025.08.30 |
| 메시지 큐와 메시지 브로커 (4) | 2025.08.08 |
| Kafka 이벤트 하나로 여러 액션 처리하는 방법 (1) | 2025.05.10 |