반응형
Serverless(서버리스)란?
- Serverless(서버리스)는 개발자가 서버를 직접 관리하지 않고 애플리케이션을 구축하고 실행할 수 있는 개발 모델입니다.
- 서버리스는 서버가 없음을 의미하는 것이 아니라 개발자가 관리할 서버가 없다는 의미로 개발자에게 서버가 보이지 않는다는 개발자 경험을 의미합니다.
- 개발자는 서버리스 서비스를 사용하면 인프라 관리에서 벗어나 비즈니스 로직과 코드 작성에만 집중할 수 있습니다.
- 서버리스는 초기에 FaaS(Function as a Service)만을 의미했지만 현재는 사용자가 인프라를 지정하거나 관리하지 않는 모든 서비스를 의미합니다.
- AWS는 다양한 서버리스 서비스(Lambda, DynamoDB, API Gateway, S3, SQS, SNS, Cognito등)를 제공합니다.
AWS Lambda란?
- AWS Lambda란 서버 관리 없이 코드만 업로드하면 코드를 실행할 수 있는 서버리스 컴퓨팅 서비스입니다.
- Function(함수)은 Lambda에서 코드를 실행하기 위해 호출되는 리소스로 사용자가 업로드한 코드와 함수에 대한 설정으로 구성되어있습니다.
- Trigger(트리거)는 Lambda 함수를 호출하는 구성 또는 리소스로 실시간 처리와 개별 이벤트 처리에 사용됩니다.
- Runtime(런타임)은 함수 실행을 위한 프로그래밍 언어 환경을 제공하며 Lambda와 Function 사이에서 데이터와 응답을 제공하는 인터페이스 역할을 합니다.
- Handler(핸들러)는 함수가 호출될때 실행되는 메서드로 함수는 핸들러가 응답을 반환하거나 종료될 때까지 실행됩니다.
- Event는 람다 함수가 처리할 데이터가 들어있는 JSON 문서입니다.
- Context는 런타임 정보를 포함하는 객체로 함수의 이름과 버전, 함수에 할당된 메모리의 양, 함수 호출 ID등이 포함됩니다.
- Execution Role은 함수가 AWS 서비스 및 리소스에 액세스할 수 있는 권한을 부여하는 IAM Role로 함수에 할당되어 동작합니다.
- Lambda는 필요할 때만 실행되고 사용한 컴퓨팅 시간에 대해서만 비용을 지불합니다.
- Lambda는 할당된 메모리 크기에 비례하여 CPU가 할당됩니다.
- Lambda의 실행시간은 최대 15분으로 조정이 불가능합니다. 실행시간이 15분을 넘는 경우에는 Lambda 대신 ECS나 EC2를 사용하는 것이 좋습니다.
- Lambda의 호출 방식은 Synchronous Invokes(Push), Asynchronous Invokes(Event), Event Source Mapping(Polling)가 있습니다.
Lambda - Synchronous Invocation
- Synchronous invocation(동기식 호출)에서 람다는 이벤트를 함수로 직접 보내고 함수가 처리를 완료할 때까지 기다립니다.
- Lambda Invoke API의 InvocationType을 RequestResponse로 하면 람다를 동기식으로 실행할 수 있습니다.
- Application Load Balancer, API Gateway, Cognito등과 통합하여 람다를 Synchronous invocation 할 수 있습니다.
- Synchronous invocation에서 에러가 발생하는 경우 기본적으로 재실행되지 않고 에러 메세지를 반환합니다.
- Synchronous invocation은 이벤트 처리가 빠르고 실행 시간이 짧은 람다에 적합합니다.
Lambda - Asynchronous Invocation
- Asynchronous invocation(비동기식 호출)에서 람다는 이벤트를 함수로 직접 보내지 않고, 이벤트를 큐에 넣고 즉시 응답을 반환합니다.
- Asynchronous invocation은 함수의 처리를 기다리지 않습니다. 큐에 넣어진 이벤트는 별도의 프로세스가 큐에서 이벤트를 읽어 함수로 보냅니다.
- Lambda Invoke API의 InvocationType을 Event로 하면 람다를 비동기식으로 실행할 수 있습니다.
- S3, SNS, SES, EventBridge, CloudWatch Logs 등과 통합하여 람다를 Asynchronous invocation 할 수 있습니다.
- Asynchronous invocation에서 에러가 발생하는 경우 2번 더 재실행되어 총 3번 실행됩니다.
- Asynchronous invocation의 경우 람다가 이벤트를 큐에 넣고 추가 정보 없이 성공 응답(StatusCode 202)을 반환합니다.
StatusCode 202는 Accepted를 의미하며 함수의 실행 결과와 무관하게 단순히 이벤트가 정상적으로 수신되었음을 의미합니다. - Asynchronous invocation는 가끔 오류가 발생하지 않더라도 동일한 이벤트를 여러 번 수신할 수 있습니다.
그렇기 때문에 Asynchronous invocation로 실행되는 람다는 멱등성을 갖도록 구성되어야 합니다. - 클라이언트가 람다를 Asynchronous로 실행하는 경우 응답을 기다리지 않아도 되기 때문에 백그라운드 처리가 가능하고 Synchronous Invocation에 비해 클라이언트 성능이 향상됩니다.
Lambda - Event Source Mapping
- Event Source Mapping은 스트림 또는 큐 기반 서비스에서 레코드를 읽고 Lambda 함수를 자동으로 호출하는 Lambda 리소스로 Lambda 내에서 생성되고 관리됩니다.
- Event Source Mapping은 Event source로 Kinesis, DynamoDB, SQS, Kafka 등을 지원합니다.
- Event Source Mapping 내의 Event poller라는 리소스가 스트림과 큐에서 메세지를 적극적으로 폴링하고 Lambda 함수를 동기식으로 호출합니다.
- Event Source Mapping은 각 이벤트를 최소 1번 이상 처리하고 레코드의 중복처리가 발생할 수 있습니다.
그렇기 때문에 Event Source Mapping으로 실행되는 람다는 멱등성을 갖도록 구성되어야 합니다. - Event Source Mapping은 큐에서 대량 스트리밍 데이터 또는 메시지를 처리하도록 설계되었으며, 스트림 또는 큐에서 레코드를 개별적으로 처리하는 것보다 일괄 처리하는 것이 더 효율적입니다.
- Event filtering은 스트림이나 큐에서 들어오는 레코드를 필터링하여 만족하는 레코드만 Lambda 함수로 전달하는 기능으로 Event Source Mapping은 1개에서 5개까지 필터를 가질 수 있습니다.
Lambda - Execution Environment
- Execution Environment(실행 환경)는 안전하고 격리된 런타임 환경으로 함수가 실행되는 공간입니다.
- Execution Environment는 Firecracker 기반의 MicroVM에서 생성됩니다.
- Execution Environment는 AWS 계정 간 공유되지 않으며, 해당 계정의 특정 함수 버전만 실행할 수 있는 독점적인 공간입니다.
- Execution Environment의 Lifecycle은 Init, Invoke, Shutdown으로 구성되어 있습니다.
- SnapStart는 Init 단계를 최적화하는 방법으로 함수의 Startup latency(시작 지연 시간, Cold start time)을 크게 단축할 수 있습니다.
Lambda - Environment variable
- Environment variable(환경 변수)는 코드를 변경하지 않고 함수의 동작을 변경하려는 경우에 사용합니다.
- Environment variable(환경 변수)는 문자열 형식의 key-value 쌍입니다.
- 예를 들어 동일한 코드에서 RDS의 엔드포인트를 환경변수로 지정하여 개발 환경과 상용 환경에서 연결되는 DB가 다르도록 구성할 수 있습니다.
Lambda - Layer
- Layer(레이어)는 함수 실행에 필요한 라이브러리나 설정 파일을 포함하는 .zip 파일 아카이브입니다.
- Layer를 사용하면 함수의 dependency(종속성)을 분리하여 배포 패키지의 크기를 줄일 수 있습니다.
- Layer를 사용하면 함수의 핵심 로직과 종속성이 있는 코드를 분리할 수 있습니다.
- Layer는 여러 함수에서 사용할 수 있으며 각 함수는 최대 5개의 Layer를 사용할 수 있습니다.
Lambda - Deployment package(.zip file과 container image)
- 사용자가 함수 코드와 코드 실행에 필요한 파일들을 Deployment Package로 만들면 Lambda는 Deployment Package를 실행환경에 배포하여 함수를 실행합니다.
- Lambda는 Deployment로 .zip file과 container image를 지원합니다.
- 함수를 생성한 후에 기존 함수에 대한 Deployment package type을 변경할 수 없습니다. 함수 생성 후 Deployment package type을 변경하려면 새로운 함수를 생성해야 합니다.
- .zip file은 코드와 의존성을 압축하여 업로드하는 방식으로 Python, Node.js 등 일반적인 런타임에서 많이 사용됩니다.
- Container image는 코드와 의존성을 컨테이너 이미지로 빌드하여 ECR에 업로드하는 방식으로 최대 10GB 크기의 이미지까지 가능하고 머신 러닝과 같은 상당한 종속성이 수반되는 대규모 워크로드를 쉽게 구축하고 배포할 수 있습니다.
- Container image의 Base image는 Lambda runtime interface를 포함하고 있어야합니다.
Lambda - Version & Alias
- Version(버전)을 사용하면 함수의 배포를 버저닝 할 수 있습니다. 예를 들어, 상용환경에 영향을 미치지 않고 베타 테스트를 위한 새 버전을 만들 수 있습니다.
- 버전 번호는 순차적으로 증가하며 특정 버전을 삭제하더라도 버전 번호는 재사용되지 않습니다.
- 배포되지 않은 버전의 이름은 $LATEST으로 새로 생성되는 버전은 $LATEST의 복사본입니다.
- 버전을 생성하기 위해서는 $LATEST가 변경되어야 합니다. 이전에 생성된 버전이 현재의 $LATEST와 동일하면 새로운 버전을 만들수 없습니다.
- 버전을 생성한 후에는 생성된 버전의 코드와 런타임, 메모리, 레이어 등을 변경할 수 없고 $LATEST는 변경이 가능합니다.
- 각 버전은 독립적이며 버전마다 ARN(Amazon Resource Name)은 고유합니다.
- Alias(별칭)은 버전에 대한 포인터로 예를 들어, dev, alp, prod 등의 별칭을 만들어 특정 버전을 가리키도록 구성할 수 있습니다.
- 별칭은 고유한 ARN을 가지며, 다른 별칭을 가리킬 수 없고 함수 버전만 가리킬 수 있습니다.
- 별칭은 트래픽을 두개의 버전으로 분산할수 있습니다. 이를 활용하면 대부분의 트래픽을 기존 버전으로 보내고 트래픽의 일부만 새 버전으로 보내면서 새 버전을 배포하는 것에 대한 위험을 줄일 수 있습니다.
Lambda - Destination & Dead Letter Queue
- Destination은 함수가 비동기식으로 호출되거나 이벤트 소스 매핑으로 레코드를 처리하는 경우에 함수 실행 결과를 수신하는 대상으로 타임스탬프와 이벤트, 페이로드 등 세부 정보 등을 수신하게 됩니다.
- Destination을 사용하면 함수 실행 결과를 모니터링하고 함수 실행 결과에 대해 후속 처리를 할 수 있습니다.
- 비동기 호출의 경우 성공한 결과(on-success)와 실패한 실행 결과(on-failure)를 Destination으로 보낼 수 있고, 이벤트 소스 매핑의 경우 실패한 실행 결과만 Destination으로 보낼 수 있습니다.
- DLQ(Dead Letter Queue)는 실패한 실행 결과를 전송하는 Destination의 대안으로 정상적으로 처리하지 못한 이벤트를 처리하기 위해 구성할 수 있습니다.
- Destination은 SQS, SNS, EventBridge, Lambda를 지원하고 DLQ는 SQS와 SNS만 지원합니다.
- DLQ는 처리에 실패한 이벤트를 저장하고, Destination은 성공 및 실패 결과를 포함한 더 풍부한 실행 정보를 전달하기 때문에 사용 목적에 따라 DLQ 또는 Destination을 선택해야 합니다.
Lambda - Function URL
- Function URL(함수 URL)은 람다 함수 전용 HTTP(S) 엔드포인트로 API GW나 ALB를 사용하지 않고 Lambda함수를 인터넷에 공개할 수 있습니다.
- Funtion URL Endpoint는 “https://
.lambda-url. .on.aws”와 같은 형식을 갖습니다. - Function URL의 인증 방식으로 AWS_IAM을 사용하면 리소스 기반 정책으로 다른 AWS 계정, AWS Organization, AWS Service에게 접근 권한을 부여할 수 있고, None을 사용하면 Function URL은 퍼블릭 엔드포인트가 됩니다.
- 함수 URL은 CORS(Cross-Origin Resource Sharing)을 지원합니다.
Lambda - VPC
- 기본적으로 Lambda function은 인터넷 접근이 가능한 Lambda-managed VPC에서 실행되며 Lambda-managed VPC는 고객에게 보이지 않습니다.
그렇기 때문에 기본적으로 Lambda function은 고객의 VPC에 존재하는 리소스에는 접근할 수 없습니다. - Lambda의 VPC Configuration을 사용하면 Lambda function이 VPC 내의 리소스에 접근할 수 있습니다.
이때, Lambda는 Hyperplane Elastic Network Interface(Hyperplane ENI)를 자동으로 생성하여 VPC 내의 리소스와 통신합니다. - Lambda function을 VPC에 연결하면 해당 VPC 내에 사용가능한 리소스만 액세스할 수 있고 인터넷에 액세스할 수 없습니다.
VPC에 연결한 Lambda function이 인터넷에 액세스하기 위해서는 NAT GW를 통해야 합니다.
Hyperplane ENI는 퍼블릭 IP를 가질 수 없기 때문에 퍼블릭 서브넷에 Lambda function을 연결하여도 인터넷 액세스가 불가능합니다. - 인터넷 액세스가 불가능한 환경에서 VPC에 연결된 함수가 AWS 서비스에 접근하기 위해서는 VPC Endpoint를 사용해야 합니다.
CloudWatch Logs는 인터넷이 불가능한 환경에서도 동작합니다.
Lambda - Ephemeral storage & File system
- Lambda는 실행 환경에 고유한 임시 저장소를 /tmp 디렉터리로 제공합니다.
예를 들어 함수가 작업할 파일을 다운로드하거나 함수 실행에 필요한 디스크 공간이 필요한 경우 사용할 수 있습니다. - /tmp 디렉터리는 512MB부터 10,240MB 사이로 구성할 수 있으며 저장된 데이터는 AWS managed key로 암호화됩니다.
- Lambda 함수가 VPC와 연결된 경우 Elastic File System(EFS)를 함수의 로컬 디렉터리에 마운트하도록 구성할 수 있습니다.
Lambda - Concurrency
- Concurrency는 특정 시점에 Lambda 함수가 동시에 처리하는 요청의 수입니다.
만약 Concurrency이 1,000이라면 특정 시점에 1,000개의 함수를 실행할 수 있다는 의미입니다. - Concurrency와 Requests per second는 다릅니다.
- Concurrency는 평균 초당 요청 건수와 평균 함수 실행 시간의 곱으로 계산합니다.
예를 들어, 1초에 평균 100건의 요청을 받고 함수의 평균 실행시간이 1초라면 Concurrency는 100이지만
1초에 평균 100건의 요청을 받고 함수의 평균 실행시간이 0.5초라면 Concurrency는 50입니다. - Lambda는 Concurrency의 10배 이내로 Requests per second를 제한합니다.
예를 들어, 1,000 Concurrency로 초당 20,000개의 요청을 처리할 수 있더라도 10,000개의 요청만 처리할 수 있어 스로틀링이 발생합니다. - Concurrency는 계정별로 리전당 1,000개가 제공되며 Pool 형태로 함수가 공유하여 사용하게 됩니다.
- Concurrency가 한도에 도달하면 Lambda는 추가 요청에 대해 429 Too Many Requests 오류를 반환합니다.
- Concurrency가 부족하다면 Service quota 증가를 요청해야 합니다.
- Reserved Concurrency는 특정 함수가 Concurrency를 보장받도록 예약하는 기능으로 중요한 함수가 충분한 Concurrency를 확보하는데 사용합니다.
- Provisioned Concurrency는 사전에 초기화된 실행 환경을 준비하는 기능으로 새로운 환경을 초기화해야하는 콜드 스타트를 방지하기 위해 사용합니다.
Lambda - Best Practice
- 핸들러가 실행되는 시간을 최소화하기 위해 핸들러 외부에서 많은 작업을 수행해야 합니다.
예를 들어, 핸들러 외부에서 데이터베이스를 연결하고 SDK 클라이언트를 생성해야 합니다. - S3 버킷 이름과 같은 운영 파라미터는 환경 변수를 통해 전달하는 것이 좋습니다.
- 함수가 스스로를 호출하는 재귀 호출은 피해야 합니다.
- 함수가 사용하는 Role에 최소 권한 원칙을 적용해야 합니다.
- 함수는 최적의 메모리 크기를 갖도록 구성되어야 합니다.
함수 실행 로그에서 Max Memory Used를 확인하면 함수에 메모리가 더 필요한지, 함수의 메모리가 과도하게 프로비저닝 되었는지 확인할 수 있습니다. - 함수에서 사용하지 않는 코드는 삭제하여 배포 패키지에 불필요하게 포함되지 않도록 합니다.
- 함수의 코드는 중복 이벤트를 우아하게 처리하도록 멱등성 있게 작성되어야 합니다.
- 정적 자산(static asset)은 /tmp 디렉터리에 캐싱하는 것이 좋습니다.
반응형
'📂 AWS > AWS Developer - Associate' 카테고리의 다른 글
[AWS] Developer Associate #11 DNS(Route53) (2) | 2024.11.15 |
---|---|
[AWS] Developer Associate #10 IaC(CloudFormation) (0) | 2024.11.11 |
[AWS] Developer Associate #9 모니터링(CloudWatch, X-Ray) (2) | 2024.11.11 |
[AWS] Developer Associate #8 메세징(SQS, SNS) (0) | 2024.09.22 |
[AWS] Developer Associate #7 CloudFront (0) | 2024.08.03 |