천만 MAU 당근 커뮤니티 시스템의 아키텍처와 기술 선택

by DD
3시간 전
조회수 6

당근 커뮤니티 서비스의 월간 활성 사용자(MAU) 천만 돌파에 따라 시스템 확장성, 신뢰성, 성능 확보가 중요해짐

2021년 가을, 기존 모놀리스에서 커뮤니티 영역을 분리하여 모듈형 모놀리스(Modular Monolith) 아키텍처 기반의 커뮤니티 시스템 구축 시작

웹앱(Web App)과 서버앱(Server App)의 역할 분담 및 내부 모듈화, 계약 기반의 경계 관리를 통해 복잡성 관리 및 빠른 제품 변화 지원

SSR, 스트리밍 SSR 도입으로 초기 렌더링 지연 문제 해결 및 사용자 경험(User Experience) 개선

API 계약을 OpenAPI 중심으로 관리하고 코드 생성 및 자동 검사를 통해 명세와 구현 간의 불일치 최소화

모듈형 모놀리스(Modular Monolith) 아키텍처의 장단점

커뮤니티 시스템은 여러 서비스의 서버 기능을 하나의 서버앱으로 배포하고 운영하는 모듈형 모놀리스(Modular Monolith) 구조를 채택했습니다. 이는 작은 팀이 운영하기 용이하며, 코드베이스 내에서 변경 영향 추적이 쉽고 핵심 흐름을 단일 트랜잭션으로 처리할 수 있다는 장점이 있습니다. 하지만 모듈 간의 의존성 관리, 빌드 및 배포 복잡성 증가, 그리고 논리적 경계가 물리적 분리로 이어지지 않을 경우 기술 부채가 될 수 있다는 단점도 존재합니다. 이 구조는 서비스 성장과 팀 규모에 따른 현실적인 선택으로, 향후 독립 배포가 필요할 때 분리 비용을 낮추는 기반을 제공합니다.

웹앱과 서버앱의 역할 분담 및 경계 관리

커뮤니티 시스템은 사용자 접점의 웹앱(Web App)과 백엔드 로직을 담당하는 서버앱(Server App)으로 역할을 명확히 분담합니다. 웹앱은 초기 렌더링 지연 문제를 해결하기 위해 스트리밍 서버 사이드 렌더링(Streaming SSR)을 도입했으며, 각 웹앱은 독립적으로 빌드 및 배포되면서도 공통 기반은 공유합니다. 서버앱은 여러 서비스 도메인을 모듈로 분리하고, OpenAPI 계약을 통해 웹앱과의 인터페이스를 관리합니다. 이러한 경계 관리는 제품 변화에 대한 빠른 대응코드의 재사용성 및 유지보수성 향상을 목표로 합니다.

후속 작업(Worker)의 격리를 통한 안정성 확보

게시글 저장과 같은 API 요청 후 발생하는 검색 색인, 임베딩 생성, 콘텐츠 검수, 알림 발송 등의 후속 작업(Worker)이벤트 기반으로 격리하여 운영합니다. 각 작업은 독립적인 큐와 소비 경로를 가지며, 특정 작업의 실패가 다른 작업이나 API 응답에 영향을 미치지 않도록 설계되었습니다. 실패 시에는 재시도 및 보정 작업을 통해 데이터 일관성을 유지하며, 회로 차단기(Circuit Breaker)와 같은 패턴을 적용하여 외부 시스템 연동 실패의 전파를 차단합니다. 이는 시스템 전체의 장애 내구성(Fault Tolerance)을 높이는 핵심 전략입니다.

데이터 관리 및 캐싱 전략

커뮤니티 시스템은 원본 데이터를 Amazon RDS에 저장하고, 서비스 도메인별로 논리적인 데이터 경계를 설정합니다. 캐시(Cache)는 자주 읽는 데이터를 로컬 캐시와 Valkey에 저장하여 원본 데이터베이스 부하를 줄이는 완충 역할을 합니다. 캐시 사용 불가 시에는 원본 데이터베이스로 폴백(Fallback)하는 전략을 사용합니다. 또한, 검색 데이터는 OpenSearch에 별도로 색인하여 원본 데이터베이스와 분리하고, 색인 지연이나 실패 시에도 원본 데이터는 안전하게 유지하며 재색인으로 복구할 수 있도록 합니다. 이는 읽기 성능 향상과 데이터 일관성 유지를 위한 설계입니다.

자동화된 테스트와 계약 기반 개발

시스템의 경계를 지키기 위해 자동화된 테스트를 적극 활용합니다. 모듈 간 의존 방향 검사, 트랜잭션 대상 데이터베이스 명시, 외부 요소 주입 등을 CI/CD 파이프라인에서 검증합니다. 특히 OpenAPI 계약을 중심으로 코드 생성을 자동화하고, 하위 호환성을 깨는 변경은 CI에서 차단합니다. 이를 통해 명세와 구현 간의 불일치 가능성을 최소화하고, 웹앱과 서버앱 엔지니어 간의 협업을 강화하여 API 설계 품질을 높입니다. 이는 개발 생산성 향상과 시스템 안정성 확보에 기여합니다.

운영 복잡성 관리 및 장애 대응 전략

천만 MAU 규모의 트래픽을 처리하며 발생한 다양한 장애 경험을 바탕으로 운영 복잡성을 관리하고 있습니다. 초기에는 회고(Retrospective)를 통해 장애 원인과 대응을 학습하고, 시스템이 커지면서는 관측 가능성(Observability) 확보를 위한 분산 추적, 중앙화 로깅, 메트릭 수집을 강화했습니다. 장애 대응은 요청 취소, 폴백, 회로 차단기, 기능 제어 등 아키텍처 수준의 장치를 통해 영향 범위를 줄이고 빠른 복구를 목표로 합니다. 또한, 비용 효율적인 개선 활동을 지속하며 운영 안정성을 높이고 있습니다.

천만 MAU를 지탱하는 커뮤니티 시스템을 소개해요