AWS Lambda란 무엇인가요?

AWS Lambda (줄여서 Lambda)는 AWS가 제공하는 서버리스 컴퓨팅 서비스입니다. 이번 장에서는 Lambda를 사용해 서버리스 애플리케이션을 구축할 것입니다. Lambda의 내부 동작 방식을 직접 다룰 필요는 없지만, 여러분의 함수가 어떻게 실행되는지 대략적으로 이해하는 것이 중요합니다.

Lambda 스펙

AWS Lambda의 기술 사양을 간단히 살펴보겠습니다. Lambda는 다음 런타임을 지원합니다.

  • Node.js 18.x, 16.x, 14.x
  • Java 17, 11, 8
  • Python 3.11, 3.10, 3.9, 3.8, 3.7
  • .NET 7, 6
  • Go 1.x
  • Ruby 3.2, 2.7
  • Rust

사용 가능한 런타임에 대해 더 알아보려면 AWS 문서를 확인하세요.

각 함수는 64비트 Amazon Linux AMI가 설치된 컨테이너 내에서 실행됩니다. 실행 환경은 다음과 같습니다.

  • 메모리: 128MB - 10240MB, 1MB 단위로 조정 가능
  • 임시 디스크 공간: 512MB - 10240MB, 1MB 단위로 조정 가능
  • 최대 실행 시간: 900초
  • 압축 패키지 크기: 50MB
  • 압축 해제 패키지 크기: 250MB
  • 컨테이너 이미지 패키지 크기: 10GB

CPU가 컨테이너 사양에 포함되지 않은 것을 눈치챘을 겁니다. 이는 CPU를 직접 제어할 수 없기 때문입니다. 메모리를 늘리면 CPU도 함께 증가합니다.

임시 디스크 공간은 /tmp 디렉토리 형태로 제공됩니다. 이 공간은 임시 저장용으로만 사용할 수 있으며, 이후 호출에서는 이 공간에 접근할 수 없습니다. Lambda 함수의 상태 비저장 특성에 대해서는 아래에서 더 자세히 설명하겠습니다.

실행 시간은 Lambda 함수가 최대 900초(15분) 동안 실행될 수 있음을 의미합니다. 따라서 Lambda는 장시간 실행되는 프로세스에 적합하지 않습니다.

패키지 크기는 함수 실행에 필요한 모든 코드를 포함합니다. 여기에는 함수가 임포트할 수 있는 모든 종속성(Node.js의 경우 node_modules/ 디렉토리)도 포함됩니다. 압축 해제된 패키지 크기는 최대 250MB, 압축된 패키지 크기는 최대 50MB로 제한됩니다. 더 많은 공간이 필요하다면 최대 10GB까지 가능한 Docker 이미지로 패키징할 수 있습니다. 패키징 프로세스는 아래에서 살펴보겠습니다.

Lambda Function

마지막으로 Node.js를 사용한 Lambda 함수의 모습입니다.

export const handler = async (event, context) => {
  // 작업 수행

  return {
    statusCode: 200,
    body: "Hello World!"
  };
};

여기서 handler는 Lambda 함수의 이름입니다. 이 함수는 async 함수입니다. event 객체는 이 Lambda를 트리거한 이벤트에 대한 모든 정보를 포함합니다. HTTP 요청의 경우, 특정 HTTP 요청에 대한 정보가 포함됩니다. context 객체는 Lambda 함수가 실행 중인 런타임에 대한 정보를 포함합니다.

Lambda 함수 내부에서 모든 작업을 수행한 후, 간단히 반환합니다. 이 함수가 API Gateway에 연결된 경우, 응답 HTTP 상태 코드와 본문을 반환할 수 있습니다.

함수 패키징

람다 함수는 패키징되어 AWS로 전송되어야 합니다. 일반적으로 함수와 모든 의존성을 압축한 후 S3 버킷에 업로드하는 과정입니다. 그리고 특정 이벤트가 발생할 때 이 패키지를 사용하도록 AWS에 알립니다. 이 과정을 도와주기 위해 SST를 사용합니다. 이 가이드에서 나중에 자세히 설명하겠습니다.

실행 모델

우리의 함수를 실행하는 컨테이너(및 그 컨테이너가 사용하는 리소스)는 AWS에 의해 완전히 관리됩니다. 이 컨테이너는 이벤트가 발생할 때 시작되고, 사용되지 않을 때는 종료됩니다. 원래 이벤트가 처리되는 동안 추가 요청이 들어오면, 새로운 컨테이너가 시작되어 요청을 처리합니다. 이는 사용량이 급증할 경우, 클라우드 제공자가 단순히 여러 개의 컨테이너 인스턴스를 생성하여 요청을 처리한다는 것을 의미합니다.

이러한 방식은 몇 가지 흥미로운 영향을 미칩니다. 첫째, 우리의 함수는 사실상 상태를 유지하지 않습니다. 둘째, 각 요청(또는 이벤트)은 단일 Lambda 함수 인스턴스에 의해 처리됩니다. 이는 여러분의 코드에서 동시 요청을 처리하지 않는다는 것을 의미합니다. AWS는 새로운 요청이 있을 때마다 컨테이너를 시작합니다. 여기서 몇 가지 최적화를 수행하는데, 컨테이너를 몇 분 동안(부하에 따라 5~15분) 유지하여 콜드 스타트 없이 후속 요청에 응답할 수 있도록 합니다.

상태 비저장 함수(Stateless Functions)

위의 실행 모델은 Lambda 함수를 효과적으로 상태 비저장으로 만듭니다. 이는 Lambda 함수가 이벤트에 의해 트리거될 때마다 완전히 새로운 환경에서 호출된다는 것을 의미합니다. 이전 이벤트의 실행 컨텍스트에 접근할 수 없습니다.

하지만 앞서 최적화에서 언급했듯이, AWS는 기존 컨테이너를 몇 분 동안 유지하고 이를 사용해 요청에 응답합니다. 따라서 해당 컨테이너 인스턴스에서는 Lambda 함수 주변의 코드가 한 번만 호출됩니다. 반면 실제 Lambda 함수는 각 요청마다 호출됩니다.

예를 들어, 아래의 createNewDbConnection 메서드는 컨테이너 인스턴스당 한 번 호출되며, Lambda 함수가 호출될 때마다 호출되지 않습니다. 반면 handler 함수는 매번 호출됩니다.

var dbConnection = createNewDbConnection();

export const handler = async (event, context) => {
  var result = dbConnection.makeQuery();
  return {
    statusCode: 200,
    body: JSON.stringify(result)
  };
};

이 컨테이너의 캐싱 효과는 앞서 언급한 /tmp 디렉토리에도 적용됩니다. 컨테이너가 캐시되는 동안 이 디렉토리를 사용할 수 있습니다.

이제 여러분은 이 방법이 Lambda 함수를 상태 저장으로 만드는 데 매우 신뢰할 수 있는 방법이 아니라는 것을 짐작할 수 있습니다. Lambda가 호출되거나 컨테이너가 캐시되는 기본 프로세스를 우리가 제어할 수 없기 때문입니다.

가격 정책

마지막으로, Lambda 함수는 함수 실행 시간에 대해서만 요금이 청구됩니다. 이는 함수 실행이 시작되는 시점부터 반환되거나 종료될 때까지의 시간을 기준으로 계산되며, 가장 가까운 1ms 단위로 반올림됩니다.

AWS가 Lambda 함수가 완료된 후에도 컨테이너를 유지할 수 있지만, 이에 대해서는 요금이 청구되지 않습니다.

Lambda는 매우 관대한 무료 티어를 제공하며, 이 가이드를 진행하는 동안 이 티어를 초과할 가능성은 낮습니다.

Lambda 무료 티어에는 매월 1백만 건의 무료 요청과 400,000 GB-초의 컴퓨팅 시간이 포함됩니다. 이를 초과할 경우, 1백만 건당 $0.20, 그리고 GB-초당 $0.00001667의 요금이 부과됩니다. GB-초는 Lambda 함수의 메모리 사용량을 기준으로 계산됩니다. 1년 또는 3년 약정을 통해 AWS Compute Savings Plan을 구매하면 최대 17%까지 비용을 절약할 수 있습니다. 자세한 내용은 Lambda 가격 페이지를 참조하세요.

우리의 경험상, Lambda는 일반적으로 인프라 비용 중 가장 저렴한 부분입니다.

다음으로, 데모 앱을 실행하는 총 비용을 포함하여 서버리스의 장점에 대해 더 깊이 알아보겠습니다.