AWS 기술 블로그
엠넷플러스 실시간 글로벌 투표 시스템 아키텍처 개선 사례
소개


엠넷플러스(Mnet Plus)는 CJ ENM이 운영하는 글로벌 K-POP 콘텐츠 플랫폼으로, 론칭 3년 만에 글로벌 누적 가입자 수 4,500만 명, 최대 월간 활성 이용자 수(MAU) 2,000만 명을 돌파하며 빠르게 성장하고 있습니다.
MAMA AWARDS, KCON, 보이즈 2 플래닛 등 다양한 Mnet 콘텐츠는 물론, 숨바꼭질, 온더맵 등 엠넷플러스 오리지널 콘텐츠까지 아우르며 글로벌 팬들에게 라이브 스트리밍과 VOD 서비스를 제공하고 있습니다. 엠넷플러스는 단순한 시청을 넘어, 팬들이 참여와 경험을 통해 결과를 함께 만들어가는 구조를 지향합니다. 실시간 투표와 다양한 참여 기능을 통해 팬들은 콘텐츠의 흐름과 결과에 영향을 미치며, 아티스트의 성장 과정에 함께 합니다.
특히 엠넷플러스의 투표 기능은 MAMA AWARDS 시상식 투표, 보이즈 2 플래닛과 같은 서바이벌 프로그램의 데뷔조 선발 등 프로그램의 결과에 직결되는 핵심 기능입니다. 투표 결과는 방송 및 콘텐츠 전개에 반영되므로, 신뢰성과 안정성이 무엇보다 중요합니다.
투표 서비스는 짧은 시간 동안 글로벌 다수 사용자가 동시에 참여하는 특성을 가지며, 데이터 유실이나 서비스 중단이 허용되지 않는 핵심 서비스(Critical Service)에 해당합니다. 일부 부가 기능이 제한되더라도 투표 자체는 반드시 안정적으로 동작해야 합니다. 기존 엠넷플러스 투표 시스템은 외부 협력사의 상용 솔루션을 기반으로 구축되어 빠른 출시에는 유리했으나, 서비스 규모 확대에 따라 확장성, 안정성, 비용 측면에서 구조적인 한계가 발생하였습니다.
이에 엠넷플러스는 투표 시스템을 AWS 관리형 서비스를 기반으로 재설계하고 내재화하여, 대규모 글로벌 트래픽 환경에서도 안정적으로 동작하는 실시간 투표 아키텍처를 구축하였습니다. 본 글에서는 기존 구조의 문제점과 새로운 아키텍처 설계 과정, 그리고 실제 운영 환경에서 적용한 안정성 및 성능 최적화 전략을 공유하고자 합니다.
배경과 요구사항
서비스 개발·운영 내재화의 필요성
초기 엠넷플러스 투표 시스템은 외부 협력사와 함께 개발되었습니다. 이는 빠른 서비스 출시에는 효과적이었으나, 서비스 성장과 함께 다음과 같은 문제가 누적되었습니다.
- 확장성 한계: 특정 구간에서 처리량이 제한되어 대규모 동시 투표 이벤트 대응이 어려웠습니다.
- 고정 비용 구조: 이벤트 규모와 무관하게 매월 고정 계약 비용이 발생하였습니다.
- 운영 유연성 부족: 투표 정책 변경이나 집계 방식 개선 시 외부 협력사 의존으로 인해 대응 속도가 제한되었습니다.
특히 글로벌 팬덤 플랫폼이라는 서비스 특성 상, 트래픽 패턴은 예측이 어렵고 이벤트 규모 또한 매번 달라지기 때문에 기존 구조는 장기적인 서비스 확장에 적합하지 않았습니다.
기존(AS-IS) 아키텍처와 문제점
AS-IS 아키텍처 개요
기존 투표 시스템은 사용자의 투표 요청을 시작으로, 검증 -> 이력 저장 -> 실시간 집계 반영까지 하나의 처리 흐름 안에서 순차적으로 수행되는 단일 파이프라인 구조로 설계되어 있었습니다. 이 파이프라인 내에서 각 데이터 스토어가 역할을 나누어 담당하고 있었습니다.

[그림1]
- PostgreSQL : 투표의 메타데이터를 관리하는 관계형 저장소로 사용되었습니다.
- Amazon DynamoDB : 사용자의 투표 이력을 저장하는 쓰기 전용 저장소로, 투표가 확정되는 기준점(Point of No Return) 역할을 했습니다. DynamoDB Streams를 통해 후속 처리를 트리거하는 이벤트 소스로도 활용되었습니다.
- Amazon ElastiCache for Redis : 실시간 투표 수 집계, 분산 락을 통한 중복 투표 방지 등 저지연 처리가 필요한 영역에서 캐시 레이어로 사용되었습니다.
- Amazon Simple Storage Service (Amazon S3) + Amazon Athena : Amazon DynamoDB의 투표 이력을 주기적으로 내보내어 전수 재집계를 수행하는 배치 분석 경로로 활용되었으며, Amazon ElastiCache for Redis 실시간 집계와의 최종 정합성을 확보하는 역할을 담당했습니다.
구조적 한계
- 강결합 구조
AS-IS에서는 투표 요청 처리 과정에서 투표 검증, 투표 이력 저장, 실시간 집계 반영이 하나의 처리 흐름으로 연결되어 있었습니다. 이로 인해 특정 단계의 지연이나 처리 부담이 다른 단계에도 영향을 줄 수 있는 구조였습니다.
- 확장성 관점의 제약
대규모 동시 투표 상황에서는 투표 요청 증가가 곧바로 저장 및 집계 처리량 증가로 이어졌습니다. 요청을 별도로 완충하거나 단계별로 처리량을 조절하기 위한 명시적인 분리 지점은 존재하지 않았습니다.
- 투표 수신 보장에 대한 한계
투표 요청은 처리 흐름 내에서 저장까지 완료되어야 확정되는 방식이었기 때문에, 저장 또는 처리 단계에서 지연이 발생할 경우 투표 요청을 별도로 적재해 두고 이후에 처리하기 어려운 구조였습니다.
새로운 아키텍처 설계 목표
엠넷플러스는 새로운 투표 시스템을 설계하며 다음과 같은 목표를 설정하였습니다.
- 투표 요청은 어떤 상황에서도 반드시 수신합니다.
- 투표 수집과 집계·분석을 분리하여 장애를 격리합니다.
- 실시간 사용자 경험과 최종 결과 정확성을 모두 만족합니다.
- 데이터 유실 없이 복구 가능한 구조를 제공합니다.
이를 위해 실시간 집계, 원장 집계, 백업 집계의 세 가지 집계 흐름을 명확히 분리하였습니다.
인프라 아키텍처

[그림2]
집계 구조 개요
1. 실시간 집계
- 사용자에게 즉시 노출되는 실시간 결과입니다.
- Amazon ElastiCache for Redis를 기준으로 집계됩니다.
- 지연 최소화를 최우선으로 하되, 실제 투표 이벤트를 기반으로 최대한 정확한 집계를 수행합니다.
- 원장 집계 결과와 일시적으로 불일치할 수 있음을 전제로 설계되었으며, 이후 원장 집계를 통해 최종 정확한 결과로 보정됩니다.
2. 원장 집계 (최종 집계)
- 공식 결과 산출을 위한 기준 데이터로 사용됩니다.
- Amazon DynamoDB에 저장된 원장 데이터를 기준으로 집계됩니다.
- Amazon Kinesis Data Streams → Amazon Data Firehose 파이프라인을 통해 처리되며, Amazon Data Firehose의 buffer interval로 인해 실시간 집계 대비 5~6분 정도의 지연이 발생할 수 있습니다.
3. 백업 집계
- 실시간 집계와 원장 집계 간 불일치 또는 데이터 이상 상황을 대비한 안전장치입니다.
- Amazon DynamoDB Streams → Amazon Managed Streaming for Apache Kafka (Amazon MSK) → Google BigQuery 파이프라인을 통해 적재됩니다.
- 운영자가 명시적으로 호출하여 수행합니다.
- 데이터 정합성 검증 및 비상 상황 대응을 위한 최종 보루 역할을 합니다.
데이터 스토리지 및 기술 선택
투표 시스템에서 가장 중요한 요소는 안정성입니다. 전세계 K-POP 팬덤에 의해서 수상, 데뷔 등 중요한 결정이 내려지기 때문에, 어떠한 상황에서도 중단되거나 데이터가 유실되어서는 안됩니다. 따라서, 안정성이 검증된 AWS 관리형 서비스를 우선적으로 검토하였습니다.
Amazon DynamoDB – 투표 원장
투표 데이터의 단일 진실 원장(Store of Record)으로 Amazon DynamoDB를 사용합니다.
- 무제한의 쓰기 처리 성능
- Warm throughput 및 RCU, WCU Quota 확보를 통해 이벤트 규모 예측 없이 자동 확장
- 관리형 서비스 기반의 운영 부담 최소화
- 높은 내구성과 가용성 제공
또한, 동시성 이슈 대응하기 위해 낙관적 락 방식을 활용하여 순수하게 Amazon DynamoDB만을 활용하여 동시성 이슈를 해결하였습니다. TransactWriteItems API를 활용하여 투표 원장 및 사용자 별 투표 정보 기록을 원자적으로 처리하였습니다.
MongoDB Atlas – 투표 메타 및 후보자, 투표 이력, 투표 확인서
투표 메타 및 후보자 정보 관리를 포함하여 페이지네이션이 필요한 투표 이력, 투표 메타, 후보자 정보, 투표 데이터가 합쳐서 만들어지는 투표 확인서 조회를 구현하기 위해서 MongoDB Atlas를 사용하고 있습니다.
Amazon Simple Queue Service (Amazon SQS) – 투표 수집과 원장 적재 분리
투표하기 API는 요청을 검증한 후 Amazon SQS에 메시지를 전달하고 즉시 응답합니다. 이 단계에서는 데이터베이스에 직접 접근하지 않습니다. Amazon SQS를 통해 전달된 메시지는 워커 파드에서 처리되며, 최종 검증을 거친 후 Amazon DynamoDB에 원장 데이터로 저장됩니다. 이를 통해 투표 API는 병목 없이 안정적으로 동작합니다.
워커 처리 안정성 및 트래픽 제어 전략
Amazon MSK 워커의 Graceful Shutdown
Amazon MSK 워커는 Spring의 SmartLifecycle 기반으로 동작하며, 애플리케이션 종료 시점에 수신을 즉시 중단하되 이미 수신한 메시지는 끝까지 처리한 뒤 종료하도록 설계하였습니다.
- 애플리케이션 종료 시점에 맞춰 메시지 소비 중단과 종료 절차를 제어합니다.
- 종료가 시작되면 shutdownSignal을 발행하여 신규 메시지 수신을 먼저 중단하고, 이미 버퍼에 있는 이벤트들은 receiver.block()을 통해 끝까지 처리를 완료한 뒤 종료됩니다.
- 종료 과정에서는 메시지 소비 구독을 명시적으로 해제(dispose())하여, 리소스 누수나 종료 지연이 발생하지 않도록 하였습니다.
Buffer 기반 Backpressure와 처리량 제어
워커는 수신한 이벤트를 즉시 처리하지 않고, 일정 개수(bufferSize) 또는 짧은 시간 단위(bufferDuration)로 묶어 배치로 처리합니다. 이를 통해 순간적인 트래픽 스파이크를 워커 계층에서 흡수하도록 하였습니다. 배치로 묶인 이벤트는 동일 PK 기준으로 집계한 뒤 검증을 거쳐 MongoDB에 저장되며, 병렬 처리 시에는 CPU 코어 수를 기준으로 동시 처리량(concurrency)을 제한하여 저장 계층에 과도한 부하가 전달되지 않도록 하였습니다.
중복 이벤트 방지 및 정확성 확보
대규모 분산 환경에서는 네트워크 재시도, 워커 재시작, 파티션 리밸런싱 등의 이유로 동일한 투표 이벤트가 중복으로 유입될 수 있음을 전제로 설계해야 합니다. 엠넷플러스 투표 시스템은 이를 워커 로직에 의존하기보다, Amazon DynamoDB 원장 테이블의 키 설계를 통해 먼저 제어합니다.
투표 원장은 “한 번 발생한 투표 이벤트는 원장에 한 번만 기록된다”는 원칙을 기준으로 설계되어 있으며, 각 이벤트가 고유하게 식별되도록 Partition Key(PK) / Sort Key(SK) 조합을 이벤트 단위로 구성합니다.
- 원장 레벨에서 중복 차단 (멱등성 확보) PK/SK를 통해 동일한 이벤트가 여러 번 유입되더라도 최초 1회 유입된 데이터만 저장됩니다.
- 정확성의 기준점 확보 실시간 집계(Amazon ElastiCache for Redis)는 지연 최소화가 우선이지만, 최종 정확성은 Amazon DynamoDB 원장을 기준으로 재집계할 수 있습니다.
- 재처리/복구 용이성 장애나 재처리가 발생해도 원장이 “단일 진실”로 남아 있어 집계 결과의 정합성 검증 및 복구가 가능합니다.
대규모 병렬 처리 환경에서의 효율적 데이터 저장 전략
- Amazon MSK 컨슈머에서 버퍼를 통해 한 번에 수백 수천개의 이벤트를 받은 뒤 BulkInsert, BulkUpsert 연산을 수행함으로써 DB operation 수를 최소화 하였습니다.
- 실시간 랭킹 집계의 경우 쓰기 충돌을 피하기 위해 투표 그룹 및 후보자 기준으로 파티션 키를 설계하였고, 메모리 캐시를 활용하여 중복을 제거함으로써 멱등성을 보장하였습니다.
- 쓰기 충돌 발생 시 원인이 되는 데이터의 인덱스를 활용하여 실패한 데이터만 DLT (Dead Letter Topic)로 전송하여 재처리를 진행하도록 설계하였습니다.
Event Driven 아키텍처 적용
- 가장 핵심 구간인 투표 요청을 받아 Amazon DynamoDB 원장 적재까지는 안정성과 확장성이 검증된 Amazon DynamoDB와 Amazon SQS를 활용한 Event Driven 아키텍처로 설계하였습니다.
- 그 외 투표 확인서 발급, 실시간 결과 집계 과정은 Amazon MSK 기반 비동기 처리 파이프라인으로 구성하여, 각 처리 단계의 독립성과 확장성을 확보하였습니다.
- Amazon MSK 장애 시 Amazon MSK 대신 Amazon SQS를 통해 이벤트를 처리하도록 fallback 경로를 마련하여, 투표 확인서 및 투표 결과 수집이 중단되지 않도록 설계하였습니다.
성능 테스트
사전 성능 테스트를 통해 트래픽과 관련된 주요 기능 및 성능을 검증 및 개선하였습니다.
- 대용량 트래픽 상황에서 주요 기능 정상 동작 여부 대용량 트래픽이 발생시키는 상황에서 각 컴포넌트들의 Backpressure, Graceful shutdown, Fallback 동작을 검증 하였습니다. API 호출 건 수와 집계된 데이터의 수치가 일치하는지 검증하였습니다.
- 투표 전체 프로세스의 지연시간을 개선 Event-Driven 구조에서 대용량 트래픽에서의 안정성은 확인했으나, 사용자가 투표한 시점부터 투표 데이터가 집계되는데까지 걸리는 지연시간을 측정한 결과 평균 3초 정도로 개선이 필요한 상황이었습니다.
Amazon SQS – 투표 latency를 줄이기 위해서 Amazon SQS Consumer가 in-flight 메세지 없이 인입된 메세지를 즉각적으로 처리할 수 있는 트래픽을 측정하였습니다. 이를 기반으로 실시간 투표와 같이 투표 종료 직후 결과를 집계해야 하는 경우 위에서 산정한 트래픽 기준으로 인프라를 구성하였습니다. 또한, 동시성 처리와 관련된 max-concurrent-messages, max-messages-per-poll 값을 변경해가면서 정해진 임계치 내에서 CPU 리소스를 최대한 사용할 수 있도록 하였습니다.
Amazon MSK – Amazon SQS 컨슈머와 동일하게 정해진 임계치 이내에서 CPU 리소스를 최대로 사용할 수 있는 쓰레드 수 및 버퍼 사이즈를 찾기 위해 성능 테스트를 진행했습니다. 추가로 SpringData의 saveAll 대신 insertAll로 변경하고 중복 제거는 메모리 캐시를 이용함으로써 불필요한 쿼리를 제거하여 속도를 개선하였습니다.
위 사항들을 개선함으로써 짧은 시간에 수백만 건의 투표가 인입되는 상황에서 평균 처리시간을 3초에서 300ms으로 개선하였습니다.
성과
새로운 아키텍처 전환 이후, 엠넷플러스 투표 시스템은 다음과 같은 정량적 성과를 달성하였습니다.
처리 성능

기존 투표 시스템의 경우 정해진 임계치가 있었고 그 이상 트래픽이 예상되는 경우 대기열을 통해 트래픽을 통제하였습니다. 그러나 현재 투표 시스템은 지금까지 가장 높았던 투표 트래픽 기준으로 3배수 이상 처리할 수 있도록 성능 테스트를 완료하였으며, 스케일 아웃을 통해 그 이상의 트래픽도 처리할 수 있도록 되어있습니다. 또한, 각 컨슈머에 Backpressure를 적용하여 갑작스러운 트래픽 증가에도 장애가 발생하지 않고 안정적으로 트래픽을 처리할 수 있도록 되어있습니다.
안정성
- 단일 파이프라인 구조 제거로 투표 중단 위험을 해소하였습니다.
- 워커 graceful shutdown 및 backpressure 전략을 통해 트래픽 급증 상황에서도 안정적인 처리를 유지하였습니다.
- 원장 데이터 기반 재집계 및 백업 집계를 통해 데이터 정합성을 확보하였습니다.
비용 및 운영 효율
- 고정 비용 중심 구조에서 사용량 기반 비용 모델로 전환하였습니다.
- 대규모 이벤트 외 기간에는 비용을 최소화할 수 있습니다.
- 투표 정책 및 집계 로직을 내부에서 빠르게 개선할 수 있는 기반을 마련하였습니다.
결론 및 향후 계획
AWS 기반으로 투표 시스템을 내재화함으로써 엠넷플러스는 대규모 글로벌 이벤트에 적합한 실시간 투표 아키텍처를 구축하였습니다.
향후에는 다음과 같은 개선을 계획하고 있습니다.
- Amazon ElastiCache for Valkey와 Amazon DynamoDB 기반 집계 구조로 단순화
- 랑킹 집계 파이프라인 (Amazon Kinesis Data Streams → Amazon Data Firehose) 대신 Amazon DynamoDB 원장 집계 시 랑킹 정보도 같이 집계하도록 변경함으로써 랑킹 집계에 걸리는 시간 단축 및 비용 절감
- 백업 집계 자동화 고도화 : 현재 실시간 집계(Amazon ElastiCache for Redis)와 Amazon DynamoDB 원장 간 데이터 불일치가 발생할 경우, 수동 데이터 비교/검증을 하여 원장 기준 백업 집계와 비교한 뒤 실시간 집계 데이터를 재적재하고 있습니다. 이를 자동화하여, 실시간 집계와 원장 집계의 불일치가 감지되면 원장 데이터를 기준으로 백업 집계와의 정합성을 검증하고, 차이가 확인될 경우 실시간 집계 데이터를 자동으로 보정하는 파이프라인을 구축할 예정입니다. 이를 통해 수동 개입 없이도 집계 데이터의 정합성을 상시 보장할 수 있도록 개선합니다.
- Amazon CloudFront 캐싱 적용을 통해 정적 데이터를 빠르고 안정적으로 제공함과 동시에 파드 부하 감소를 통한 리소스 절감
마무리
본 사례는 “투표는 절대 멈추지 않는다”는 원칙을 아키텍처 분리뿐 아니라, 실제 운영 환경에서의 처리 전략과 튜닝을 통해 구현한 경험입니다.

또한, 지금까지 소개한 투표 시스템은 전세계 K-pop 팬이 참여하는 오디션 프로그램인 보이즈2플래닛 및 시상식 MAMA Awards 과 같은 주요 행사에서 안정적으로 운영되었으며, 엠넷플러스의 모든 투표는 이제 새롭게 개발된 투표 시스템을 통해서 운영됩니다.
이 구조는 엠넷플러스의 투표 서비스뿐 아니라, 다양한 실시간 이벤트 처리 시스템을 개발하는데 활용될 예정입니다.