0. 이 글 혹은 문제 혹은 프로젝트의 탄생 배경
얼마 전, 티스토리에서 예약 발행 기능을 사용하던 중 흥미로운 현상을 보았다.
예를 들어 자정(00시 00분)에 맞춰 예약 발행을 걸어뒀는데, 실제로는 00시 01분쯤에 게시물이 올라오는 것이다.
생각컨대, 아마도 분 단위 스케줄러가 일정 간격으로 scheduled_time < 현재 시각
조건을 체크하는데, 이게 분 단위로 작동하는 것 같았다.
그러다 “그렇다면 대규모 예약 발행이 몰릴 때는 어떻게 될까?” 하는 궁금증이 생겼다.
백엔드 관점에서, 만약 같은 시각(예: 자정)에 수십만~수백만 건의 예약이 한꺼번에 쏟아진다면 DB나 서버가 버틸 수 있을까?
어떤 구조로 설계해야 성능 저하나 발행 지연 없이 안전하게 처리할 수 있을까?
이런 의문에서 출발해, 대규모 예약 발행 시나리오를 가정하고 시스템을 설계·검증해 보자는 챌린지가 바로 이 글의 시작이다.
1. 시나리오 및 목표
시나리오 배경
- 대형 블로그 플랫폼에서 게시물을 지정한 시점에 자동으로 발행하는 예약 발행 기능을 개발하려고 합니다.
- 사내에서는 “진짜로 대규모로 예약된 게시물을 단기간에 처리해야 할 경우 성능 저하나 지연이 발생하지 않을까?” 라는 의문이 제기되었습니다.
- 최근 연말 카운트다운·대규모 공동 프로모션(예: 블랙프라이데이·신제품 공개)처럼 ‘자정 공개’ 효과를 노리는 캠페인이 늘면서, 수십 만 ~ 백 만 명의 크리에이터가 동시에
00 시 00 분
에 게시물을 예약하는 사례가 급증하고 있습니다. 이때 쏟아지는 대량 쓰기 트래픽을 안전하게 흡수할 수 있는지 검증이 필요합니다.
서비스 규모 및 동시 트래픽 가정
- 서비스: 대형 블로그 플랫폼: 월간 활성 사용자 2천만, 일간 활성 사용자 500만 수준
- 기능: 사용자가 게시물을 지정된 시점에 자동으로 발행하는 예약 발행 기능
- 운영 규모:
- 일평균 예약 등록 건수: 300만 건
- 최대 피크 타임(예: 자정 직전)의 동시 예약 건수: 100만 건/분
- 실제 월간 누적 예약 건수: 1천만 건 수준(최대 1억 건, 약 5년치 누적)
- 핵심 문제:
- “1분 안에 100만 건 이상의 예약 발행 레코드를 쓰고(등록·발행 처리)”
- “초 단위 정확도는 요구하지 않으며, 예약 시각 +1분 안에 완료
목표
- 핵심 이슈 : 예약 시점에 1분 이내에 최대 100만 건의 쓰기(예약 상태→공개 상태 업데이트)를 안정적으로 감당
- 대량 동시 요청 시에도 CPU/메모리 과부하 없이 안정적으로 처리
2. 요구사항(Requirements)
기능적 요구사항
- 예약 발행 등록
- 사용자는 게시물 내용, 제목, 예약 발행 시각 등을 입력하여 등록할 수 있어야 합니다.
- 예약 발행은 1분 단위로 합니다. (초는 오차 범위 허용)
- 예약 발행 조회
- 예약된 게시물 목록을 조회할 수 있어야 하며, 게시물 제목, 예약 시각, 발행 상태(예정/발행 완료) 등을 확인할 수 있어야 합니다.
- 발행 기준 시각은 UTC 기준(또는 KST)이며, 사용자 로캘별 표기 문제는 과제 범위에서 제외합니다.
- 예약 발행 실행
- 예약된 시간에 게시물은 발행되어야 합니다(게시물 상태가 '공개'로 전환)
- 예약 시각과 실제 발행 시각이 같거나(이상적) 혹은 근접(가능한 범위 내)해야 하며, 최대 오차는 1분입니다. (e.g., 00시 00분 발행 예정이라면, 00시 01분 이내에 발행되어야 함)
- 대규모 데이터 처리 방안
- 예약 데이터 최대 1백 만 건, 전체 데이터 최대 1억 건을 가정하였을 때도 특정 시점에 발행이 원활히 이뤄지도록 성능 최적화가 필요합니다.
- 데이터는 최대 5년 간 보관될 수 있어야 합니다.
비기능적 요구사항
- 확장성(Scalability)
- 대량의 예약 발행 데이터를 처리할 수 있어야 합니다.
- 데이터베이스나 서버 노드를 확장(Sharding, Partitioning) 가능하도록 아키텍처를 고려합니다.
- 가용성(Availability)
- 예약 발행이 특정 시점에 몰릴 때에도 시스템이 멈추거나 중단되지 않아야 합니다.
- 필요 시 분산 큐, 메시지 브로커 등을 고려할 수 있습니다.
- 성능(Performance)
- 예약 시간 도래 시 스케줄러가 게시물을 검색하는 데 드는 시간이 과도하게 길어지지 않아야 합니다.
- 인덱싱 설계, 배치 처리(batch), 혹은 별도의 검색 구조 활용이 권장됩니다.
- 신뢰성(Reliability)
- 발행 시점이 정확하게 지켜지지 못하더라도(초 단위 편차) 1분 내외로는 발행이 되어야 합니다.
- 발행된 컨텐츠는 발행된 즉시 유저에 의해 정확하게 조회될 수 있어야 합니다.
- 트랜잭션 관리
- 예약 발행 시 게시물 상태 변경과 실제 “게시물 공개” 로직 사이에 데이터 정합성을 유지해야 합니다.
3. 제약사항(Constraints)
- 인프라 환경
- 클라우드 서비스 무관(온프레/프라이빗·퍼블릭 클라우드 모두 적용 가능)
- Docker·Kubernetes 등 컨테이너 기반 배포 권장
- 기술 스택 및 데이터 저장소
- 언어: Kotlin (JVM 17 이상) 또는 Java
- 프레임워크: Spring Boot
- 데이터 저장소: 자유
- 기타 필요한 프레임워크, 모듈, 라이브러리: 자유
- 테스트 데이터 규모
- 실제 100만 건/분 피크 부하 시나리오 시뮬레이션
- 최소 100만~500만 건 더미 데이터로 성능·병목 분석
4. 과제 제출 시 요구사항
- GitHub URL (소스 코드)
- 아키텍처 다이어그램 & 설명
- DB 스키마 설계(DDL)
- 배포·실행 가이드 (
./gradlew bootRun
, Docker Compose 등) - 성능 테스트 결과 요약 (k6/Gatling 스크립트, 주요 지표)
c.f. 평가 항목
- 설계의 타당성: 대규모 데이터 처리에 대한 인덱스, 배치, 분산 처리 등을 고려했는가?
- 코드 품질: Kotlin과 JPA 사용 시 엔티티 매핑, 트랜잭션 관리, 예외 처리 등이 적절한가?
- 확장성: 단순 예약 발행 외에, 취소/수정 등 추가 요구사항을 쉽게 지원할 수 있는 구조인가?
- 성능 및 안정성: 극단적인 시나리오(백만~수천만 건)에 대해서도 스케줄러가 동작하는지, 중복 발행 방지 로직이 있는지.
6. FAQ
예약 발행된 게시물이 티스토리처럼 구글 SEO 관점에서 URL 등록(인덱싱) 처리까지 고려되어야 하나요?
답변:
이번 과제의 범위에는 구글 SEO나 URL 인덱싱 작업은 포함되지 않습니다.
본 과제는 대규모 예약 발행 시스템의 아키텍처와 성능 최적화에 집중합니다.
- 대량 예약 데이터를 정해진 시점에 지연 없이 발행할 수 있는지
- DB 인덱스 및 배치 처리 설계가 적절한지
- 다중 노드 환경에서 중복 없이 안정적으로 발행되는지
- 시스템이 확장 가능하고 장애에 강한 구조인지
SEO 노출 최적화는 실제 서비스 운영 시 중요한 주제지만, 이번 과제에서는 예약 발행 이후 별도 비동기 처리(사이트맵 제출, robots.txt 관리 등) 범위로 간주해 제외합니다.
예약 취소·시간 변경이 피크 직전에 대량으로 발생하면 어떻게 처리해야 하나요?
답변:
이 역시 과제 범위 안에 포함될 수 있는 현실적 시나리오입니다.
- Soft-delete, Version update, Upsert Queue, 재정렬 캐시 등 어떤 전략을 채택할지는 지원자의 재량입니다.
- “왜 해당 전략을 선택했는가?” 를 설계 문서에 근거와 함께 서술해 주시면 됩니다.
발행 실패가 발생했을 때 재시도(재발행) 로직이나 Dead Letter Queue가 꼭 필요할까요?
답변:
Retry/Back-off, DLQ, Idempotent update 도입 여부도 지원자가 판단합니다.
- 장애 시나리오 정의 → “어떤 조건에서, 얼마 간격으로, 몇 회 재시도할지” 를 자유롭게 설계해 주세요.
- 반드시 구현까지 할 필요는 없으나, 필요성 판단과 설계 근거를 문서화해 주시면 충분합니다.
샤딩·파티셔닝은 어떤 기준으로 설계해야 하나요?
답변:
시간, 사용자, 해시 등의 분할 키 선택은 전적으로 지원자에게 맡깁니다.
- 읽기/쓰기 패턴, 데이터 핫스팟, 운영 복잡도 등을 고려해 설계하고
- 선택 이유(장단점 비교 포함)를 명확히 문서로 설명해 주세요.
※ 위 세 가지 이슈 모두 “정답”은 없습니다. 설계 의도·근거·트레이드오프를 논리적으로 제시하면 평가에 충분히 반영됩니다.
'이슈와해결' 카테고리의 다른 글
이벤트 드리븐 트러블슈팅 Ep. 2: 사라진 혜택, 중복된 포인트? Kafka 메시지 처리, 어디까지 믿어야 할까 (1) | 2025.06.01 |
---|---|
이벤트 드리븐 트러블슈팅 Ep. 1: 비동기 결제 파이프라인에서 구글 API가 늦을 때 생기는 일 (1) | 2025.05.10 |
대기열 기반 예약 시스템에서 MSA와 EDA를 이용해 느슨한 결합 추구하기 (0) | 2024.08.11 |
대기열 시스템 다양한 설계 방법 탐구 (feat. 레디스와 카프카를 이용한 O(1) 최적화) (2) | 2024.08.10 |
백엔드 응답 속도 500ms 줄이고 7배 개선한 썰 (2) | 2024.04.12 |