안녕하세요. 비즈스프링입니다.
비즈스프링에서 현재 진행중인 애드몬스터 쇼츠 광고시스템을 기술적으로 살펴보려고 합니다.
애드몬스터 쇼츠 광고시스템은 크게 『광고 등록 및 송출』 파트와 『광고 성과 정제 및 집계』 파트로 분류되어 있습니다.
그 중 오늘은 쇼츠 광고시스템을 구성하는 광고 구조 및 운영에 필요한 내용에 관해 기술적 관점으로 살펴보겠습니다.
쇼츠 광고시스템 광고의 구조
애드몬스터 쇼츠 광고는 크게 3개의 구조로 이루어져 있습니다.
![애드몬스터 쇼츠 광고플랫폼 구조](https://blog.bizspring.co.kr/wp-content/uploads/2025/02/광고구조1_1-1024x444.png)
캠페인
캠페인이란 가장 큰 광고 전략 단위입니다.
캠페인은 광고 그룹의 집합체이며 노출 기간등을 공유합니다.
광고의 목표, 노출 기간에 따라 광고 전략을 수립하고 운영할 수 있습니다.
광고 그룹
광고 그룹이란 중간 크기의 전략 단위입니다.
유사한 광고 소재들을 공유하는 소재들의 그룹입니다.
각 캠페인별로 하나 이상의 광고그룹을 구성하고 있습니다.
광고 그룹별로 일 예산을 제한할 수 있으며 광고 그룹에 포함된 광고는 이 내용을 공유하여 제어합니다.
소재
광고 소재란 가장 작은 광고 전략 단위입니다.
일반 사용자가 흔히 알고 있는, 실제 웹사이트에 게재되는 광고이며 광고의 목표에 따라 광고 게재에 필요한 데이터를 가지고 있습니다.
광고 소재는 항상 광고 그룹에 포함되어 있습니다.
쇼츠 광고시스템 광고의 등록 순서
쇼츠 광고시스템 광고는 다음과 같은 순서로 등록할 수 있습니다.
- 캠페인 등록
- 캠페인 목표 설정
- 캠페인명 설정
- 노출 기간 설정 (노출기간 미설정도 가능)
- 광고 그룹 등록
- 광고 그룹명 설정
- 광고 그룹 일 예산 설정 (일 예산 제한 미설정도 가능)
- 소재 등록
- 재생될 쇼츠 설정
- 섬네일 설정
- 광고에 표시될 내용 설정
- 브랜드명
- 메인 문구
이 글을 읽으시는 분 중에서 애드몬스터 쇼츠 광고시스템을 기술적으로 알아보려고 하는데 구조 및 등록 과정을 왜 설명하는 것인지 궁금해하실 수 있습니다.
이제부터 위와 같이 광고가 등록되는 과정에서 사용되는 기술들을 살펴보겠습니다.
Redis와 Kafka
애드몬스터 쇼츠 광고시스템을 운영함에 있어 가장 중요한 두 가지 요소는 Redis와 Kafka입니다.
Redis란?
![Redis logo](https://blog.bizspring.co.kr/wp-content/uploads/2025/02/clipart1307069.png)
Redis(Remote Dictionary Server)란 키(Key)와 값(Value)의 쌍으로 이루어진(프로그래밍의 Map) 구조의 데이터를 가진 인 메모리(In-Memory) 데이터베이스 관리 시스템입니다.
MySQL, Oracle 같은 정형 데이터를 다루는 관계형 데이터베이스(SQL)와 다르게 비정형 데이터를 다루는 비관계형 데이터베이스(NoSQL)를 다룰 수 있습니다.
즉, 데이터에 대한 고정된 스키마가 없이 여러 종류의 데이터 적재가 가능합니다.
또, 하드디스크에 데이터를 저장하는 일반 데이터베이스와 다르게 컴퓨터의 메모리에 데이터를 저장 및 처리하는 인 메모리 시스템인 것이 특징입니다.
인 메모리 시스템이기 때문에 일반 하드디스크보다 훨씬 빠른 메모리에서 데이터를 처리하기 때문에 매우 빠른 성능을 제공하지만, 메모리 사용량이 많아지는 단점도 존재합니다.
이러한 특징으로 인하여 Redis는 메시지 브로커, 캐시 서버등 데이터가 복잡하지 않으면서도 빠른 읽기 및 쓰기 성능을 요하는 곳에 사용하고 있습니다.
Kafka란?
![Apache Kafka 로고](https://blog.bizspring.co.kr/wp-content/uploads/2025/02/kafka_highres-1024x512.png)
Kafka란 아파치 재단에서 제공하는 분산형 이벤트 스트리밍 플랫폼입니다.
메시지 지향 미들웨어(MOM)을 구현한 메시지 큐 형식으로 동작하는 Pub/Sub 모델 형식의 프로그램인 것이 특징입니다.
![Pub/Sub 모델](https://blog.bizspring.co.kr/wp-content/uploads/2025/02/pub-sub.webp)
Pub/Sub 모델이란 Publish / Subscribe 의 줄임말로 서버 간의 메시지(데이터나 이벤트) 전달을 직접하지 않고 중간에 중재자가 존재하여 데이터를 전달하는 모델입니다.
메시지를 전달하는 중재자가 존재하기 때문에 서버 간의 결합도가 느슨해져 한쪽 시스템에 문제가 발생하더라도 연쇄 작용이 발생할 확률을 낮출 수 있습니다.
또, Kafka는 설정한 만큼 디스크에 메시지를 저장할 수 있으므로 메시지를 받는 쪽 시스템이 데이터 처리에 느려지거나 문제가 발생하여 작동하지 못하더라도 메시지 손실을 최대한 줄일 수 있습니다.
![Apache Kafka 구성 요소](https://blog.bizspring.co.kr/wp-content/uploads/2025/02/1715599437773-1024x576.jpg)
Kafka에서는 Producer(Publisher), Consumer(Subscribe), Broker(중재자) 라는 이름으로 Pub/Sub 모델을 구현하였습니다.
Producer가 Consumer로 메시지를 보낼 때는 메시지를 어느 곳에서 받을 지 지정하는 Topic을 명시하여 메시지를 받아서 이벤트를 처리합니다.
애드몬스터 쇼츠 광고플랫폼에서는 Kafka에서 제공하는 Streams API인 Kafka Streams를 사용하여 데이터를 처리하고 있습니다.
이전 비즈스프링 기술 블로그에서 ‘Kafka Streams’에 대해 살펴보았습니다. Kafka Streams에 대해 확인하고 싶으시다면, 아래 링크에서 해당 블로그 글을 참고해 주세요.
📑[비즈스프링블로그] 🔽 Kafka Streams: 실시간 데이터 처리의 혁신
애드몬스터 쇼츠 광고플랫폼 내 Kafka Streams 구현 방식
사용자가 많아질수록 데이터의 저장 및 업데이트 빈도가 높아지게 되는 광고 데이터 (캠페인, 광고그룹, 소재) 저장 시, Kafka Streams를 사용하고 있습니다.
해당 내용의 구현 방법에 대해 간략하게 살펴보겠습니다.
Producer (데이터를 보내는 서버)
먼저 Springboot에서 Kafka Streams를 사용하기 위해 Spring Kafka를 import 합니다.
// pom.xml
org.springframework.kafka
spring-kafka
Kafka Streams를 통하여 데이터를 전달 및 저장할 서비스를 지정하기 위한 Annotation을 생성합니다.
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface AspectCreative {
}
데이터를 저장할 Service에 Annotation을 지정해줍니다.
// CreativeService.java
@AspectCreative
@Override
public CreativeDto create(UserDto userDto, Map props) {
소재 생성 작업
}
해당 코드로 상황에 맞게 데이터를 생성하고 Topic명과 내용을 담아 전송합니다.
58 라인의 this.kafkaCreativeTemplate.send 함수에 메시지를 받을 Topic명과 데이터를 삽입하여 전송합니다.
// CreativeAspect.java
@Qualifier("kafkaCreativeTemplate")
private final KafkaTemplate kafkaCreativeTemplate;
@Around("@annotation(AspectCreative)")
@Transactional
public Object creative(ProceedingJoinPoint joinPoint) {
Object rtn = null;
try {
String className = joinPoint.getSignature().getDeclaringTypeName();
className = className.substring(className.lastIndexOf(".") + 1);
String methodName = joinPoint.getSignature().getName();
AdsType adsType = AdsType.byService(className);
MethodType methodType = MethodType.valueOf(methodName);
log.info("Detect {} [{}]", adsType.name(), methodType);
Map adsMap = new HashMap<>();
Object[] args = joinPoint.getArgs();
UserDto userDto = (UserDto)args[0];
if (!methodType.equals(MethodType.create)) {
Map props = (Map)args[1];
Creative orgCreative = null;
switch (methodType) {
case update:
case delete:
Update, Delete에 필요한 내용 처리
break;
default:
break;
}
}
rtn = joinPoint.proceed();
CreativeDto creativeDto = (CreativeDto)rtn;
adsU = creativeDto;
// Kafka Streams 메시지 전송에 사용할 MQ Object 생성
CreativeMq creativeMq = null;
삭제의 경우
if (methodType.equals(MethodType.delete)) {
creativeMq = CreativeMq.builder()
.creativeId(creativeDto.getCreativeId())
.remove(true)
.build();
} else {
creativeMq = CreativeMq.builder()
.creativeId(creativeDto.getCreativeId())
.title(creativeDto.getOptionString(OptionKey.CREATIVE_title))
.build();
}
this.kafkaCreativeTemplate.send(this.prefixProvider.get() + AppProperty.TOPIC_creative, adsType.name(), creativeMq);
} catch (Throwable e) {
e.printStackTrace();
}
return rtn;
}
Listener 서버 (데이터를 받아서 처리하는 서버)
먼저 Springboot에서 Kafka Streams를 사용하기 위해 Spring Kafka를 import 합니다.
// pom.xml
org.springframework.kafka
spring-kafka
Kafka Streams의 전송 응답을 받는 KafkaListener를 생성합니다.
각 Topic별로 Listener를 생성한 후 해당 응답을 받아서 메시지를 처리합니다.
해당 Topic의 메시지를 받아 처리할 메소드를 생성하고 @KafkaListener라는 어노테이션에 응답할 Topic을 지정하여 설정합니다.
해당 메소드의 작업이 이루어지고 나서
acknowledgment.acknowledge();
코드를 호출하여 Kafka에 해당 메시지에 대해 처리가 완료되었다고 전달하여 Kafka가 메시지를 정상적으로 처리했다고 판단하게 전달하여 서비스가 정상적으로 마칠 수 있게 해줍니다.
// KafkaTopicListener.java
@KafkaListener(topics = prefix + AppProperty.TOPIC_creative)
public void consumeCreative(@Header(name = KafkaHeaders.RECEIVED_KEY, required = false) String key, @Payload CreativeMq creativeMq, Acknowledgment acknowledgment) {
log.info("Kafka [T:creative] # K:{} P:{}", key, creativeMq);
this.creativeService.insert(creativeMq);
acknowledgment.acknowledge();
}
이상으로, 애드몬스터 쇼츠 광고시스템 중 광고 구조 및 운영에 필요한 내용에 대해 정리해보았습니다.
유튜브 쇼츠 광고플랫폼에 대해 궁금한 점이 있다면 언제든지 문의 해주시길 바랍니다.
감사합니다.
최신 마케팅/고객 데이터 활용 사례를 받아보실 수 있습니다.