AWS Lambda 함수 작업의 모범 사례 - AWS Lambda

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

AWS Lambda 함수 작업의 모범 사례

다음은 AWS Lambda 사용에 대한 권장 모범 사례입니다.

Lambda 애플리케이션의 모범 사례에 대한 자세한 내용은 Serverless Land의 Application design을 참조하세요.

함수 코드

  • 핵심 로직에서 Lambda 핸들러를 분리합니다. 이를 통해 단위 테스트를 수행할 수 있는 더 많은 함수를 만들 수 있습니다. Node.js에서 이는 다음과 같을 수 있습니다.

    exports.myHandler = function(event, context, callback) { var foo = event.foo; var bar = event.bar; var result = MyLambdaFunction (foo, bar); callback(null, result); } function MyLambdaFunction (foo, bar) { // MyLambdaFunction logic here }
  • 실행 환경 재사용을 활용하여 함수 성능을 향상시킵니다. 함수 핸들러 외부에서 SDK 클라이언트 및 데이터베이스 연결을 초기화하고 정적 자산을 /tmp 디렉토리에 로컬로 캐시합니다. 동일한 함수 인스턴스에서 처리하는 후속 호출은 이러한 리소스를 재사용할 수 있습니다. 이를 통해 함수 실행 시간을 줄여 비용을 절감합니다.

    호출에서 발생할 수 있는 데이터 유출을 방지하려면 실행 환경을 사용하여 사용자 데이터, 이벤트 또는 보안과 관련된 기타 정보를 저장하지 마세요. 함수가 핸들러 내부 메모리에 저장할 수 없는 변경 가능한 상태에 의존하는 경우 각 사용자에 대해 별도의 함수 또는 별도의 함수 버전을 생성하는 것이 좋습니다.

  • 연결 유지 지시문을 사용하여 지속적인 연결을 유지하세요. Lambda는 시간이 지남에 따라 유휴 연결을 제거합니다. 함수를 호출할 때 유휴 연결을 재사용하려고 하면 연결 오류가 발생합니다. 지속적인 연결을 유지하려면 런타임과 관련된 연결 유지 지시문을 사용하세요. 예를 들어, Node.js에서 연결 유지를 이용해 연결 재사용을 참조하세요.

  • 환경 변수를 사용하여 함수에 운영 파라미터를 전달합니다. 예를 들어, Amazon S3 버킷에 기록하는 경우 기록하고 있는 버킷 이름을 하드 코딩하는 대신 환경 변수로 구성합니다.

  • 함수 배포 패키지의 종속성을 제어합니다. AWS Lambda 실행 환경에는 Node.js 및 Python 런타임용 AWS SDK와 같은 여러 라이브러리가 포함되어 있습니다(전체 목록은 Lambda 런타임에서 찾을 수 있음). 최신 기능 및 보안 업데이트를 활성화하려면 Lambda가 주기적으로 이러한 라이브러리를 업데이트해야 합니다. 이러한 업데이트는 Lambda 함수의 동작에 사소한 변화를 가져올 수 있습니다. 함수가 사용하는 종속성을 완전히 제어하려면 모든 종속성을 배포 패키지로 패키징하세요.

  • 배포 패키지 크기를 런타임 필요에 따라 최소화합니다. 이렇게 하면 호출 전에 배포 패키지를 다운로드하고 압축을 풀 때 걸리는 시간이 단축됩니다. Java 또는 .NET Core에서 작성된 함수의 경우 배포 패키지의 일부로 전체 AWS SDK 라이브러리를 업로드하지 마세요. 대신, 필요한 SDK의 구성 요소를 선택하는 모듈을 선택적으로 활용합니다(예: DynamoDB, Amazon S3 SDK 모듈, Lambda 핵심 라이브러리).

  • 종속성 .jar 파일을 별도의 /lib 디렉터리에 배치하여 Java에서 생성된 배포 패키지의 압축을 푸는 데 Lambda가 소요하는 시간을 단축합니다. 이는 많은 수의 .class 파일이 있는 단일 jar에 모든 함수 코드를 배치하는 것보다 빠릅니다. 자세한 내용은 .zip 또는 JAR 파일 아카이브를 사용하여 Java Lambda 함수 배포 섹션을 참조하세요.

  • 종속성의 복잡성을 최소화합니다. 실행 환경 시작 시 빠르게 로드되는 더 단순한 프레임워크가 권장됩니다. 예를 들어 Spring Framework와 같은 더 복잡한 프레임워크보다는 Dagger 또는 Guice 같은 더 단순한 Java 종속성 주입(IoC) 프레임워크를 선호합니다.

  • 일부 임의 기준이 충족될 때까지 함수가 자동으로 자체 호출이 되는 리커시브 코드를 Lambda 함수에서 사용하지 않도록 합니다. 리커시브 코드를 사용할 경우, 의도하지 않은 함수 호출이 증가하고 비용이 상승할 수 있습니다. 실수로 그렇게 한 경우 코드를 업데이트하는 동안 즉시 함수 예약된 동시성을 0으로 설정하여 해당 함수에 대한 모든 호출을 조절합니다.

  • Lambda 함수 코드에는 문서화되지 않은 비공개 API를 사용하지 마세요. AWS Lambda 관리형 런타임의 경우, Lambda는 주기적으로 보안 및 기능 업데이트를 Lambda의 내부 API에 적용합니다. 이러한 내부 API 업데이트는 이전 버전과 호환되지 않으므로 함수가 이러한 비공개 API에 종속성을 갖는 경우 호출 실패와 같은 의도하지 않은 결과를 초래할 수 있습니다. 공개적으로 사용 가능한 API의 목록은 API 레퍼런스를 참조하세요.

  • 멱등성 코드를 작성합니다. 함수에 멱등성 코드를 작성하면 중복 이벤트가 동일한 방식으로 처리됩니다. 코드는 이벤트를 올바르게 검증하고 중복 이벤트를 정상적으로 처리해야 합니다. 자세한 내용은 멱등성 Lambda 함수를 만들려면 어떻게 해야 합니까? 단원을 참조하십시오.

  • Java DNS 캐시를 사용하지 마십시오. Lambda 함수는 이미 DNS 응답을 캐싱하고 있습니다. 다른 DNS 캐시를 사용하는 경우 연결 시간 초과가 발생할 수 있습니다.

    java.util.logging.Logger 클래스는 JVM DNS 캐시를 간접적으로 활성화할 수 있습니다. 기본 설정을 재정의하려면 logger 초기화 전에 networkaddress.cache.ttl을 0으로 설정하십시오. 예제

    public class MyHandler { // first set TTL property static{ java.security.Security.setProperty("networkaddress.cache.ttl" , "0"); } // then instantiate logger var logger = org.apache.logging.log4j.LogManager.getLogger(MyHandler.class); }

    UnknownHostException 오류를 방지하려면 networkaddress.cache.negative.ttl을 0으로 설정하는 것이 좋습니다. AWS_LAMBDA_JAVA_NETWORKADDRESS_CACHE_NEGATIVE_TTL=0 환경 변수를 사용하여 Lambda 함수에 대해 이 속성을 설정할 수 있습니다.

    JVM DNS 캐시를 비활성화해도 Lambda의 관리형 DNS 캐싱은 비활성화되지 않습니다.

함수 구성

  • Lambda 함수를 테스트하는 성능은 최적의 메모리 크기 구성을 선택할 때 매우 중요합니다. 메모리 크기가 증가하면 함수에 사용 가능한 상응하는 CPU 사용이 증가합니다. 함수의 메모리 사용은 호출마다 결정되며 Amazon CloudWatch에서 볼 수 있습니다. 매 호출마다 아래와 같이 REPORT: 항목이 만들어집니다.

    REPORT RequestId: 3604209a-e9a3-11e6-939a-754dd98c7be3 Duration: 12.34 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 18 MB

    Max Memory Used: 필드를 분석함으로써 함수가 더 많은 메모리를 필요로 하는지 또는 함수의 메모리 크기가 과다 프로비저닝되었는지 확인할 수 있습니다.

    기능에 적합한 메모리 구성을 찾으려면 오픈 소스 AWS Lambda Power Tuning 프로젝트를 사용하는 것이 좋습니다. 자세한 내용은 GitHub에서 AWS Lambda Power Tuning을 참조하세요.

    함수 성능을 최적화하려면 Advanced Vector Extensions 2(AVX2)를 활용할 수 있는 라이브러리를 배포하는 것이 좋습니다. 이를 통해 기계 학습 추론, 미디어 처리, 고성능 컴퓨팅(HPC), 과학 시뮬레이션, 금융 모델링 등 까다로운 워크로드를 처리할 수 있습니다. 자세한 내용은 Creating faster AWS Lambda functions with AVX2를 참조하세요.

  • Lambda 함수를 로드 테스트하여 최적의 제한 시간 값을 확인합니다. 함수의 실행 시간을 분석하여 함수의 동시성을 기대 이상으로 높일 수 있는 종속성 서비스를 통해 문제를 더 효과적으로 확인하는 것이 중요합니다. 이는 Lambda 함수가 Lambda의 조정을 처리하지 못할 수 있는 리소스에 대한 네트워크 호출을 수행할 때 특히 중요합니다.

  • IAM 정책을 설정할 때 가장 제한적인 권한을 사용합니다. Lambda 함수에 필요한 리소스와 작업을 이해하고 실행 역할을 이러한 권한으로 제한합니다. 자세한 내용은 Lambda 리소스 액세스 권한 섹션을 참조하세요.

  • Lambda 할당량 단원의 내용을 숙지합니다. 페이로드 크기, 파일 설명자 및 /tmp 공간은 런타임 리소스 제한을 결정할 때 자주 간과됩니다.

  • 업스트림 및 다운스트림 처리량 제한 사항을 잘 알고 있어야 합니다. Lambda 함수는 로드에 따라 원활하게 규모를 조정할 수 있지만 업스트림 및 다운스트림 종속성의 처리량 용량이 동일하지 않을 수 있습니다. 함수의 규모를 조정할 수 있는 수준을 제한해야 하는 경우 예약된 동시성을 구성하십시오.

  • 더 이상 사용하지 않는 Lambda 함수를 삭제합니다. 삭제하면 사용되지 않는 함수는 배포 패키지 크기 제한에 불필요하게 포함되지 않습니다.

  • 이벤트 소스로 Amazon Simple Queue Service를 사용하는 경우 함수의 예상 호출 시간 값이 대기열의 표시 제한 시간 값을 초과하지 않도록 합니다. 이는 CreateFunctionUpdateFunctionConfiguration 모두에 적용됩니다.

    • CreateFunction의 경우 AWS Lambda가 함수 생성 프로세스에 실패합니다.

    • UpdateFunctionConfiguration의 경우, 함수가 중복 호출될 수 있습니다.

지표 및 경보

  • Lambda 함수 코드 내에서 지표를 생성하거나 업데이트하는 대신 Lambda 함수 지표 작업CloudWatch 경보를 사용합니다. 이는 Lambda 함수의 상태를 파악하는 훨씬 더 효율적인 방법이며, 개발 프로세스 초기에 문제를 파악할 수 있습니다. 예를 들어, 함수 코드로 인한 병목 현상이나 지연 시간을 해결하기 위해 예상되는 Lambda 함수 호출 소요 시간을 기준으로 경보를 구성할 수 있습니다.

  • 로깅 라이브러리 및 AWS Lambda 지표 및 차원을 사용하여 앱 오류를 파악합니다(ERR, ERROR, WARNING 등).

  • AWS Cost Anomaly Detection을 사용하여 계정에서 비정상적인 활동을 감지합니다. Cost Anomaly Detection은 기계 학습을 사용하여 비용과 사용량을 모니터링하고 오탐지 알림을 최소화합니다. Cost Anomaly Detection은 AWS Cost Explorer의 데이터를 사용하며, 최대 24시간의 지연이 있습니다. 따라서 사용량이 발생한 후 이상 탐지에 최대 24시간이 걸릴 수 있습니다. Cost Anomaly Detection을 시작하려면 먼저 Cost Explorer에 가입해야 합니다. 이후 Cost Anomaly Detection에 액세스합니다.

스트림 작업

  • 서로 다른 배치 및 레코드 크기로 테스트하여 각 이벤트 소스의 폴링 빈도를 조정하고 해당 함수가 얼마나 빨리 작업을 완료할 수 있는지 확인합니다. CreateEventSourceMapping BatchSize 파라미터는 각 호출에서 함수로 보낼 수 있는 최대 레코드 수를 제어합니다. 배치 크기가 클수록 더 큰 레코드 세트에서 호출 오버헤드를 더 효율적으로 수용하여 처리량을 늘릴 수 있습니다.

    기본적으로, Lambda는 레코드가 사용 가능하게 되는 즉시 함수를 호출합니다. Lambda가 이벤트 소스에서 읽는 배치에 하나의 레코드만 있는 경우, Lambda는 함수에 하나의 레코드만 전송합니다. 소수의 레코드로 함수를 호출하는 것을 피하려면 일괄 처리 기간을 구성하여 이벤트 소스가 최대 5분 동안 레코드를 버퍼링하도록 지정할 수 있습니다. 함수를 호출하기 전에 Lambda는 전체 배치가 수집되거나, 일괄 처리 기간이 만료되거나, 배치가 페이로드 한도인 6MB에 도달할 때까지 이벤트 소스에서 레코드를 계속 읽습니다. 자세한 내용은 일괄 처리 동작 단원을 참조하십시오.

    주의

    Lambda 이벤트 소스 매핑은 각 이벤트를 한 번 이상 처리하므로 일괄 처리가 중복될 수 있습니다. 중복 이벤트와 관련된 잠재적 문제를 방지하려면 함수 코드를 멱등성으로 만드는 것이 좋습니다. 자세한 내용은 AWS 지식 센터의 멱등성 Lambda 함수를 만들려면 어떻게 해야 합니까?를 참조하세요.

  • 샤드를 추가하여 Kinesis 스트림 처리량을 늘립니다. Kinesis 스트림은 하나 이상의 샤드로 구성됩니다. Lambda는 최대 한 개의 동시 호출로 각 샤드를 폴링합니다. 예를 들어 스트림에 100개의 활성 샤드가 있으면 최대 100개의 Lambda 함수 호출이 동시에 실행됩니다. 샤드 수를 늘리면 Lambda 함수의 최대 동시 호출 수가 증가하고 Kinesis 스트림 처리량이 증가할 수 있습니다. Kinesis 스트림에서 샤드 수를 늘리는 경우 데이터에 대해 적절한 파티션 키를 선택하여(파티션 키 참조) 관련 레코드가 동일한 샤드에서 끝나며 데이터가 잘 분산되도록 해야 합니다.

  • IteratorAge에 대해 Amazon CloudWatch를 사용하여 Kinesis 스트림이 처리 중인지 확인합니다. 예를 들어 최대 값을 30,000(30초)으로 설정하여 CloudWatch 경보를 구성합니다.

보안 모범 사례

  • AWS Security Hub을 사용하여 보안 모범 사례와 관련된 AWS Lambda의 사용량을 모니터링하십시오. Security Hub는 보안 제어를 사용하여 리소스 구성 및 보안 표준을 평가하여 다양한 규정 준수 프레임워크를 준수할 수 있도록 지원합니다. Security Hub를 사용하여 Lambda 리소스를 평가하는 방법에 대한 자세한 내용은 AWS Security Hub 사용 설명서의 AWS Lambda 제어를 참조하십시오.