gony-dev 님의 블로그

Section 21. AWS 서버리스: Lambda - 1 본문

AWS

Section 21. AWS 서버리스: Lambda - 1

minarinamu 2024. 11. 3. 18:04

 

서버리스란
서버가 없는 상태가 아니라
서버를 관리할 필요가 없는 상태를 의미한다.

AWS Lambda

람다를 설명하기에 앞서 EC2를 설명하자면 클라우드의 가상 서버라서 프로비저닝을 해야한다.
또한 메모리와 CPU 크기가 제한되며 계속 실행해주어야 하는 특징이 있다.
ASG로 스케일링이 가능하지만 이는 자동으로 추가해주고 삭제해야하는 것을 의미한다.

하지만 람다는 가상의 함수로 관리할 서버 없이, 코드를 프로비저닝하고 함수를 실행한다.
시간제한이 있어서 실행 시간이 짧지만 최대 15분이라 큰 단점은 아니다.
on-demand로 실행되어 호출하지 않으면 실행되지 않아 비용도 호출 횟수에 따라 청구된다.
스케일링 또한 자동화 되어 있다는 장점이 있다.

 

Lambda의 장점

  • Easy Pricing
    • 람다가 수신하는 요청의 숫자에 따라 청구되며, 이는 호출 숫자 및 컴퓨팅 시간에 따른다.
    • 프리 티어에서는 람다 요청 1백만 개와 컴퓨팅 시간 40만 GB를 제공해준다.
  • 다양한 AWS 서비스와 통합된다.
  • 많은 프로그래밍 언어를 사용할 수 있어서 자유롭다.
  • CloudWathch를 통해 모니터링하기 쉽다.
  • 함수랑 많은 리소스를 얻기 쉽다.
  • RAM을 증가시키면 CPU와 네트워크가 향상된다.

AWS Lambda가 지원하는 언어

  • Node.js, Python, Java, C#, Goland, C3 Powershell, Custom Runtime API 등등 여러 언어가 가능하다.
  • 람다 컨테이너 이미지 | 컨테이너 이미지는 람다 런타임 API를 구현해야만 한다.(ECS나 Fargate에서 컨테이너를 실행한다.)

 

AWS Lambda를 사용하여 S3 이벤트 알림에 대한 썸네일 생성을 실행


Lambda - Synchronous Invocations

CLI, SDK, API Gateway, ALB를 사용하고 있을 때 동기식 호출을 사용한다.
동기식이란 결과가 바로 사용자에게 돌아오는 과정을 의미한다.
에러는 클라이언트 측에서 해결해야만 한다.
api gateway의 경우, 람다를 프록시하여 반응을 얻어낸다.

 

람다와 동기식에 해당하는 서비스

  • 사용자가 호출했을 경우:
    • ELB(ALB)
    • Amazon API Gateway
    • Amazon CloudFront
    • Amazon S3 Batch
  • 서비스가 호출했을 경우:
    • Amazon Cognito
    • AWS Step Functions
  • 다른 서비스:
    • Lex
    • Alexa
    • Kinesis Data Firehose

Lambda Integration with ALB

람다 함수를 HTTP나 HTTPS 엔드포인트로 노출시키기 위해서 ALB를 사용할 수 있다!
ALB가 작동하기 위해서는 람다 함수를 대상 그룹에 등록해야만 한다.
그러면 ALB는 대상 그룹에 있는 람다 함수를 동기식으로 호출을 하게 된다.

 

ALB to Lambda: HTTP to JSON

  • ALB에서 람다로 갈 때 HTTP는 JSON 문서로 변환된다.

JSON 형태의 요청의 세부 사항들

Lambda to ALB conversions: JSON to HTTP

  • 람다 함수의 응답을 확인할 때는 아주 단순하다.


Lambda - Asynchronous Invocations

비동기식 호출은 람다 함수를 뒤에서 불러오는 서비스를 위한 것으로 Amazon S3, SNS, CloudWatch 이벤트 등이 있다.
람다 함수는 에러에 대해 여러 번 재시도를 하기 때문에 멱등적이여야 함을 명심해야 한다.

람다와 비동기식에 해당하는 서비스

  • Amazon Simple Storage Service(S3)
  • Amazon Simple Notification Service(SNS)
  • Amazon CloudWatch Events / EventBridge
  • AWS CodeCommit(람다 함수를 트리거함)
  • AWS CodePipeline
  • 다른 서비스
    • CloudWatch Logs
    • Simple Email Service
    • CloudFormation
    • Config
    • IoT

S3 Events Notifications

  • S3 이벤트 알림은 객체가 생성, 제거, 복구, 복제가 일어날 때 알림을 해주는 기능으로 접두어와 접미어로 필터링이 가능하다.
  • S3에 업로드된 모든 이미지 파일의 썸네일을 생성할 때 사용된다.
  • S3 이벤트 알림은 전형적으로 몇 초안에 이벤트를 보내지만, 가끔 몇 분이 더 걸릴 수도 있다.
  • 이벤트 알림을 하나도 놓치고 싶지 않다면 버킷에 버저닝을 반드시 활성화해야한다. 그렇지 않으면 하나의 오브젝트에 동시에 두 개의 작성이 일어날 때, 하나의 알림 밖에 받지 못하게 된다.

람다로 바로 보내는 경우는 비동기식 호출


Lambda - Event Source Mapping

이벤트 소스 매핑은 Kinesis Data Streams, SQS & SQS FIFO Queue, DynamoDB 스트림에 사용된다.
이들의 공통점은 레코드가 소스에서 폴링되어야 한다는 것이다. 즉, 람다가 서비스에 레코드를 요청해야 레코드가 반환된다는 것이다.
이 경우에 람다함수는 동기적으로 호출된다.

Streams & Lambda (Kinesis & DynamoDB)

이벤트 소스 매퍼에는 두 가지 범주가 존재한다.

하나는 스트림, 다른 하나는 대기열이다.

 

1. Streams

  • Streams은 Kinesis Data Stream과 DynamoDB 스트림에 적용이 된다.
  • 이벤트 소스 매핑이 일어나 각 샤드에 대한 반복자를 생성한다.
  • 샤드 레벨에서는 아이템을 순차적으로 처리하여 읽기 시작 위치를 구성할 수 있게 된다.
  • 샤드에서 아이템이 처리될 때, 아이템은 스트림으로부터 제거되지 않으며 다른 소비자들이 데이터를 읽어올 수 있다.
  • 사용 예시
    • 트래픽이 낮은 경우, 배치 윈도우를 사용해서 처리 전에 레코드를 축적한다. 이를 통해 다른 람다 함수를 효율적으로 호출할 수 있다.
    • 스트림의 처리량이 매우 많고 처리 속도를 높이고 싶다면, 람다가 샤드 레벨에서 동시에 여러 배치를 처리하도록 설정할 수 있다.
      • 샤드 당 최대 10개의 배치를 가질 수 있으며, 파티션 키 레벨에서 각 배치가 순차적으로 처리된다.

1-1. Error Handling

  • 기본적으로, 함수가 오류를 반환한다면, 함수가 성공하거나 배치 내에 있는 아이템이 만료될 때까지 모든 배치를 다시 처리한다.
  • 순차적인 처리를 위해, 영향을 받는 샤드에 대한 배치 처리는 에러가 해결될 때까지 중단된다.
  • 이벤트 소스 매핑에 가능한 설정:
    • 오래된 이벤트 폐기
    • 재시도 횟수 제한
    • 오류 시 배치 분할

2. Lambda - Event Source Mapping SQS & SQS FIFO

  • 이벤트 소스 매핑은 SQS를 폴링한다.
  • 배치 사이즈는 1부터 10까지 설정이 가능하다.
  • 대기열 표시 시간초과를 람다 함수 시간초과의 6배로 설정하는 것을 추천!
  • DLQ 사용 시, 읽기와 쓰기에 문제가 생겨서 Deal-Letter 대기열로 보내는 경우 DLQ가 아닌 SQS 대기열에 설정해야 한다.
    • 그 이유는 람다용 DLQ는 비동기식 호출에만 작용하기 때문이다.

Queues & Lambda

  • FIFO 대기열을 사용하는 경우에는 람다가 순차적 처리를 지원한다. 이때 스케일링 될 람다 함수의 수는 활성 메시지 그룹의 숫자와 동일하다.
  • 하지만 표준 대기열을 사용하면 아이템이 순서대로 처리되지 않을 것이다.
  • 표준 대기열에서 람다는 대기열의 모든 메시지를 읽을 수 있도록 최대한 빠르게 스케일링된다.
  • 대기열에 오류 발생 시, 배치는 개별 아이템으로서 대기열로 반환될 것이고 원래 배치와 다른 그룹에서 처리될 수 있다.
  • 간혹, 이벤트 소스 매핑이 함수의 오류가 발생하지 않는다면 대기열에서 두 번이나 같은 아이템을 받을 수 있다. 그런 경우, 람다 함수에서 아이템이 처리되도록 해야한다.
  • 람다에서 아이템이 처리되면 람다는 대기열에서 아이템을 처리하여 아이템이 나타나지 않게 된다.

Lambda Event Mapper Scaling

  • Kinesis Data Streams와 DynamoDB Streams
    • 각 스트림 샤드당 람다 호출은 한 번씩 일어난다.
    • 병렬 처리를 사용할 경우에는 샤드당 동시에 10개 배치까지 처리할 수 있다.
  • SQS 표준
    • 람다가 매우 빠르게 스케일링된다.(스케일 업을 위해 추가하는 인스턴스가 분당 16개)
    • 초당 동시에 처리되는 배치량은 최대 1,000개이다.
  • SQS FIFO
    • 그룹 ID가 같은 메시지는 무조건 순서대로 처리되고, 람다 함수는 활성 메시지 그룹의 수만큼 스케일업한다.

Lambda - Event and Context Objects

  • EventBridge를 통해 람다 함수를 호출할 수 가 있는데 이때 전송되는 것에는 이벤트 객체와 컨텍스트 객체가 있다.
  • 이벤트 객체는 다양한 정보를 갖고 있는데, 이 정보는 이벤트가 어디에서 발생했는지 서비스에 어떤 데이터가 있는지 등의 정보가 포함되어 있다.
  • 컨텍스트 객체는 함수에 대한 메타데이터가 포함되어 있다. 함수의 AWS 요청, 함수 이름, 함수의 로그 그룹 등이 이에 포함된다.

1. Event Object

  • JSON 형태의, 함수가 처리할 데이터를 갖고 있는 문서이다.
  • EventBridge나 SQS, SNS 같이 호출되는 서비스는 람다 함수가 이벤트를 처리할 때 필요한 모든 정보를 갖는 셈이다.
  • 람다 런타임은 객체로 이벤트를 변환한다.

2. Context Object

  • 런타임 환경과, 호출 자체의 데이터에 대한 정보를 제공하는 메서드와 속성을 제공한다.
  • 런타임에 있는 람다가 이 객체를 함수에 전달한다.

Lambda - Destinations

기존에는 비동기식 호출이나 이벤트 매퍼를 실행할 때 성공의 유무를 알 수 없다는 문제점이 있었다.

목적지는 비동기화 호출이나 이벤트 매퍼의 실패 결과를 다른 어딘가로 전송한다.

 

1. 비동기식 호출

비동기식 호출에서는 성공이나 실패한 이벤트 모두에 목적지를 정의한다.(성공 및 실패 = 이벤트 처리 여부)
비동기식 호출의 목적지로는 SQS, SNS, Lambda, EventBridge bus 등이 있다.

커리큘럼이 DLQ와 비슷하지만 목적지를 사용하는 것을 권장한다.
목적지 기능이 더 최신이고 많은 대상을 가질 수 있기 때문이다.
DLQ | SQS와 SNS로 실패만 전송하도록 함
Destination | 성공과 실패 모두가 전송되도록 함

 

2. Event Source mapping

이벤트 소스 매핑은 처리할 수 없는 요청을 폐기하는 경우에 사용이 된다.

해당 이벤트를 SQS나 SNS로 전송할 수 있다.


Lambda Logging & Monitoring

  • CloudWatch Logs
    • 람다는 CloudWatch Logs와 통합되어 있으므로 람다의 모든 실행 로그는 자동으로 CloudWatch Logs에 저장된다.
    • 이때, AWS 람다 함수가 CloudWatch Logs에 쓸 수 있는 IAM 정책을 가진 실행 역할을 가져야 함을 유의해야 한다!
  • CloudWatch Metrics
    • AWS 람다 지표는 CloudWatch 지표에 저장된다.
    • 호출, 기간, 동시 실행, 스로틀, 비동기 전송 실패에 대한 정보를 나타낸다.
    • Kinesis or DynamoDB 스트림에서 읽어오는 경우, 스트림을 읽어 들이는 작업에 얼마나 지연이 발생하는지 알 수 있다.

Lambda Tracing with X-Ray

  • 람다 함수는 X-Ray를 이용한 추적이 가능하다.
  • 람다 구성에서 Active Tracing만 활성화해주면 된다!
  • 이때 람다 구성에 X-Ray를 사용할 수 있는 IAM 실행 역할이 있는지 확인해야 한다.
    • 'AWSXRayDaemonWriteAccess'라는 관리 정책을 확인할 것!
  • X-Ray를 활성화 시키는 환경 변수들
    • _X_AMZN_TRACE_ID
    • AWS_XRAY_CONTEXT_MISSING
    • AWS_XRAY_DAEMON_ADDRESS | 람다 함수에 대해 X-Ray 데몬이 실행되는 IP와 포트를 알려준다.

Lambda Edge & CloudFront Function

1. Customization At The Edge

함수와 어플리케이션을 특정 리전에 배포한다고 배웟지만 CloudFront 등을 사용할 때는 엣지 위치에 콘텐츠를 배포하는 경우도 있다.
현대적 어플리케이션의 경우 어플리케이션 자체에 도달하기 전에 엣지에서 먼저 논리를 실행할 때도 있다.
이를 "엣지 함수"라고 부른다.

 

Edge Function:

  • 이 코드는 작성하여 CloudFront에 배포 시 연결한다.
  • 지연 시간을 최소화하기 위애 사용자와 가까운 곳에서 함수를 실행한다.

CloudFront 함수 유형은 두 가지로 CloudFront Function과 Lambda@Edge가 있다.

엣지 함수 사용 시, 전역적으로 배포되기에 서버를 관리할 필요가 없다.

또한 서버리스 상태를 가진다.

2. CloudFront Functions

전형적인 CloudFront 함수의 과정은 다음과 같다.

  1. 클라이언트가 CloudFront에 요청을 보낸다.(이때 클라이언트가 확인하기에 '뷰어 요청'이라고 부른다.)
  2. CloudFront는 오리진 서버로 오리진 요청을 보낸다.
  3. 서버는 CloudFront에 응답하여 오리진 응답을 받는다.
  4. CloudFront는 뷰어 응답을 보낸다.

  • 큰 규모로 대기 시간이 중요한 상황에 수행된다.(수준이 높고 규모가 큼)
  • 초당 수백만 개의 요청을 수행할 수 있다.
  • 모든 코드가 CloudFront에서 관리된다.

기억할 부분은 CloudFront 함수가 뷰어 요청 및 응답에만 해당되어 수준이 높고 규모가 크다는 것이다!

3. Lambda@Edge

  • 과정은 CloudFront와 같으며, Node.js나 파이썬 언어로 쓰인다.
  • 초당 수천 개의 요청을 수행할 수 있다.
  • 하나의 AWS 리전인 us-east-1에 함수를 작성하면, CloudFront에서 이 함수를 모든 위치에 복제한다.
  • CloudFront 함수와 달리 뷰어 응답 및 요청, 오리진 요청 및 응답에 영향을 미친다.

4. CloudFront Functions VS. Lambda@Edge

두 함수의 차이점은 아래와 같다.

 

 

5. CloudFront Functions VS. Lambda@Edge - 사용 사례

  1. CloudFront Functions
    • 캐시 키 정규화
    • 헤더 조작
    • URL 재작성 및 리디렉션
    • 요청 인증 및 인가
  2. Lambda@Edge
    • 실행 시간이 더 김
    • 조정 가능한 CPU와 메모리
    • 코드에 타사 라이브러리 이용 가능
    • HTTP 요청의 본문 액세스 획득 가능

Lambda in VPC

1. Lambda by default

  • 람다 함수는 기본적으로 자체 VPC 외부에서 실행된다.
  • VPC에 있는 리소스에는 액세스가 불가능하다.(EC2 인스턴스, RDS, Elasti Cache는 VPC 리소스)

2. Lambda in VPC

  • 람다를 배포하기 위해서는 VPC ID와 서브넷을 정의하고 람다 함수에 보안 그룹을 배정해야 한다.
  • 람다는 서브넷에 ENI를 생성한다.
  • ENI를 생성하기 위해 람다 함수는 "AWSLambdaVPCAccessExecutionRole"을 부여해야 한다.

RDS 보안 그룹에 람다 보안 그룹에 대한 액세스를 허용해야 제대로 작동한다.

 

만일 람다 함수를 VPC에서 배포한다고 했을 때, 공용 인터넷에 대한 액세스의 가능 여부를 알아보자.

  • 기본적으로 VPC 내에 있는 람다 함수는 인터넷 액세스 권한이 없다.
  • 람다 함수를 공용 서브넷에서 배포하는 것은 인터넷 액세스 권한이나 공용 IP 접근 권한을 얻을 수 없다.
  • 람다 함수를 사설 서브넷에 배포하여 인터넷 액세스 권한을 얻으려면 NAT 게이트웨이나 NAT 인스턴스를 사용해야 한다!
  • 결론은 NAT 없이 AWS 서비스를 사적으로 액세스 하기 위해서는 VPC 엔드포인트를 사용할 수 있다.
    • 이것은 NAT 디바이스나 인터넷 게이트웨이에 액세스하지 않고도 액세스를 할 수 있다.
  • 람다는 사설 서브넷에 배포하였을 때 엔드포인트나 NAT 게이트웨이가 없어도 CloudWatch Logs를 사용할 수 있다.

람다를 사설 서브넷에 배포하였을 때 외부 API와 통신할 수 있다!


Lambda Function Configuration & Performance

1. Configuration

  • RAM
    • 128MB부터 10GB까지 용량을 조절할 수 있다.
    • RAM을 늘릴수록 더 많은 vCPU를 얻게 될 것이다.
    • RAM 용량이 1,792MB일 때, 1개의 완전한 vCPU를 갖게 되는 것과 동일해진다.
    • 1,792MB를 넘는다면 하나 이상의 CPU를 얻는 것으로, 추가된 vCPU의 이점을 살리기 위해 멀티스레딩을 사용해야 한다.
  • 계산이 많고, 함수를 많이 사용해야 한다면 RAM을 반드시 늘려라!
  • Timeout
    • 특정 시간이 지나면 오류를 내고 타임아웃으로 처리한다.
    • 기본적으로 3초로 설정되어 있으며 15분까지 설정이 가능하다!

2. Execution Context

  • '실행 컨텍스트'는 람다 코드의 외부적 의존성을 시작하는 일시적 런타임 환경을 말한다.
  • DB 접속, HTTP 클라이언트나 SDK 클라이언트를 만들 수 있다.
  • 실행 컨텍스트는 또 다른 함수 호출을 예상하면서 특정 시간 동안 유지된다.
  • 다음 함수 호출은 실행 시간에 컨텍스트를 재사용할 수 있고, 초기화된 연결 객체들에 대한 시간을 절약할 수 있다.
  • 실행 컨텍스트는 "/tmp" 디렉터리를 포함한다.

3. Lambda Functions /tmp space

  • /tmp 공간을 이용하여 람다 함수가 큰 파일을 다운로드하거나 디스크 공간을 필요로 할 때 유용하게 사용할 수 있다.
  • 최대 10GB의 크기를 갖는다.
  • 람다 함수가 중지되고 다시 호출되어도 /tmp 공간에서 같은 파일들을 찾을 수 있다!!
  • 만일 일시적이 아닌 영구적으로 저장을 하여 사용해야 하는 경우라면 S3를 사용하자!
  • tmp 공간의 파일들을 암호화하고 싶다면 KMS 데이터 키를 사용하여 암호화하자!