본문 바로가기

프로젝트

[기록] ec2, lambda, 서버 구성에 대한 고민

최근 졸업 팀 프로젝트에서 백엔드 서버 구현 역할을 맡고 있다. 내가 맡은 역할은 크게 2가지로 나눌 수 있겠다.

  1. nest.js 기반 API 백엔드 구성
  2. cron(스케줄) 기반으로 동작하는 데이터 스크래핑 로직 구현

현재 글에서는 2번 항목에 대한 고민을 기록한다.


이전에 네이버 뉴스 URL 분석 및 댓글 API 분석에 대한 글을 작성한 적이 있다.

두 가지 분석 결과를 기반으로 키워드에 대한 기사 및 댓글 목록을 가져오는 함수를 작성했다.

https://github.com/blaxsior/crawler-project/tree/master/server/src/crawling

여기서부터 고민거리는 이 함수를 어떤 환경에서 동작시킬까에 대한 부분이었다. 처음 고려한 점은 AWS EC2를 이용하는 방식이었다. nest.js 는 @nestjs/schedule 모듈을 통해 cron 기반 스케줄링 방식을 제공한다. 어차피 백엔드 API도 nest.js를 사용하겠다, 처음에는 BatchService를 활용하여 구현하는 방향성을 잡았다.

// batch.module.ts
import { Logger, Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';
import { BatchService } from './batch.service';

@Module({
  imports: [ScheduleModule.forRoot()],
  providers: [BatchService, Logger],
})
export class BatchModule {}


// batch.service.ts
import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';

@Injectable()
export class BatchService {
  constructor(private logger: Logger) {}
  @Cron('0/10 * * * * *') // 10초마다 실행
  batch() {
    this.logger.log('hello');
  }
}

 

그런데, 현재 구현한 데이터 스크래핑 함수의 경우 로컬 기준(i7 7850) 기사 1개, 댓글 100여개를 가져오는데 0.5초 정도의 시간을 소요했고, 대략 6개의 언론사로부터 데이터를 가져와도 키워드 1개에 1분 정도면 충분하다는 결과가 나왔다.

코드를 실행한 결과

 여기서, EC2 프리티어는 기본 메모리가 1GB에 CPU 크레딧 개념이 존재해서 바쁜 작업을 수행하게 되면 먹통이 될 수 있는 문제가 있다. 과거 진행했던 프로젝트에서 EC2 프리티어를 사용했는데, 겨우 데이터 100개 정도를 삽입하려 시도할 때마다 먹통이 되어 울며 겨자먹기로 데이터를 분할해서 삽입한 경험이 있다. 이 경험을 바탕으로, API 서버에 스케줄러를 같이 올려서 자정이 될 때마다 API 서버마저 먹통이 될 위험을 배제하기 위해 API 서버는 반드시 스케줄러와 분리하여 사용하자고 생각했다.

이미 스케줄러는 API 서버와 결별했으므로, 동작하기 위한 방법은 다른 서버를 사용하거나 서버리스 서비스를 이용하는 방법밖에 없다. 이때 EC2는 프리티어 기간이 아니면 겨우 켜놓는 것만으로도 10000원이 넘게 필요한 자원이라, 하루의 절반도 동작하지 않는 스크래핑 기능을 위해 따로 EC2 환경을 제공하는 것은 너무 아깝다는 생각이 들었다.


aws lambda는 AWS의 서버리스 컴퓨팅 플랫폼으로 사용한 만큼만 돈을 내면 된다. 프리티어 기준으로는 EC2와 별개로 가격이 책정되기 때문에 둘 다 무료로 사용할 수 있다는 점도 가난한 졸업 예정자 입장에서는 눈에 띄는 옵션이었다.

다만 사용하기 위해 조사해보니, 일부 제약점도 존재했다.

  • 함수를 오랜만에 실행할 경우 코드 복사 + 컨테이너 실행 시간이 필요하다.
  • 한 번에 15분 이상 실행할 수 없다.

첫번째 문제의 경우 어차피 사용자의 응답이 필요한 부분이 아니라, 큰 상관이 없다는 생각이 들었다. 찾아보니 이 문제는 프로비저닝 또는 event bridge에서 일정 시간마다 실행되도록 처리하여 해결할 수 있다고 한다.

 두번째 문제의 경우 내가 예상하지 못한 부분이다. 내 환경에서 10초 정도 걸리는 작업이 lambda에서 대략 20 ~ 30초 걸린다는 것을 알게 되었기에, 단순히 모든 키워드를 하나의 람다 함수에서 처리하겠다고 하면 많아봤자 키워드 5개 정도밖에 처리할 수 없다. 인터넷을 찾아보니, 15분이 될 때마다 새로운 람다 함수를 호출하는 방식으로 지속시간을 늘릴 수 있다는 설명이 있었는데, 이 부분에 대해서는 어떻게 구현해야 할지에 대해 좀 더 고민이 필요할 것 같다.