AWS

[AWS] aws 강의 섹션 21-1 (람다 (Lambda), 람다 함수(Labda Function))

대기업 가고 싶은 공돌이 2024. 10. 22. 20:49

AWS Serverless Lambda

 

서버리스란?

  • 서버리스를 사용하는 개발자는 서버를 관리할 필요가 없어진다.
  • 서버가 아예 없다는 뜻이 아니라 관리할 필요가 없다는 것이다. 
    • 초기의 서버리스는 Faas (Function as a Service)를 의미했으나 지금은 더 많은 것을 의미한다.
      • faas란 기능을 제공하는 서비스로, 사용자가 함수 단위로 코드를 작성하면 해당 함수를 실행시켜 주는 것을 의미한다.
      • 현재는 단순히 함수 이외에, 데이터베이스, 메시징, 저장 등의 기능도 다 포함한다.

aws에서는 다음과 같은 서비스가 서버리스 서비스에 해당한다.

 

AWS Lambda란?

EC2의 단점

  • 메모리와 CPU의 크기가 제한돼 있다. 
  • 24시간 돌아간다.
  • 스케일링 즉, 서버를 더하고 제거하는 작업이 필요하다.

람다는 어떨까

  • 람다는 서버리스다. 가상 함수를 실행한다.
  • 실행 시간이 15분으로 제한이 있다.
  • 온디맨드로 요금 청구가 된다.
    • 함수가 실행될 때만 비용이 청구된다.
  • 스케일링이 자동화된다. 
    • 더 많은 수행능력이 필요하면 자동으로 함수를 프로비저닝 한다.

람다의 장점

  1. 가격 책정이 쉽다.
    • 람다가 수신하는 요청의 숫자에 따라 청구되며, 이는 호출 숫자 및 컴퓨팅 시간에 따라 책정된다.
    • 프리티어에서 1,000,000개의 요청과 100,000GB의 컴퓨팅 시간을 제공한다.
  2. 다양한 AWS 서비스와 통합된다.
  3. 다양한 언어를 지원한다.
  4. 클라우드워치를 통해 모니터링이 쉬워진다.
  5. 함수당 더 많은 리소스를 프로비전 할 수도 있다.
    • 최대 10GB의 메모리를 프로비저닝 할 수 있다.
  6. 함수의 Ram을 증가시키려면 CPU와 네트워크 성능도 같이 향상시켜야 한다.

  • 람다에선 위와 같이 다양한 언어를 지원한다.
  • 람다 컨테이너 이미지는 좀 특별한데
    • 컨테이너 이미지 자체가 람다의 런타임 API를 구현해야 하기에 다른 기존의 컨테이너 이미지와는 다르다.
    • ECS/ Fargate는 도커 컨테이너 이미지를 실행하는데 많이 사용된다.
    • 따라서 컨테이너를 실행해야 할 경우, 람다 API를 구현하는 컨테이너가 아니라면
      ECS/ Fargate를 이용해서 컨테이너를 실행하는 것이 좋다. 

 

 

예시: 서버리스로 썸네일 만들기

  • S3에 이미지가 삽입되면 S3이벤트 트리거로 람다 함수를 호출한다.
  • 호출된 람다함수는 다른 S3버킷에 썸네일을 만들어 올리고
  • 호출된 다른 람다함수는 DB에 썸네일의 메타데이터를 올리는 방식으로 동작할 수 있다.

예시: ServerLess Cron job (특정 시간마다 특정 작업 수행하기)

  • 이벤트 브릿지에서 특정 시간마다 람다 함수를 호출하게 하고 람다함수는 특정 작업을 수행하는 코드로 작성하면 쉽게 구축할 수 있다.

람다함수 비용

  • 첫 백만 개의 호출은 무료이고
    • 이후 백만 개의 호출 당 20센트가 발생한다.
  • 시간은 1ms 단위로 요금이 부과된다.
    • 첫 한 달간 400,000GB초의 컴퓨팅 시간은 무료다
      • 400,000GB 초란 1GB의 램을 400,000초 실행하는 시간을 의미한다.
      • 즉 램이 128MB라면, 3,200,000초를 무료로 실행할 수 있는 것이다.
    • 이후엔 600,000GB초당 1달러가 부과된다.

Synchronous Invocation (동기식 호출)

  • 람다 함수를 동기식으로 호출하는 서비스의 목록이다.
  • 동기식이란 한 서비스를 호출했을 때 해당 서비스의 응답이 돌아올 때까지 다른 작업을 수행하지 못 하는 것을 동기식이라 한다.

람다함수와 ALB의 통합

  • 람다함수는 SDK와 CLI를 통해 호출할 수 있다. 하지만 엔드포인트를 통해 호출하고 싶을 수도 있다.
  • 이럴 때 쓰는 방법이 바로 로드밸런서와 API 게이트웨이다.
    • 여기선 로드밸런서만 보겠다.
  • 우선 람다 함수를 로드밸랜서 target 그룹에 등록해야 한다.
  • 그러면 사용자가 로드밸런서를 호출 했을 때 람다 함수를 호출할 수 있다.

어떻게 로드 밸런서가 람다 함수를 호출할까?

  • ALB에서 람다로 갈 때 http요청은 Json 문서로 변환된다.

  • 이렇게 http 요청 전부를 json 형식으로 ALB에서 바꿔서 람다 함수로 보내면 람다함수가 해석하는 것이다. 

이제 람다함수에서 json 형식으로 반환 값을 ALB에게 보낸다.

  • 이제 이 요청을 ALB에서 다시 http로 변환해서 사용자에게 전송한다.

ALB와 다중 값 파라미터

  • ALB는 다중 값 파라미터를 변환할 수 있는 기능을 지녔다.
    • 다중 값 파라미터란 동일한 key 값이 여러 개 존재하는 것을 의미한다.
    • 예를 들어, name = foo, name = bar 이라면 name이라는 동일한 키가 두 개 존재하는 것이다.
  • 이 경우 키 값이 같다면 람다 함수는 마지막에 들어온 값으로 밸류를 덮어 씌운다.
  • 만약 두 밸류 모두 사용하고 싶다면, ALB에서  다중 값 파라미터를 활성화 하면 된다.
    • 이 값을 활성화 하면 ALB는 다중 값 파라미터를 배열 형식으로 만들어 하나의 키 안에
      배열 형식으로 value를 집어넣어 두 값 모두 사용되게 만든다.

비동기식 호출

  • 백그라운드에서 람다 함수를 호출하기 위한 것이다. 결과를 기다리지 않고 호출한 뒤 다른 작업을 시도하는 게 비동기다.
  • s3, SNS, CloudWatch Events 등이 있다.
  • s3를 예로 들면, s3에 새로운 객체가 들어왔고, 이벤트가 발생했다.
  • 람다 함수는 비동기 처리를 위해 큐에 해당 이벤트를 저장해둔다.
  • 큐에 들어있는 이벤트는 총 3번 까지 실행이 된다.
  • 첫 번째 시도는 바로 이뤄지고
    • 실패할 경우, 두 번째 시도는 1 분 후에
    • 마지막 시도는 두 번째 시도 이후 2분 후에 시도된다. 
  • 같은 항목이 여러 번 실행될 경우 데이터베이스에 중간 작업물이 반복해서 저장된다거나 하는 문제가 발생할 수 있다.
    • 이러한 문제가 발생하지 않도록 람다 함수가 중간에 실패해도 처음 시도와 동일한 상태를 보장한다는 것이
    • 멱등적이다. 따라서 비동기 처리일 때 람다함수는 멱등적이어야 한다.
  • 만약, 람다 함수가 재시도 된다면, 클라우드 워치 로그에서 중복된 로그를 볼 수 있을 것이다.
  • DLQ를 정의할 수 있는데, 재시도로 성공이 절대 불가능한 경우에 람다 함수가 이벤트를
    SQS나 SNS로 보내서 나중에 처리가 되도록 할 수 있다.
  • 비동기 처리에서 람다 함수는 함수의 성공 여부와 상관없이 항상 상태코드 202를 반환한다.
    • 비동기식이기 때문에 함수의 성공 여부를 비로 반환할 수 없기 때문이다. 

  • 람다 함수를 비동기 식으로 호출하는 서비스는 다음과 같다. 

클라우드 워치 이벤트 / 이벤트 브릿지와 람다 함수의 통합

  • CRON 또는 Rate 사용
    • 일정 시간을 설정해두고 해당 시간 마다 람다 함수를 수행하도록 하는 방법이다.
  • 이벤트 브릿지 규칙 생성
    • 예를 들어, 코드 파이프라인 상태가 변경될 때마다 람다 함수를 호출하는 방식이다.

S3 Event Notification 과 람다 함수 통합

  • s3 객체에 복구나 복제 생성, 제거가 일어날 때 알림을 해주는 기능으로, 접두어, 접미어 필터링이 가능한 것이 s3 이벤트 알림이다.
  • s3는 총 세 가지 서비스에 알림을 보낼 수 있다.
    1. SNS: SNS에서 SQS로 보내는 팬 아웃 패턴
    2. SQS: 큐로 보낸 후 람다 펑션으로 보내는 처리방식
    3. 바로 람다 함수로 보내기

  • s3 이벤트 알림은 보통 몇 초 이내로 알림을 전달하지만 종종 1분 이상이 걸릴 수도 있다.
  • 모든 알림을 다 수신하고 싶다면
    • 버저닝을 활성화 해라
    • 버저닝이 없다면 동일 객체에 대한 두 번의 작성이 일어나는 경우 하나의 알림밖에 받지 못할 수도 있기 때문이다. 

람다 함수와 이벤트 소스 매핑 

  • 위의 예시들이 이벤트 소스 매핑에 해당하는 서비스들이다.
  • 위 서비스들의 공통점은 레코드가 소스에서 폴링되어야 한다는 점이다.
  • 즉 람다가 서비스에 레코드를 요청 해야, 레코드가 반환되는 것이다.
    • 람다가 직접 폴링해야된다는 것이다.
    • 여기서 람다는 동기식으로 작동한다.

  • 위의 예시를 살펴보면, 람다 함수가 키네시스에서 데이터를 읽어오려 하면, 내부에서 이벤트 소스 매핑이 생성된다.
  • 이벤트 소스 매핑은 배치 데이터를 키네시스에서 받아오고
  • 해당 배치 데이터와 함께 람다 함수를 호출한다.

스트림과 람다 함수 (키네시스, 다이나모 디비)

  • 이벤트 소스 매핑은 스트림 종류와 큐 종류 두 가지로 나뉜다. 스트림 종류를 먼저 살펴보자.
  • 스트림은 이벤트 소스 매핑이 일어났을때, 각각의 샤드가 독립적으로 들어오는 이벤트를 처리한다.
    그리고 샤드 레벨에서 아이템을 순차적으로 처리한다. 따라서 읽기 시작 위치를 구성할 수 있게 된다.
    • 새로운 아이템만 읽기를 하거나, 특정 타임스탬프부터 읽도록 구성이 가능하다.
    • 샤드에서 아이템이 처리될 때 아이템은 스트림으로부터 제거되지 않으며, 
      다른 소비자들이 데이터를 읽을 수 있다.
  • 트래픽이 낮은 경우: 
    • 배치 위도우를 사용해서 처리 전에 레코드를 축적한다. 
  • 트래픽이 매우 높은 경우:
    • 람다가 샤드 레벨에서 동시에 여러 배치를 처리하도록 병렬 배치로 설정할 수 있다.

스트림과 람다 함수 - 에러 핸들링

  • 기본적으로, 함수가 오류를 반환하면 함수가 성공할 때까지 혹은 배치 내 아이템(처리해야할 이벤트)이 다 소진될 때까지 모든 배치가 다시 처리된다.
  • 배치에 오류가 발생하면 모든 처리가 중단될 수 있다.
  • 그래서 순차적인 처리를 위해, 오류가 해결될 때까지는 오류의 영향을 받는 배치의 처리가 중단된다.
    • 이벤트 소스 매핑이 오래된 이벤트를 폐기하도록 구성할 수도 있고
    • 재시도 횟수 제한이나, 오류 발생 시 배치 분할 등을 사용할 수 있다.
      • 람다가 배치 전체를 처리할 능력은 없어도, 절반은 처리할 수도 있으니

람다 함수와 큐 

  • 큐도 동일하다.
  • 이벤트 소스 매핑이 발생하고, 이벤트 소스 매핑에서 큐의 데이터를 배치로 폴링해와서 람다 함수로 보내 처리한다.
  • 람다함수는 동기적으로 호출될 것이다.
  • 이벤트 소스 매핑이 긴 폴링을 사용해 SQS를 폴링한다.
  • 배치 사이즈는 1~10까지 설정이 가능하다.
  • 대기열 표시 시간초과(일정 시간 동안 대기열에 메세지를 보이지 않게 하는 것)를 람다 함수 시간초과의 6배로 설정하는게 가능하다고 한다.
  • DLQ를 만드는 경우 DLQ를 람다가 아닌 SQS 큐에 설정한다.
    • 람다함수용 DLQ는 비동기식 호출에만 작동하기 때문에 SQS로 DLQ를 만들어야 한다고 한다.

람다 함수와 큐 2

  • 피포 큐를 사용하는 경우 람다도 순차적 처리를 지원한다. 
  • 대기열을 처리하기 위해 스케일링 될 람다 함수의 수는 활성 메세지 그룹의 숫자와 동일하다.
    • 그룹 아이디 별로 독립적으로 실행되기 때문에 람다 함수는 그룹 숫자와 동일해야 한다.
  • 표준 대기열을 사용하면 아이템이 순서대로 처리되지 않는다.
  • 표준 대기열에서 람다는 대기열의 모든 메시지를 읽을 수 있도록 최대한 빠르게 스케일링 된다.
    • 대기열에 오류가 발생하면, 배치는 개별 아이템으로서 대기열에 반환될 것이고
    • 원래 배치와 다른 그룹에서 처리될 수도 있다.
  • 가끔 이벤트 소스 매핑이 함수 오류가 일어나지 않았음에도 불구하고, 대기열로부터 같은 아이템을 두 번 수신할 수도 있는데,
    • 그럴 경우 람다 함수에서 아이템이 처리되도록 해야한다.
  • 마지막으로 람다에서 아이템이 처리되면 람다는 대기열에서 아이템을 삭제할 것이고 아이템은 대기열에 나타나지 않는다.
  • 큐를 구성하여 처리되지 않은 아이템들을 DLQ로 보낼 수 있다.

람다 함수의 스케일링

  • 키네시스와 DynamoDB:
    • 샤드 당 하나의 람다 함수를 호출한다.
    • 병렬 처리를 사용하면 샤드당 동시에 10개 배치까지 처리할 수 있다.
  • 표준 큐:
    • 스케일 업을 위해 분당 60개의 람다 함수를 추가한다.
    • 초당 최대 1000개의 배치를 처리할 수 있다.
  • 피포 큐:
    • 그룹 ID가 같은 메시지는 무조건 순서대로 처리되고
    • 람다 함수는 활성 메시지 그룹의 수만큼 스케일링 된다. 

 

람다함수 - Event and Context Objects

  • 이벤트 객체가 무엇인가
    • 예를 들어, 이벤트 브릿지에서 이벤트가 발생했고, 해당 이벤트가 람다 함수로 전송되면
      전송되는 이벤트를 이벤트 객체라고 한다.
    • 이벤트 객체에는, 이벤트가 어디에서 발생했는지, 이와 관련된 서비스에 어떤 데이터가 있는지
      등이 포함되어 있다.
  • 컨텍스트 객체란 무엇인가
    • 함수에 대한 메타데이터가 들어있는 것이다.
    • 함수의 AWS 요청 ID, 함수 이름, 함수의 로그 그룹, 사용 가능한 메모리 등이 컨텍스트 객체다.
  • 두 객체는 상호 보완적이다.

이벤트 객체

  • 이벤트 객체는 JSON 형태의, 함수가 처리할 데이터를 갖고 있는 문서다.
  • 이벤트 브릿지나 SQS, SNS 같이 호출되는 서비스는 람다 함수가 이벤트를 처리할 때 필요한 모든 정보를
    갖는 셈이다.
  • 람다 함수의 환경에 따라서 이벤트 객체는 환경에 맞게 적절하게 변환된다.
    • 예를 들어, 파이썬에서 이벤트 객체는 딕셔너리로 바뀐다.
    • 물론 입력된 파라미터들도 다 변환된다.

컨텍스트 객체

  • 컨텍스트 객체는 런타임 환경과 호출 자체의 데이터를 갖고 있다.
  • 런타임 과정에서 람다가 이 객체를 함수에 전달하고
  • AWS 요청 ID, 함수명, 사용 가능한 메모리량과 같은 정보가 전달 되어 람다 함수에서 사용된다.

  • 이벤트 객체엔 이벤트 소스, 리전 정보가,
  • 컨텍스트 객체에는 함수 이름, 메모리 량, 로그 스트림명, 로그 그룹명 같은 것이 포함 돼 있다.

람다 함수 - Destinations

  • 기존엔 비동기식 호출을 하거나 이벤트 매퍼를 사용할 때, 성공인지 실패인지를 쉽게 알 수 없다는 문제점이 있었다.
  • Destination은 비동기식 호출과 이벤트 매퍼의 실패 결과를 다른 어딘가로 전송하는 개념이다.

비동기식 호출

  • 비동기식 호출에선 성공 이벤트와 실패 이벤트 모두 목적지를 정의할 수 있다.
  • 성공 및 실패 구분은 이벤트 처리 여부로 이뤄진다.
  • 비동기식 호출의 목적지는
    • 람다, SQS, SNS, 이벤트 브릿지 버스가 있다.
  • 비동기식 호출의 DLQ와 굉장히 유사하다.
  • 그래서 이 기능이 나오고 난 후에는 DLQ 대신 목적지를 사용하는 것이 권장된다고 한다.
    • DLQ는 SQS와 SNS로 실패만 전송하도록 하지만, 
      목적지 기능은 성공과 실패 모두 더 다양한 목적지로 보낼 수 있기 때문이다.

이벤트 소스 매핑

  • 처리할 수 없는 이벤트 배치를 폐기하는 경우에 사용된다.
  • 목적지는
    • SQS, SNS가 있다.
  • 키네시스로부터 읽기를 해 이벤트 소스 매핑이 있을 것이고, 
    데이터 처리에 실패한 경우에는, 실패한 배치를 이벤트 목적지로 전송한다.
  • 그러나 이벤트 소스 매핑이 SQS에서 읽기를 하고 있다면 
    바로 DLQ로 보낼 수 있다는 사실도 알아두자. 

람다 함수 Execution Role

  • 람다 함수는 IAM Role을 통해 서비스와 리소스에 액세스할 수 있는 권한을 갖는다.
  • 이벤트 소스 매핑으로 함수를 호출할 때마다, 이벤트 데이터를 읽기 위해 Role을 실행하는 것이 람다다.
  • 람다 함수가 다른 서비스를 통해 호출된 경우라면, 특정 IAM 역할이 필요 없다.
    • 이 경우 다른 서비스가 람다 함수를 호출할 역할이 필요하다.
    • 다른 서비스가 람다를 호출할 수 있는 건 두 가지의 경우가 있다.
      • 사용자의 IAM 정책에서 람다 함수 접근 권한이 있는 경우
      • 리소스 기반 정책을 가지고 람다 함수로 권한을 부여하는 경우
  • 이벤트 소스 매핑이나 람다함수가 다른 서비스를 호출해야 하는 경우에 사용된다.

리소스가 람다함수를 호출하는 경우에, 리소스 기반 정책으로 리소스에서 람다 함수를 호출하고

람다 함수가 데이터를 폴링하는 경우에, 람다 함수가 직접 폴링을 해와야 하므로, 람다 Execution Role을 사용한다.

 

람다 함수 환경 변수

  • 람다에서 환경 변수란 코드를 업데이트하지 않고도 함수 행위를 조정할 수 있는 것이다.
  • 키 밸류 쌍으로 이뤄져있다.
  • 환경 변수는 코드에 작성할 수 있다.
  • 코드에 작성한 환경변수는, 자체 시스템 환경변수와 같이 사용할 수 있다.
  • 환경변수는 kms를 사용하여 암호화 할 수 있다.
  • 환경변수는 람다 서비스 키나 cmk로 암호화 될 수도 있다.