2024. 10. 21. 18:07ㆍDEVELOPMENT
ART WINDOW 프로젝트 개요
주요 기능
- 공공데이터 Open API로부터 데이터를 fetching -> processing -> RDB에 저장한다.
- 서버는 요청에 따라 전시회, 박물관/미술관 정보를 return한다.
- 클라이언트는 서버로부터 받은 정보를 예쁘게 보여준다✨
주요 프레임워크 / 도구
- 서버: Spring Boot
- 클라이언트: Flutter
- DB: PostgreSQL, Redis, Cloud Storage
- Cloud Service: Google Cloud Platform, Netlify
인프라 구조 설계
환율이 상승세에 있는 점을 감안해 비용이 초과되지 않도록 넉넉하게 1,390을 기준으로 잡으면
가용 가능한 크레딧은 '$105.8 / 월'이 된다.
DB 전체 크기는 현재 10MB 안팎이며, Open API에 업데이트 되는 전시 수는 평균적으로 주당 20개 안팎으로 추정된다.
그 중에서도 현재 전시중인 전시로 한정하면 평균적으로 100개 안팎으로 유지될 것으로 추정된다.
넉넉하게 이미지 별 평균을 1MB로 잡으면 전체 용량은 200MB 내외가 된다.
즉 이미지를 포함한 데이터 전체를 Redis와 같은 In-Memory DB에 캐싱해놓고 운용해도 부담되지 않는 수준의 용량이 된다.
그러나 이런 구현에는 문제점이 있다.
Spring Boot 서버가 이미지 데이터를 직접 fetching 해야하기 때문에 요청마다 그만큼의 오버헤드가 발생하게 된다.
모든 데이터를 메모리에서 처리하는 만큼 서버 메모리가 아주 넉넉하다면 빠른 응답을 제공할 가능성은 있으나
전반적인 메모리 사용량을 크게 증가시키기 때문에 비용효율성 면에서는 훌륭하다고 보기 어렵다.
구성을 이렇게 바꾸면 비용효율성을 개선할 수 있다.
Storage 서비스는 디스크에 기반하기 때문에 Redis에 비하면 응답속도가 느리지만 CDN을 이용해 이를 어느정도 보완할 수 있다.
대략적으로 구조가 잡혔으니 각 요소들의 구체적인 배포 옵션을 설정한다.
앞서 개요에 언급되었듯이 배포해야 할 서비스의 구성 요소는 다음과 같다.
Spring Boot - 서버
Flutter - 클라이언트
PostgreSQL - 데이터베이스
Redis - 캐시
서버가 오토스케일링 등으로 분산될 때에도 일관된 데이터 접근성과 확장성을 보장하기 위해
데이터베이스와 캐시는 서버와는 별도의 인스턴스로 분리한다.
데이터베이스는 주로 CPU, 디스크 성능이 중요하고, 캐시는 메모리 용량이 중요하므로 성능 최적화와 성능 간섭 최소화를 위해
데이터베이스와 캐시도 각자 별도의 인스턴스를 이용한다.
데이터베이스 옵션 설정
Cloud SQL은 GCP에서 제공하는 관리형 데이터베이스 서비스로 주로 고가용성 데이터, 서버 유지보수 등을 자체적으로 보장한다.
Compute Engine은 커스텀 VM 서비스로 자동복구 등의 기능을 제외하면 거의 대부분을 직접 관리해야 한다.
두 서비스 간 비슷한 성능의 인스턴스 옵션의 가격차가 2배 이상이다.
총 예산이 $105.8임을 감안하면 $36 정도는 지출할 수도 있겠으나 후술할 캐시 인스턴스 비용 문제와
비용 효율성 최적화를 고려해 데이터베이스는 Compute Engine에 자가 관리형으로 이용한다.
대부분의 데이터를 캐싱해놓고 서버는 주로 캐시와 통신할 예정이니 데이터베이스 성능은 적당히 타협 가능하다.
따라서 ec2-small 옵션의 인스턴스를 할당한다. ($16.99 / 월)
캐시 옵션 설정
Redis 인스턴스는 최소 옵션으로 활용할 경우 메모리 용량이 다소 부족함에도 가격이 매우 부담스러운 수준이다.
따라서 캐시 또한 Compute Engine에 자가 관리형으로 이용한다.
Redis는 각 키와 값에 대한 메타데이터 오버헤드를 추가로 가지기 때문에, 데이터의 크기보다 더 많은 메모리가 필요하다.
또 서버로부터의 읽기 요청이 빈번한 구조이기 때문에 더 많은 메모리와 CPU 자원이 필요하다.
따라서 ec2-medium 옵션의 인스턴스를 할당한다. ($32.68 / 월)
서버 옵션 설정
현재 Spring Boot 서버의 경우 정적 리소스를 거의 포함하지 않고 메모리 점유량도 크지 않다.
그리고 마케팅 비용을 크게 운용하기 어려운 지금, 부하 테스트 할 때를 제외하면 트래픽이 많지 않을 것으로 예상한다.
따라서 작은 인스턴스를 트래픽에 맞춰 오토 스케일링하면 비용효율성을 극대화 할 수 있다.
Cloud Run을 이용하면 컨테이너 단위로 오토스케일링을 간편하게 적용할 수 있다.
현재 공공데이터에서 제공하는 이미지 url의 cors 문제로 클라이언트에서 이미지를 가져올 수가 없어 서버에서 대신 fetch하고 있다.
그로 인해 단건의 api 요청에도 메모리 사용량이 크게 튀는 모습을 보이고 있다.
그러나 이러한 현상은 이미지 파일을 Storage에 미리 받아놓도록 수정하면 크게 개선될 것이다.
인스턴스 당 메모리는 우선 512MB로 설정하고
부하 테스트 후 인스턴스가 자주 재시작되거나 메모리 부족 현상이 있을 경우 1GB로 확장한다.
서울(asia-northeast3)은 Tier 2에 해당한다.
그러나 부하테스트까지 고려하더라도 거의 비용이 들지 않을 것으로 예상된다.
스토리지 옵션 설정
스토리지는 GCP에서 제공하는 Cloud Storage를 이용한다.
Cloud Storage에서 Cloud CDN으로 캐싱될 때 Storage에 대한 트래픽 비용도 미세하게 발생한다.
그러나 아주 넉넉하게 잡아도 월 $10을 넘지 않을 것으로 예상한다.
클라이언트 옵션 설정
클라이언트는 Netlify에 배포한다. Netlify을 이용함으로써 다음과 같은 이점을 누릴 수 있다.
- 무료로 제공되는 간편한 서버리스 환경 -
- 글로벌 CDN을 통한 빠른 배포와 SSL 인증서 자동 적용 -
비용효율성이 중요한 현 상황에서 개발에 더 집중할 수 있는 아주 매력적인 옵션이다.
시스템 아키텍처 정리
Cloud Run을 제외한 예상 비용을 모두 더하면 약 $59.68 / 월 정도가 된다.
따라서 월 평균 Cloud Run 서버에 할당 가능한 금액은 $46.12이며,
인스턴스 당 vCPU 1개와 512MB 메모리를 사용하고, CPU가 요청 처리 중에만 할당되는 옵션을 기준으로 계산한다.
- 유지 비용: $18.14/월 (유휴 상태에서 발생하는 비용)
- 나머지 금액 $27.98은 실제 트래픽 처리에 사용되며, 이를 통해 약 350만 회의 요청이나 부하 테스트를 감당할 수 있을 것으로 예상된다.
단 주의할 점이 하나 있다. CPU가 요청 처리 중에만 할당되는 옵션을 선택할 경우
cron job을 수행하지 않으므로 Cloud Scheduler와 같은 기능으로 전시 데이터를 갱신해줄 필요가 있다.
그리고 이로써 인프라 설계는 마무리된다.
'DEVELOPMENT' 카테고리의 다른 글
ART WINDOW 개발일지 - 2 (0) | 2025.02.08 |
---|---|
ART WINDOW 개발일지 - 1 (0) | 2024.12.04 |
ART WINDOW 개발일지 - 0 (2) | 2024.11.29 |
ART WINDOW 성능 튜닝 - 1차 (0) | 2024.10.28 |