서론
프로젝트에 앞서 전체적인 인프라 구성을 고려해 보았다. 특히 사이드 프로젝트로 진행하는 만큼 비용의 문제가 가장 크다고 생각했다. 그래서 최대한 비용과 학습의 사이에서 고민해 보자 하고, 프로젝트를 진행하면서 계속 수정할 예정이다.
전체 기능 정리

우선 아키텍처 설계에 앞서 생각했던 프로젝트 구조를 3가지 부분을 나눠서 생각했다.
- API 호출 부분
- 데이터 저장 부분
- 웹 서비스 부분
여기서 데이터 저장 부분은 프로세스 자체를 메달리온 아키텍처 기반으로 생각했다. 데이터 저장 부분에 메달리온 아키텍처를 사용했는데, 이는 상세 아키텍처 설계를 진행하며 생각한 부분에 대해 설명하겠다.
제약 사항
아키텍처를 구상하면서 제1번 제약 사항은 비용이었다. 결국은 학습 겸 사이드 프로젝트가 목표이기 때문에 수익 창출을 통해 운영 비용을 충당하기보단, 절감할 수 있는 부분을 절감해서 금전적으로나 시간적인 비용을 최대한 고려하고자 했다.
제일 큰 비용 걱정은 두 곳이었다. 데이터 관련 비용과 WAS 운영 비용. 클라우드 인스턴스를 띄워 운영하게 되면 알게 모르게 계속 비용이 들기 때문에, 이 부분을 최대한 어떻게 절감하면 좋을지를 설계의 중점으로 두고 생각하기로 했다.
두 번째 제약 사항은 게임사 API라는 점이었다. 처음에는 프로젝트의 초기 목표를 데이터 레이크로 생각했었다. 하지만 곰곰이 생각해 보니 게임사에서 가지고 있는 데이터가 이미 정형으로 이뤄진 데이터 레이크였고, 이를 좀 더 활용성 있게 데이터 플랫폼을 구현할 필요가 있었다. 결과적으로는 데이터 웨어하우스를 통한 서비스를 목표로 삼았는데, 게임사의 데이터는 데이터 레이크지만 게임사에서 제공하는 API로 접근해야 했다.
제약사항을 정확하게 정의하면 게임사에서 제공하고 있는 API 제한은 초당 1회라는 점이었다. 다만 게임이 매치당 평균 20분 정도 걸리고, 승률 및 메타 판단을 위한 상위권 인구수는 %가 생각보다 크지 않아 언젠간 모든 데이터를 모을 수 있다고 생각했다. 그래도 호출 부분의 인스턴스가 죽으면 많으면 초당 1개의 레코드의 손해가 생길 터였다.
전체 아키텍처

결과적으로 구성한 전체 아키텍처는 그림과 같다. 데이터를 관리하기 위해 2개의 인스턴스를 사용하기로 했고, 웹 서비스 제공하는 부분은 별도의 인스턴스를 사용해서 데이터 레이어와 분리하고자 했다.
데이터 저장 부분

다른 부분보다 데이터를 다루는 프로젝트인 만큼 이 부분부터 어떻게 생각했는지 먼저 설명하는 게 좋을 것 같다. 데이터 저장 부분은 Amazon S3를 사용하는 것으로 계획했고, 별도의 인스턴스를 통해 저장한 데이터에 대해 정리 및 연산을 진행할 계획이다.
Amazon S3

우선 데이터의 값은 API를 무작위로 하나 찍어서 확인해 본 결과 약 302KB 정도 나왔다. 예상했던 것보다 훨씬 큰 값이기에 놀랬던 감이 있었다. 어찌 됐든 데이터의 값이 크기 때문에 예전에 진행했던 Backend 프로젝트 구성으로 사용할 경우 데이터 저장에 대한 비용을 크게 잡아갈 수밖에 없었다.
특히 그냥 EC2를 사용하면서 EBS(Elastic Block Store)에 DB를 설치하거나 RDS를 사용할 경우와 비용 차이가 커지기 때문에 오브젝트 스토리지를 선택했다.



각각의 비용을 살펴봤을 때, RDS는 S3에 비해 2배 이상의 GB당 저장 요금이 발생할뿐더러 24시간 동작해야 하는 데이터 저장소 특성상 시간당 비용을 내야 했다. 뿐만 아니라 데이터의 용량과 집계 시 요구되는 스펙을 좀 더 높게 설정한다면 추가 비용이 발생활터였다. EBS의 경우 인스턴스에 DBMS를 설치해서 진행해야 하는데, 이 경우엔 이미 스토리지당 비용이 S3를 몇 배로 넘어가고 있으므로 데이터의 용량을 생각해 보면 EBS에 저장할 수 없었다.
S3를 쓰지 않는 이유는 데이터를 읽는 속도의 문제인데, 저장할 원본 데이터에 대해서 Read를 요구하지 않으므로 S3이 제일 좋은 선택지로 보였다. 특히 1GB당 0.025 USD이므로 약 1TB의 데이터를 저장해도 저장 비용으로 5만 원이 채 안 나가기 때문에 적절한 비용으로 처리가 가능해 보였다.
| S3 | EBS | RDS | |
| 저장 비용 | 낮음 | 높음 | 중간 |
| 인스턴스 비용 | 없음 | 없음(서비스 인스턴스에 포함) | 있음 |
메달리온 아키텍처
S3를 선택하면서 데이터 저장을 어떻게 할 것인가에 대한 문제가 떠올랐다. 기존에는 데이터를 수집 후에 NoSQL이나 RDB를 통한 저장을 할 생각이었다. 그렇게 저장해서 정리한 다음에 웹 서비스 파트로 집계 및 분석을 완료한 데이터를 전송할 생각이었는데, 용량 및 비용에 대한 문제로 S3로 이전하게 되면서 이를 더 잘 저장할 방법이 필요했다.
물론 데이터 엔지니어링 자체가 용량이 큰 데이터를 자주 수집하기에 이를 다루는 방법에 대해 많이 고안되어 있었다. 그래서 그중에서 수집/저장과 데이터 활용을 같이 활용하기 좋은 방법을 찾았고, 메달리온 아키텍처를 채택하기로 했다. S3에 버킷 하나를 두고 Prefix를 통해 구분할 수 있다는 점과 데이터 관리에 사용할까 고민 중이던 Iceberg에서 지원하는 점이 있다는 것이 좋았다.
데이터 영역
데이터 저장에 AWS S3와 메달리온 아키텍처를 사용하기로 결정하면서 각 영역에 대한 데이터의 목적을 설정했다.
- Bronze 영역
- 기본적으로 수집한 Raw 데이터를 저장하는 영역으로 사용할 계획에 있음
- Silver 및 Gold에서 발생한 문제에 대해 재확인을 위해 저장하는 목적을 가짐
- 결과적으로 필터링 전의 데이터 저장 목적과 데이터 계보를 위한 저장 목적을 지님
- Silver 영역
- 간단한 필터링을 거친 데이터를 저장하는 목적의 영역
- 비즈니스 로직과 관련된 데이터(Gold Zone)를 집계하기 위한 기반 데이터를 저장함
- Gold 영역
- 실제로 서비스(기능)에 활용될 수 있는 데이터 저장 목적의 영역
- 당장 해당 데이터를 가져다가 서비스에 활용할 수 있는 수준의 데이터 저장함
- 추가 기능을 개발할 때, 해당 데이터를 재활용할 수는 있겠으나 기존 집계 결과에 추가하는 것이 아니라 기능에 해당하는 데이터를 추가하는 형태로 개발할 계획에 있음
여기서 영역별로 좀 더 나눠서 설계 목적과 그에 따른 계획을 설명하자면,
Bronze 영역
데이터 계보를 위한 저장 목적이 큰 영역으로 가장 Raw 데이터의 집합이 된다. 데이터에 대한 정책을 설정해서 필터링을 진행하고, 실제로 활용할 수 없다고 판단되는 데이터(유저 개개인의 닉네임 등)에 대해서 제외하고 Silver 영역으로 옮길 생각이다. 그렇기 때문에 Gold 영역까지의 분석에 활용되진 않아서 참조가 적을 것이란 생각에 있다.
Bronze 영역의 가장 큰 문제는 API 요청 내에서 사용하는 레코드당 약 300KB의 데이터를 가지기 때문에 아무리 S3의 비용이 낮더라도 이를 그대로 저장하면 비용면에서 무리가 발생할 것으로 생각했다. 그래서 여기에 대해서 몇 가지 해결책을 생각은 해뒀다.
- 데이터 압축
첫 번째로 고려한 방법은 데이터 압축이다. 우선 Bronze 영역 자체는 문제가 생겨 원본 참조가 발생할 경우를 대비한 저장이 주목적이다. 그렇기 때문에 기본적으로 집계나 통계를 위해 잦은 Read가 발생하지 않을 것으로 예상했다. 그렇다면 적절히 어떤 데이터 압축을 찾을지에 대한 메타 데이터 정도만 가지고 있으면, 해당 압축 파일만 해제해서 확인할 수 있으므로 데이터를 압축하는 방법이 적절해 보였다.
- 데이터 이관 및 삭제
두 번째로 고려한 방법은 데이터 이관 및 삭제다. 데이터 압축 때도 말했듯 Bronze 영역의 목적은 원본의 재참조기 때문에, 오래된 데이터는 이미 충분히 활용되어 굳이 재참조가 거의 일어나지 않을 것으로 판단할 수 있다. 그런 데이터에 대해서는 이관을 통해 사용 중인 S3의 데이터 용량을 줄이는 것이 괜찮은 방법이라 생각했다.
다만 아키텍처 내에 해당 방법을 포함하진 않았는데, 우선 프로젝트 진행 및 데이터 수집/분석부터 진행해야 이관이 필요한지 알 수 있다고 판단했다. 그리고 어느 곳에 데이터를 이관할지도 고민이기 때문인데, 현재로선 AWS의 Glacier를 활용하거나 다른 플랫폼의 드라이브 시스템(구글 드라이브, 네이버 마이박스 등)을 활용하는 방법을 생각 중에 있다. Glacier의 경우 S3에 대비해서도 비용을 1/5 가량으로 줄일 수 있으니, 필요하다면 AWS 상에서 연결해서 바로 진행해도 늦지 않을 것이라 판단했다.

- 영역 삭제
어떻게 보면 최후의 수단으로 생각하고 있는 방법으로 아예 Bronze 영역을 삭제하는 것도 고민 중에 있다. 이 부분은 기본적인 데이터 영역 및 데이터 성격과 무관한 방법으로, 시스템상에서 이미 게임사의 API가 Data Lake 역할 수행하기 때문에 선택지에 넣었다.
정리하자면 어느 데이터(gameId, date 정보) 등을 메타 데이터로 Silver Zone에 저장하면 충분히 게임사의 API로 재접근 가능하기 때문에 이에 대해 고민에 있다. 다만 게임사 측의 데이터 정책이 어떻게 될지 몰라 해당 데이터를 재접근하지 못하는 경우(삭제, 이관하여 API 상에서 제공하지 않는 경우)가 발생할 수 있을 것이라 생각한다. 그래서 정말 데이터 저장 비용이 감당할 수 없는 경우에 진행할 생각에 있다.
이외에도 Bronze 영역과 Silver 영역에 대해서 데이터 GET/POST 요청이 좀 많이 발생할 텐데, 그렇지만 동일 리전 내에서 발생하는 수신 데이터는 제외한다. 기본적으로 버킷과 서버는 API 요청과 웹 서비스 속도를 고려하여 서울 리전으로 설정할 생각에 있기에, 인스턴스와 버킷 간의 데이터는 비용이 없을 것으로 보고 있다. 만에 하나 발생해서 데이터 전송 비용이 발생할 경우, 로컬에 홈서버라도 구축해서 데이터 저장용으로 온프레미스하게 짜야할지도 모르겠다.

데이터 필터링 및 데이터 집계/분석

데이터 필터링 및 집계/분석 부분은 아래의 특징을 먼저 주목해서 작업을 진행했다.
- 필터링과 집계/분석은 각각 Airflow에 의해 DAG로 정의된다
- 주로 특정 데이터의 분류, 집계 등을 수행하며, 데이터량이 많지만 작업은 단순하다
먼저 1번 특징에서 생각할 점은 각각의 작업은 24시간 이뤄지지 않는 배치 작업이라는 점이었다. API 호출 부분에서 후술 하겠지만 Bronze 영역에 압축된 데이터가 올라오기까지의 시간이 있다. 그리고 필터링 작업은 해당 데이터가 업로드된 이후 이뤄진다. 다시 말해서 필터링은 (데이터 압축) > (데이터 업로드) > (데이터 필터링)의 DAG로 구성되며, 이는 데이터 압축 주기에 따라 필터링 동작에 비는 시간이 있다는 말이 된다. 집계/분석의 경우에도 충분히 데이터가 모이는 주기, 약 하루에서 이틀 가량의 시간 필요하며 이에 따라 스케줄링이 이뤄진다. 결과적으로 인스턴스가 동작하지 않는 시간이 생기고, 이는 Spot 인스턴스를 구성하면 가격을 낮출 수 있다는 말이 된다.
2번 특징은 데이터 엔지니어링 프로젝트로 가닥을 잡으면서 필연적으로 발생하는 내용이었다. 사실 서비스에 사용될 승률이나 기타 집계 데이터는 더하고 빼고 나누는 간단한 연산만 진행된다. 그렇기 때문에 하나하나의 컴퓨팅 파워보단 많은 양의 병렬 작업이 더 요구된다. 결과적으로 MapReduce 방식의 연산이 효과적으로 적용되는 환경이 되고, 그쪽 방면을 사용할 수 있게 기술을 선정해야 했다.
기술 선정에서는 Spot 인스턴스를 써본 경험이 없기도 하고, 어느 정도 스펙의 인스턴스가 요구되는지 감이 오지 않았다. 그리고 EMR은 별도로 EMR 운영 비용을 받기에 정확히 데이터를 운영했을 때의 가격을 알기 어려웠다. 또 데이터가 적고 빠르게 개발하는 것이 필요하면 DuckDB를 활용할 수 있을 것이라 생각도 했다. 그렇지만 또 일단 학습을 목적으로 Spark를 통한 MapReduce 환경을 구성하는 것도 좋아 보였다. 그런 식으로 당장 데이터를 직접 다루지 않아서 감을 잡기 어려웠고, 그래서 기술을 유동적으로 정할 수 있도록 인스턴스를 분리해서 마이그레이션을 최대한 하기 편하도록 구성했다.
정리하자면 아키텍처에서 필터링과 집계/분석을 위해 이를 진행해 줄 Spot 인스턴스를 배치했다. 다만 해당 인스턴스를 어떻게 활용할지에 대해 고민 중에 있고 아래의 옵션을 생각하고 있다.
- AWS EMR
- Spark on EC2
- DuckDB
그렇지만 각 옵션을 꼭 하나를 고집할 생각은 없고, 비용과 데이터 규모에 따라 마이그레이션할 생각에 있다. 개발 비용(시간, 요금 등)을 어떻게 관리할지 차차 개발하면서 인스턴스 내부 구성을 정하는 것이 좋다고 생각했다.
서비스 호출 부분 (데이터 수집 & 오케스트레이션)

기능 정리에서 서비스 호출 부분으로 명명했지만, 아키텍처에서는 정확히 데이터 수집 부분이 된다. 인스턴스 내에 서비스 호출 이외에 몇 가지가 더 추가되었는데, 차례로 설명을 진행하겠다.
Airflow
우선 이전 항목에서 데이터 필터링, 집계/분석도 DAG 구성을 진행한다고 작성했다. 이를 관리할 Airflow 인스턴스가 위치해야 하는데, 이를 서비스 호출 부분과 함께 동작하도록 구성했다. 여기에는 다음의 요소를 고려했다.
1. 24시간 구동(온디맨드) 필요
오케스트레이션을 통해 스케줄링 작업을 하는데, 이를 위해 24시간 구동이 필요하다. 그런데 결국 데이터 수집도 24시간(1초에 1회) 수행이 필요하므로 온디맨드 인스턴스 내에서 따로 구동하는 것이 비용면에서 낫다고 생각했다.
2. 데이터 수집 동작 방식
데이터 수집은 단순 API 호출을 기반으로 몇 가지 조건에 따라 분기 정도만 갈리기 때문에 별도의 어플리케이션으로 동작할 필요가 없었다. 그래서 스크립트 정도로 구성이 충분히 가능했고, 이 경우 별도의 컨테이너로 리소스만 할당해 주거나 아예 Airflow를 통해 스크립트만 동작시켜도 훨씬 쉽게 사용이 가능할 것이라 생각했다.
Script & SQLite
데이터 수집 및 스크립트 설명을 위해서 먼저 지금 고려 중인 데이터 수집 로직을 설명할 필요가 있다. 우선 게임의 조건은 다음과 같다.
1. 한 매치 내에 21 ~ 24명의 참가자가 진행한다.
2. 게임 내 티어는 다음과 같이 분류되며, 랭크 1000명 이내는 in 1000이란 명칭으로 추가로 구분한다.

3. 게임은 레이팅을 올릴 수 있는 `랭크 게임`과 레이팅과 무관한 `일반 게임`으로 나뉜다.
4. API는 1초에 1번 호출 가능하다.
5. API에서 Match 데이터는 최신순으로 따로 접근할 수 없고, 특정 유저의 최신 Match 기록만 가져올 수 있다.
그리고 API 구조상 직접적으로 내가 원하는 매치 결과를 가져오기 위해서 다음의 선택지를 생각했다.
1. 순차 증가하는 GameId 접근하는 방식
실제로 게임 API 조회한 결과 GameId는 증가할수록 게임의 시작 시간이 증가하는 것으로 보아 순차로 접근해서 게임 데이터를 취득할 수 있을 것이라 생각했다. 그렇지만 API를 몇 번 조회해 보니 생각보다 시간당 게임 수가 많았고, 내가 원하는 유의미한 메타 데이터만 조합하기에 생각보다 너무 오랜 시간이 걸릴 것이라 생각했다. 특히 조합이나 메타를 의식하려면 점수에 민감한 랭크 게임의 데이터를 취득하는 것이 좋은데, 데이터 전부를 끌어다 쓰기엔 시간이 너무 오래 걸릴 것이라 생각한다.
2. 유저를 검색해서 Match 데이터를 랜덤 접근하는 방식
API 중 in1000에 해당하는 유저 정보를 가져올 수 있는 API가 있다. 해당 API로 유저 리스트를 가져와서 최근 플레이한 게임을 집계하고, 해당 매치에 참여한 다른 유저 리스트에 다시 접근하는 식으로 뻗어 나갈 수 있다. 특히 필요한 데이터가 다이아몬드 티어 내지 플레티넘 티어까지로 한정시키면 접근 및 저장하는 게임 수도 확 줄어들게 된다. 여기서 일반 게임인 경우도 제외하면 훨씬 더 적은 데이터 접근으로 필요한 데이터 수집이 가능할 것이라 생각했다.
생각으로는 2번 방법으로 할 수 있다고 생각하는데, 여기서 문제는 중복이 발생한다는 점이다. 순차 접근이 아니라 랜덤 접근으로 이뤄지므로 동일 게임에 이전에 탐색한 유저가 들어가 있기만 해도, Match 정보 중복에 해당 Match에서 다시 유저 데이터 중복 접근이 발생한다. 그래서 고유값인 GameId를 저장해서 중복을 피하고자 SQLite 도입을 고려했다. 비교적 가볍게 리소스를 사용하도록 가져갔으면 좋겠고, Match 데이터의 경우 최대한 오래 저장하고 싶어 조건에 맞는 DBMS를 고려했다. 그렇지만 저장하는 데이터가 비교적 작고 단순하기 때문에 ACID를 지킬 이유가 없어 다른 저장 방식도 고민하고 있다.
추가적으로 이미 한 번 탐색한 유저의 Id에 대해서도 접근 시 중복 접근이 발생하고, API Request의 낭비로 이어지기 때문에 유저 Id에 대한 저장 및 중복 회피도 생각했다. 다만 유저의 경우 개개인의 특성에 따라 게임을 매일 많이 할 수도 있고, 일주일에서 한 달간 접속을 하지 않는다거나 다양한 유형이 존재하기 때문에 한번 탐색했더라도 새로운 정보 획득을 위해 접근이 필요할 수 있다. 그렇기 때문에 별도로 페이징 전략을 고려하고 있는데, 이 부분은 생각만 하고 확정 짓지는 않았다.
1. 특정 주기 데이터 삭제
간단하게 3일 ~ 일주일 정도 지난 유저 데이터는 삭제하는 방식이다. 한번 탐색한 지 오래된 유저일수록 접근하지 않는 동안 다른 매치를 진행했을 것으로 판단해서, 특정 주기 이후 다시 접근 가능하도록 설정하는 방법이다. GameId는 최대한 유지할 생각이므로 중복 데이터는 발생하지 않는 방법이나 특정 유저가 주기보다 오래 게임을 하지 않는 경우 불필요한 접근 횟수가 발생한다.
2. 접근 횟수 윈도우 방식
Match 내에 있는 유저를 접근 횟수를 늘려나가며 윈도우가 특정 크기를 넘으면 제일 적게 접근한 유저부터 삭제하는 방식이다. Match에서 자주 만나는 유저일수록 매치를 자주 진행했을 것으로 판단하는 방법이다. 이 또한 GameId를 유지하고 있으므로 중복 데이터가 발생하진 않는다. 하지만 이를 위한 접근 횟수를 유지해야 하는 문제가 있다.
3. 접근 순서 윈도우 방식
Match 내에 있는 유저를 윈도우에 올리면서 특정 크기를 넘으면 제일 오래 탐색이 안된 유저부터 삭제하는 방식이다. 최근 Match에서 만난 유저일수록 매치를 자주 진행할 것이라 판단하는 방법이다. 접근 횟수와 동일하나 각 유저에 대한 접근 일시를 추적해야 하고, 순서에 따라 오래된 유저를 빠르게 탐색할 수 있도록 구현이 어려워질 것이란 문제가 있다.
이렇게 게임 데이터를 수집한 이후에는 S3로 압축해서 데이터를 전송할 것이다. 데이터 저장부에서 얘기했듯이 Raw 데이터를 그대로 다 저장하기엔 비용의 문제가 크기 때문에 이를 압축해서 올릴 것이다. 여기서 이 압축의 주기가 수집 부분에서 결정된다. 전송 이전까지 Raw 데이터는 전부 수집 부분에서 들고 있어야 하고, 이는 EBS의 사용으로 이어진다. 그래서 EBS를 감당 가능한 수준만큼 해야 하고, 그러면서 데이터는 적절하게 필요시 열어볼 수 있도록 균형을 맞출 필요가 있다. 직접 데이터를 몇 번 다뤄보면서 그에 적절한 주기에 맞춰 압축을 진행할 예정이다.
위에서 설명한 방식들은 각각 스크립트나 시스템 내 스케줄로 작성할 것이다. 그렇기 때문에 DB와 Script를 구동할 Container를 두어 리소스가 오버되어도 에어플로우의 오케스트레이션에 최대한 영향을 주지 않도록 구성했다. 여기서 가장 핵심은 필요할 경우 오케스트레이션 담당인 Airflow와 데이터 수집 영역을 분리할 수 있게 구성하는 것이다. 오케스트레이션이 최대한 중단이 적어야 내가 외부에서 동작에 대해 확인할 수 있고, 적절하게 로그를 남기고 삭제할 수 있기에 수집으로 인해 침범 당하지 않는 것을 목표로 했다.
웹 서비스 부분
웹 서비스 부분의 핵심은 데이터 레이어와의 분리라고 생각했다. 데이터 중점의 프로젝트이기 때문에 웹 서비스는 비교적 많은 기능을 넣지 않을 생각이고, 주로 웹 페이지 내의 검색을 통한 데이터 서빙이 주요 기능이 될 것이다. 이용자가 많아서 발생하는 트래픽에 대한 데이터도 관리할 수 있다면 좋겠지만, 우선은 게임사 데이터를 주로 사용하기 때문에 분리를 통해 보안 및 안정성을 올리고자 했다.
우선 데이터의 경우 운용 가능한 데이터를 Gold 영역에서 저장하기 때문에 웹 서비스에서는 약 하루 정도의 기간으로 주기적으로 데이터를 가져올 생각이다. 이에 대해 이력을 저장하진 않고, 업데이트하는 방식을 사용함으로 웹 서비스 영역 내의 저장 비용을 줄이려고 한다. 그리고 이렇게 구성하면 실시간 데이터를 전달할 순 없지만, 데이터 수집이나 데이터 집계/분석이 중단되었을 때 실제 웹 서비스는 지속할 수 있도록 할 생각이다. 집계의 경우 아키텍처를 수정하면 실시간 데이터로 전달하고, 분석 내용만 배치 작업을 통해 전달할 순 있다. 하지만 일주일마다 패치가 진행되는 게임 특성상 실시간 데이터로 인한 기능의 문제가 발생하진 않을 것이라 판단했다.
DB의 경우 서비스 내에 데이터 입력은 거의 없다시피하고, 대부분 데이터 레이어의 데이터를 가져오는 방식이기 때문에 RDB를 통한 ACID를 지킬 이유가 없을 것이라 생각했다. 그래서 Read를 빠르게 진행할 수 있는 NoSQL만을 통해서 서비스를 진행할 생각이다.
그리고 웹 서비스도 온디맨드 구성이 필요하기 때문에 Spot 인스턴스를 사용하진 않을 생각이다. 또 다른 시스템에 비해 외부에 노출되는 부분이기에 트래픽이나 기타 API Call에 민감하게 반응할 수 없는 사이드 프로젝트 특성상 AWS Lightsail을 사용할 생각이다.

비용이 싼 것보단 정액제 요금을 통해 관리에 필요한 비용을 줄일 수 있을 것이라 도입을 고려했다. 데이터 레이어와 아예 별개이기 때문에 다른 플랫폼을 사용하는 것도 좋지만, S3에 저장할 생각이므로 AWS 내에서 찾았다. 월 단위 트래픽에 대한 문제가 좀 있지만 캐싱과 Nginx를 통한 트래픽 관리를 진행하면 테라바이트 단위 내에서 해결할 수 있을 것이라 생각했다.
기타
마지막으로 모든 시스템의 배포는 Github Action을 사용할 생각이다. 원래 프로젝트들은 Jeknins를 통해서 빌드 서버를 구성했는데, 단순히 이번엔 비용이 없다. 빌드 시에만 빌드 인스턴스가 돌아가도록 Spot 인스턴스를 사용할까 생각도 했는데, Jenkins 자체가 JVM 위에서 돌아가기 때문에 이를 컨트롤할 인스턴스에서 이미 너무 많은 리소스가 들어갔다. 그래서 사이드 프로젝트로 활용하는 만큼 간단하게 사용할 수 있는 Github Action을 사용해 볼 생각이다.
후기
생각했던 것보다 아키텍처 구성 및 블로깅에 시간이 오래 걸렸다. 회사 일이랑 병행하면서 생각하는게 생각보다 쉽진 않았나 보다. 최대한 비용을 생각하면서 구성해봤는데, 진짜 얼마가 들지 생각하면서 예산을 정하고 고려해보는게 쉽지는 않았다. 솔직히 과연 진짜 비용이 이렇게 어림 잡은 만큼 줄일 수 있을까 싶은 마음도 있다.
이제 프로젝트는 앞으로 데이터 엔지니어링 학습과 병행할 생각이고, 아키텍처를 정하면서 생겼던 몇 가지 문제를 해결할 필요가 있다.
1. 데이터 집계/분석 관련 기술 선정
2. 유저 Id 페이징 전략 선택
3. 데이터 압축 주기 고민
4. 데이터 전송 비용 고려
이외에도 아마 다음 개발은 데이터 저장 부분과 데이터 수집 부분부터 고려할 생각이므로 아래의 기술부터 공부할 계획을 가지고 있다,
1. Iceberg (데이터 저장 방식)
2. Airflow (오케스트레이션)
3. Docker (아키텍처 구성)
'이터널 리턴 조합 사이트 개발 일지' 카테고리의 다른 글
| 이터널 리턴 조합 분석 사이트 개발 - 프로젝트 기획 (0) | 2025.09.14 |
|---|