coredot.today
AWS Lambda 완전 정복: 함수 하나로 시작하는 서버리스 아키텍처
블로그로 돌아가기
LambdaAWS서버리스FaaSMSA마이크로서비스이벤트

AWS Lambda 완전 정복: 함수 하나로 시작하는 서버리스 아키텍처

2014년 '함수 하나만 실행하는 서비스'로 시작해, 전 세계 수백만 개발자의 기본 도구가 된 Lambda. 탄생 배경부터 내부 작동 원리, MSA와의 관계, 실전 패턴과 비용 최적화까지 — Lambda를 제대로 이해하고 활용하는 완전 가이드.

코어닷투데이2026-02-1730

들어가며: "함수 하나만 실행하는 서비스가 뭔 의미가 있지?"

2014년 11월, AWS re:Invent. VP Werner Vogels가 무대에서 새 서비스를 발표했다. 이름은 Lambda. "코드를 업로드하면 이벤트에 반응하여 자동으로 실행된다. 서버 관리 불필요. 사용한 100밀리초 단위로만 과금."

발표 직후 개발자 커뮤니티의 반응은 반신반의였다. "그래서 이걸로 뭘 하라는 건데?" "장난감 아닌가?" "실무에서 쓸 수 있을까?"

10년이 지난 지금, Lambda는 AWS에서 가장 많이 사용되는 서비스 중 하나가 됐다. Datadog의 2024년 보고서에 따르면 AWS를 사용하는 조직의 70% 이상이 Lambda를 사용한다. 하루에 수조 건의 호출이 전 세계에서 처리된다.

"함수 하나만 실행하는 서비스"가 어떻게 이렇게 됐을까? 그리고 당신의 서비스에서는 Lambda를 어떻게 활용해야 할까?


1. Lambda는 왜 탄생했는가

AWS 내부의 문제 인식

Lambda의 탄생 배경을 이해하려면, 2013~2014년 AWS가 목격한 패턴을 알아야 한다.

수많은 AWS 고객이 동일한 아키텍처 패턴을 반복하고 있었다:

  1. S3에 이미지가 업로드된다
  2. EC2 인스턴스가 이를 감지한다
  3. 이미지를 리사이징한다
  4. 결과를 다시 S3에 저장한다

이 과정에서 EC2 인스턴스는 이미지가 업로드될 때만 일한다. 나머지 시간에는 놀고 있다. 그런데 이 "대기 → 이벤트 감지 → 처리 → 대기" 패턴을 위해 서버를 24시간 켜놓아야 했다.

Tim Wagner (Lambda의 GM)는 2014년 블로그에서 이렇게 설명했다:

"고객들이 EC2 위에서 반복적으로 구현하는 글루(glue) 코드가 있었다. 이벤트를 감지하고, 작은 작업을 수행하고, 결과를 다른 서비스에 전달하는 코드. 우리는 이 패턴 자체를 서비스로 만들기로 했다."

학술적 배경: 이벤트 기반 컴퓨팅의 진화

Lambda의 아이디어는 컴퓨터 과학의 오랜 개념에 뿌리를 두고 있다.

1936년 — 람다 대수(Lambda Calculus): 수학자 Alonzo Church가 개발한 함수 추상화 체계. "이름 없는 함수"로 연산을 표현하는 방법. AWS Lambda의 이름은 여기서 따왔다 — 입력을 받아 출력을 반환하는 순수 함수라는 개념.

1990~2000년대 — 이벤트 기반 아키텍처: Martin Fowler 등이 정리한 EDA(Event-Driven Architecture) 패턴. 시스템 간 통신을 직접 호출이 아닌 이벤트(메시지)로 하는 아키텍처. Lambda는 이 패턴을 클라우드에서 가장 쉽게 구현하는 방법이 됐다.

2014년 — AWS Lambda 출시: 이 두 아이디어의 결합. 순수 함수(입력 → 처리 → 출력) + 이벤트 트리거(이벤트가 오면 함수 실행) = FaaS.


2. Lambda의 작동 원리

핵심 개념: 함수 = 실행의 최소 단위

Lambda에서 배포하는 단위는 함수(Function) 다. 하나의 함수는 하나의 작업을 수행한다.

hljs language-python
# 가장 간단한 Lambda 함수
def lambda_handler(event, context):
    name = event.get("name", "World")
    return {
        "statusCode": 200,
        "body": f"Hello, {name}!"
    }
  • event: 함수를 트리거한 이벤트 데이터 (HTTP 요청, S3 이벤트, SQS 메시지 등)
  • context: 실행 환경 정보 (남은 시간, 메모리, 요청 ID)
  • 반환값: 호출자에게 돌려줄 결과

이 함수를 Lambda에 올리면, 누군가 HTTP 요청을 보내거나, S3에 파일을 올리거나, SQS에 메시지가 도착할 때마다 자동으로 실행된다.

내부 아키텍처: Firecracker microVM

이전 Fargate 글에서 소개한 Firecracker가 Lambda의 기반이기도 하다.

각 Lambda 함수 호출은 전용 Firecracker microVM 안에서 실행된다:

이벤트 도착 (API 요청, S3 업로드 등)
Lambda 서비스가 Firecracker microVM 생성 (~125ms)
런타임 초기화 (Python, Node.js 등)
함수 코드 로드 + 핸들러 외부 초기화 실행
핸들러 함수 실행 (여기부터 과금)
결과 반환 → 실행 환경 "동결" (재사용 대기)

핵심 포인트: 실행 환경은 즉시 삭제되지 않고 "동결(freeze)" 된다. 같은 함수에 곧 다시 요청이 오면 동결된 환경을 "해동(thaw)" 하여 재사용한다. 이것이 웜 스타트(Warm Start) — 콜드 스타트 없이 밀리초 단위로 응답한다.

이벤트 소스: Lambda를 깨우는 100가지 방법

Lambda의 진짜 힘은 AWS의 거의 모든 서비스가 Lambda를 트리거할 수 있다는 것이다.

이벤트 소스트리거 시점대표적 사용 사례
API GatewayHTTP 요청 도착REST/GraphQL API 구현
S3파일 업로드/삭제이미지 리사이징, 파일 처리
DynamoDB StreamsDB 레코드 변경변경 감지, 동기화, 알림
SQS메시지 큐 도착비동기 작업 처리
EventBridge스케줄/이벤트 패턴 매칭크론 작업, 이벤트 라우팅
SNS알림 발행팬아웃, 알림 처리
Kinesis스트림 데이터 도착실시간 데이터 처리
CloudWatch Events리소스 상태 변경인프라 자동화
Cognito사용자 인증 이벤트가입 후처리, 토큰 커스터마이징
IoT CoreIoT 디바이스 메시지센서 데이터 처리
💡
핵심 인사이트: Lambda를 "함수 실행 서비스"로만 보면 과소평가다. Lambda는 AWS 서비스들을 연결하는 "접착제(glue)"다. S3 → Lambda → DynamoDB, SQS → Lambda → SNS — 이런 이벤트 기반 파이프라인을 서버 없이 구축하는 것이 Lambda의 진짜 가치다.

3. Lambda와 마이크로서비스 아키텍처 (MSA)

모놀리스에서 마이크로서비스로

모놀리식 아키텍처에서는 하나의 거대한 애플리케이션이 모든 기능을 포함한다. 사용자 인증, 주문 처리, 결제, 알림 — 모두 하나의 코드베이스, 하나의 배포 단위.

이 구조의 한계:

  • 한 기능을 수정하면 전체를 다시 배포해야 한다
  • 주문 처리의 버그가 인증 시스템까지 죽일 수 있다
  • 팀이 커지면 코드 충돌이 빈번해진다
  • 특정 기능만 스케일 아웃할 수 없다 (전체를 복제해야 함)

MSA(Microservices Architecture)는 이 문제를 서비스를 독립적인 작은 단위로 분리하여 해결한다. 각 서비스가 독립적으로 개발·배포·스케일링된다.

Lambda는 MSA의 극단적 형태다

MSA를 구현하는 방법은 여러 가지다:

MSA 구현 스펙트럼
모놀리스 하나의 거대 서비스
마이크로서비스 도메인별 서비스 ECS / K8s
나노서비스 함수 단위 서비스 Lambda

전통적 마이크로서비스는 도메인 단위로 분리한다: 주문 서비스, 결제 서비스, 사용자 서비스.

Lambda 기반 아키텍처는 이것을 더 잘게 쪼갠다: 기능(함수) 단위로 분리. 주문 생성 함수, 주문 검증 함수, 결제 요청 함수, 결제 확인 함수, 알림 발송 함수...

이 접근의 장점:

  • 극단적 독립성: 함수 하나를 수정해도 다른 함수에 영향 없음
  • 극단적 스케일링: 결제가 폭주하면 결제 함수만 수천 개로 확장
  • 비용 효율: 각 함수가 호출될 때만 비용 발생

하지만 단점도 명확하다:

  • 분산 시스템의 복잡성: 함수가 수십~수백 개가 되면 관리가 어려움
  • 콜드 스타트: 자주 호출되지 않는 함수는 매번 콜드 스타트
  • 디버깅 난이도: 수십 개 함수의 호출 체인을 추적해야 함
⚠️
실전 조언 — "Lambda per API endpoint"의 함정: API 엔드포인트마다 Lambda 함수를 하나씩 만드는 것은 초기에는 깔끔해 보이지만, API가 50개를 넘으면 관리가 악몽이 된다. 실무에서는 도메인별로 하나의 Lambda 함수(내부에서 라우팅)를 권장한다. "모놀리식 Lambda"라고 부르기도 한다.

실전 MSA 패턴: 오케스트레이션 vs 코레오그래피

Lambda 기반 MSA에서 서비스 간 통신에는 두 가지 패턴이 있다:

오케스트레이션 (Step Functions)
중앙 조율자가 각 함수를 순서대로 호출
워크플로우가 명시적으로 정의됨
에러 처리·재시도가 중앙에서 관리
디버깅이 쉬움 (실행 기록 시각화)
적합: 주문 처리처럼 순서가 중요한 워크플로우
코레오그래피 (EventBridge)
각 함수가 이벤트를 발행하고 구독
중앙 조율자 없이 느슨한 결합
각 함수가 자체적으로 에러 처리
전체 흐름 추적이 어려움
적합: 알림, 로깅처럼 독립적 반응

4. Lambda 실전 가이드

함수 작성의 핵심 원칙

1. 핸들러는 가볍게, 초기화는 밖에서

hljs language-python
import boto3

# 핸들러 밖에서 초기화 → 웜 스타트 시 재사용
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table("users")

def lambda_handler(event, context):
    # 핸들러 안에서는 비즈니스 로직만
    user_id = event["pathParameters"]["id"]
    response = table.get_item(Key={"id": user_id})
    return {
        "statusCode": 200,
        "body": json.dumps(response.get("Item", {}))
    }

boto3.resource() 호출은 핸들러 밖에 둔다. 첫 번째 호출(콜드 스타트)에서만 실행되고, 이후 웜 스타트에서는 재사용된다. 이것만으로 응답 시간이 50~200ms 단축된다.

2. 함수는 한 가지 일만

하나의 Lambda 함수가 "이미지 리사이징 + 메타데이터 저장 + 알림 발송"을 모두 하면, 알림 서비스 장애가 이미지 처리까지 막는다. 각 작업을 별도 함수로 분리하고, 이벤트(SQS, EventBridge)로 연결한다.

3. 멱등성(Idempotency) 보장

Lambda는 최소 1회(at-least-once) 실행을 보장한다. 드물지만 같은 이벤트로 함수가 두 번 실행될 수 있다. 같은 요청이 두 번 와도 결과가 동일하도록 설계해야 한다.

hljs language-python
# 나쁜 예: 중복 실행 시 잔액이 두 번 차감됨
balance -= amount

# 좋은 예: 트랜잭션 ID로 중복 확인
if not is_processed(transaction_id):
    balance -= amount
    mark_processed(transaction_id)

콜드 스타트 최적화

전략효과비용
경량 런타임 (Python, Node.js)콜드 스타트 100~300ms무료
패키지 크기 최소화로드 시간 단축무료
Provisioned Concurrency콜드 스타트 제거인스턴스 유지 비용
SnapStart (Java)콜드 스타트 90% 단축무료
Lambda Layer로 공통 라이브러리 분리배포 크기 감소무료
ARM64 (Graviton2)시작 시간 + 비용 동시 절감무료 (오히려 20% 저렴)
가장 효과적인 조합: Python 또는 Node.js + ARM64(Graviton2) + 패키지 최소화. 이것만으로 대부분의 API 응답이 콜드 100~200ms, 웜 5~20ms 수준이 된다. Java가 필수라면 SnapStart를 반드시 활성화하라.

비용 구조와 최적화

Lambda의 비용은 두 가지로 구성된다:

요청 수: 100만 건당 0.20(100만건/월무료)실행시간:GB초당0.20 (첫 100만 건/월 무료) **실행 시간**: GB-초당 0.0000166667 (1ms 단위 과금)

실제 비용 시뮬레이션:

$0 월 100만 건, 200ms 프리 티어 범위 내
~$18 월 1,000만 건, 200ms 128MB 메모리 기준
~$220 월 1억 건, 200ms 128MB 메모리 기준

비용 최적화 핵심:

  • 메모리 = CPU 성능: Lambda에서 메모리를 늘리면 CPU도 비례하여 증가. 128MB → 256MB로 올렸을 때 실행 시간이 반으로 줄면 비용은 동일. AWS Lambda Power Tuning 도구로 최적 메모리를 찾아라
  • ARM64 전환: x86 대비 20% 저렴하면서 대부분의 워크로드에서 성능 동등 이상
  • 실행 시간 최소화: 외부 API 호출은 타임아웃을 짧게, DB 연결은 밖에서 초기화

5. Lambda 실전 아키텍처 패턴

패턴 1: REST API (가장 흔한 패턴)

클라이언트 (웹/앱)
API Gateway
Lambda 함수
DynamoDB / RDS / 외부 API

API Gateway가 HTTP 요청을 받아 Lambda로 전달하고, Lambda가 비즈니스 로직을 수행한 뒤 응답을 반환한다. 가장 기본적이고 가장 많이 쓰이는 패턴이다.

패턴 2: 이벤트 기반 파이프라인

사용자가 프로필 사진 업로드
       ↓
S3에 원본 저장 → S3 이벤트 트리거
       ↓
Lambda A: 이미지 리사이징 (썸네일, 중간, 대형)
       ↓
리사이징된 이미지를 S3에 저장 → 완료 이벤트
       ↓
Lambda B: DynamoDB에 메타데이터 업데이트
       ↓
Lambda C: CloudFront 캐시 무효화

각 Lambda가 자신의 작업만 수행하고, 이벤트로 다음 단계를 트리거한다. 서버를 한 대도 관리하지 않는 완전한 이벤트 기반 파이프라인이다.

패턴 3: 워크플로우 오케스트레이션 (Step Functions)

주문 처리처럼 순서가 중요한 작업에는 AWS Step Functions을 사용한다:

  1. 주문 검증 (Lambda)
  2. 재고 확인 (Lambda)
  3. 결제 처리 (Lambda) — 실패 시 재시도 3회
  4. 배송 요청 (Lambda)
  5. 확인 이메일 발송 (Lambda)

각 단계의 성공/실패/재시도/타임아웃을 Step Functions가 관리한다. Lambda 함수는 자기 로직에만 집중하면 된다.

패턴 4: 크론 작업 (스케줄 기반)

EventBridge 스케줄러로 정기 작업을 실행한다:

  • 매일 새벽 3시: DB 정리 Lambda 실행
  • 매 시간: 외부 API에서 환율 가져오기
  • 매주 월요일: 주간 리포트 생성 + 이메일 발송

EC2를 24시간 켜놓을 필요 없이, 실행되는 시간만 과금된다.

패턴 5: 실시간 스트림 처리

Kinesis 스트림 또는 DynamoDB Streams와 연동하여 실시간 데이터를 처리한다:

  • IoT 센서 데이터 → Kinesis → Lambda → 이상 감지 → 알림
  • 사용자 활동 로그 → DynamoDB Streams → Lambda → 분석 + 추천

6. 실제 사례: Lambda를 쓰는 기업들

Netflix: 미디어 파이프라인

Netflix는 동영상 파일이 업로드되면 Lambda가 자동으로 여러 인코딩 작업을 트리거한다. 각 해상도(4K, 1080p, 720p)별 인코딩, 자막 처리, 메타데이터 추출 — 이 모든 것이 이벤트 기반으로 동작한다.

콘텐츠가 업로드되지 않는 시간에는 비용이 0이다. 새 시즌이 공개되어 대량 업로드가 발생하면 자동으로 수천 개의 Lambda가 병렬 실행된다.

Coca-Cola: IoT 자판기 네트워크

이전 서버리스 글에서 언급한 사례를 더 구체적으로 보자. 전 세계 수백만 대의 자판기가 결제·재고 이벤트를 발생시키면:

  1. IoT Core가 이벤트를 수신
  2. Lambda가 결제 검증 + 재고 차감
  3. DynamoDB에 트랜잭션 기록
  4. 재고가 임계값 이하면 SNS로 보충 알림

이 전체 아키텍처에 EC2 인스턴스가 한 대도 없다.

Bustle: 미디어 서비스의 완전 서버리스 전환

디지털 미디어 회사 Bustle은 매달 10억 건 이상의 요청을 Lambda로 처리한다. EC2 기반에서 Lambda로 전환하면서:

  • 인프라 비용 84% 절감
  • 운영 인력 0명 (인프라 관리 전담자 불필요)
  • 배포 시간 분 단위

한국 기업 사례

  • 배달의민족: 주문 이벤트 처리, 푸시 알림, 쿠폰 검증을 Lambda로 처리
  • 당근마켓: S3에 업로드된 중고 거래 이미지를 Lambda@Edge로 즉시 리사이징. CDN에서 가장 가까운 엣지에서 처리하여 지연 최소화
  • 뱅크샐러드: 금융 데이터 수집·가공 파이프라인을 Lambda + Step Functions으로 구축

7. Lambda의 진화: 2014년에서 2026년까지

2014
출시: Node.js만 지원, 최대 60초
초기에는 "장난감"이라는 반응도. S3, Kinesis, DynamoDB 트리거만
2016
Python, Java, C# 추가. API Gateway 연동
서버리스 REST API가 가능해짐. 실무 채택 급증
2018
Lambda Layers, Custom Runtimes, ALB 연동
어떤 언어든 실행 가능. 공통 라이브러리 공유
2019
Provisioned Concurrency
콜드 스타트 제거 옵션. 금융·실시간 서비스에서 채택
2020
컨테이너 이미지 지원 (최대 10GB)
Docker 이미지를 Lambda에서 직접 실행. ML 모델 배포 가능
2022
Lambda SnapStart, Function URLs
Java 콜드 스타트 90% 단축. API Gateway 없이 직접 HTTP 엔드포인트
2024–2026
1ms 과금, 15분 실행, 10GB 메모리, ARM64
초기 제약이 대부분 해소. 서버리스와 컨테이너의 경계가 흐려짐

2014년의 Lambda와 2026년의 Lambda는 사실상 다른 서비스다. 초기의 "60초 제한, Node.js만" 같은 제약은 대부분 해소됐다. 15분 실행 시간, 10GB 메모리, 컨테이너 이미지 지원 — 이제 Lambda로 할 수 없는 것은 거의 없다.


8. Lambda를 쓰지 말아야 할 때

모든 도구에는 한계가 있다. Lambda가 최선이 아닌 경우:

상황이유대안
15분 이상 실행Lambda 시간 제한Fargate, ECS
GPU 필요 (AI 학습)Lambda GPU 미지원EC2 P/G 인스턴스, SageMaker
WebSocket 장시간 연결Lambda는 요청-응답 모델ECS, AppRunner
초당 수만 건의 상시 트래픽비용이 EC2보다 높아짐ECS + EC2
복잡한 로컬 개발/디버깅서버리스 환경 재현 어려움SAM Local, LocalStack
최종 판단 기준: Lambda를 선택할지 고민될 때, 이 질문을 해보라: "이 워크로드가 24시간 쉬지 않고 동일한 부하로 실행되는가?" 답이 "아니오"라면 Lambda가 거의 항상 더 효율적이다. 답이 "예"라면 EC2/ECS가 더 저렴할 수 있다.

마치며: Lambda는 "문제 해결의 최소 단위"다

Lambda의 본질은 이렇다:

"문제를 함수 하나의 크기로 쪼개고, 이벤트에 반응하여 자동으로 실행되게 하는 것."

이것은 단순한 기술 선택이 아니라 사고방식의 전환이다. "어떤 서버에서 실행할까?"가 아니라 "어떤 이벤트에 반응해야 할까?"를 먼저 생각하는 것. "서버를 몇 대 준비할까?"가 아니라 "함수가 얼마나 빨리 응답해야 할까?"를 고민하는 것.

Alonzo Church의 람다 대수가 "이름 없는 함수"로 계산을 추상화했듯, AWS Lambda는 "서버 없는 함수"로 인프라를 추상화했다. 이름의 선택은 우연이 아니었다.

코어닷투데이의 AI 서비스에서도 Lambda는 곳곳에서 활용된다. 이미지 전처리, 이벤트 기반 알림, 데이터 파이프라인, API 엔드포인트 — 각각의 작업이 함수 하나의 크기로 정의되고, 필요할 때만 실행되며, 완료되면 사라진다. 인프라가 보이지 않는 곳에서, 문제 해결이 함수 단위로 일어나고 있다.