참고: https://www.youtube.com/watch?v=0PRjqEQ2J3g&t=56s
https://www.slideshare.net/awskorea/aws-lambda-aws-aws-summit-seoul-2019
Front End Invoke: 실제 API call을 받는 역할(동기 / 비동기 호출 모두 관장)
(Synchronous Inoke)
Counting Service: 사용자가 얼마나 많은 API 요청을 하는지 모니터링하고 제한 기능 제공
Worker Manager: 실제 Container의 상태를 관리하고 API 요청을 가용 가능한 Container로 중계
Worker: 고객 함수(코드)가 안전하게 실행되는 실제 Container 환경
Placement Service: Worker에 Sandbox 구성을 자원 활용률이 높고, 고객 서비스 영향이 없도록 관리
Load Balancing & Auto Scaling
(Worker가 있는 건 알겠는데 얼마나 바쁜지 일을 더 줘도 되는지 Mgr가 Placement에게 물어본다.)
(필요한 Function이 일하고 사라지는 개념, 일을 다하면 리소스에 대한 return → 이 역할도 Placement 담당)
Handling Failures
멀티 AZ로 관리 되기 때문에 한 AZ에서 장애 발생해도 상관 없다!
Isolation
고객의 Workload = function = code는 항상 안전한 환경에서 실행한다.
Firecracker (하나의 host 내에서 수백개 ~ 수천개 단위의 vm 돌아갈 수 있음)
→ 하나의 코드가 그냥 독립되어서 돌아간다고 생각하면 됨
https://github.com/firecracker-microvm/firecracker
이렇게 되면 굉장히 많은 vm이 동시에 제한된 하드웨어 리소스를 공유하는 건데 충돌 발생 안하나???
→ Guest OS에서 Host OS로 접근할 때의 Driver를 개선! (firecracker device 안에서 직접적으로 하드웨어를 액세스)
(VirtIO: 게스트 커널의 디바이스 드라이버와 협력해 게스트 커널을 부팅하는데 필용한 하드웨어를 가상으로 제공)
- Guest OS가 VirtIO 드라이버에 쓰기 요청
- VirtIO 드라이버가 커널 링 버퍼의 공유 메모리에 요청을 PUSH
- Firecracker가 쓰기 요청을 풀고 물리 디스크에 쓰기
Utilization
"Lambda의 경우 사용한 만큼 요금을 지불하기에 주어진 시간 내 최대한 시스템을 바쁘게 돌려야 좋다."
→ 균형 잡힌 분배가 아닌 몰빵
동일한 Workload를 한 곳에 담게 되면 자원에 대한 충돌이 일어날 확률이 높다.
→ 각 각 다른 타이밍에 다른 자원을 사용하는 멀티태스킹을 해라!
Worker 외부의 RemoteNAT 컴포넌트로 ENI와의 NAT 처리 진행
- 시간이 많이 걸리는 처리는 Lambda Function의 스케일 시가 아닌 Lambda Function 작성 시에 실행되므로 스케일이 빨라진다
- VPC Lambda의 대기 시간이 낮아지고 대기 시간이 예측하기 쉬워진다
- ENI 및 IP 주소 범위에 제한을 두지 않고 VPC Lambda를 실행할 수 있다
- 하나의 ENI를 많은 Worker에서 공유하고 이용하기 때문에 IP 주소의 소비 수가 줄어 NW 관리가 간소화된다
Lambda 와 RDS/RDBMS 접근
- 여러 가용 영역 내 Subnet에 ENI 사용: AZ 레벨의 이벤트 또는 IP 소모 문제 피할 수 있음
- Lambda는 VPC 내 ENI로 접근: 가용 IP에 따른 확장성의 제약을 고려해야한다, ENI 신규 구성은 시간이 소모됨.
- Public host name DNS 쿼리를 피할 수록 좋음
- 기본적으로 VPC의 Lambda는 인터넷 접근 불가능: NAT 추가하고 Routing Table 구성 필요
DB 커넥션 관리는 어떻게 해야할까?
(수많은 Lambda가 필요할 때)
- Connection Pooling과 Lamdba
- Container 당 하나의 connection 만 사용: Connection Pool Size = 1
- Handler 밖에 Global section 에 DB connect 객체를 생성, 재활용
위처럼 하면 생기는 문제점
- Lambda container가 사라지는 지 인지할 수 없음: Connection을 명시적으로 닫을 수 없음(Database TTL에 의지)
- Lambda container의 생성 삭제를 조정할 수 없음: Idle(대기) connection이 많이 생성될 수 있음
- 여러 Lambda 함수 실행은 여러 다른 Container에서 실행될 수 있음: Connection 재사용 보장 못함
해결 방법 1: Concurrency limit
- 계정 Concurrency 제한 / 함수 Concurrency 제한
- AWS support - Account 제한 요청
- Lambda는 호출 제한이 있을 경우 retry 수행/관리
"Concurrency limit: 본인의 전체 서비스에 문제가 없도록 보호하기 위해 존재, 필요에 따라 조절 가능"
- Account level: 계정 내 모든 lambda에 적용되어 DB 접근 함수 제한이 간단하지 않음
- Function level: 어떤 Lambda 함수가 DB 접근이 필요한지 확인, Peak 발생하기 전에 알고 App 레벨의 이해 필요
해결 방법 2: 동적 Connection 관리
- 확장 가능한 구조 구현
- Connection 수를 관리 가능, Lambda 함수 개수와 무관
- 고려 사항: 관리 리소스 증가, Connection 재사용 불가, 약간의 Latency 증가
❗ 그래서 결론적으로 뭔 소리냐...? ❗
(Lambda + RDS의 경우 문제점)
1) lambda와 rds가 connection을 맺었는데 lambda가 명시적으로 connection 종료를 하지 않은 채 없어졌는데, 또다른 요청이 들어왔을 경우 새로운 connection을 맺게 됨...(max_connection 문제)
2) lambda가 과도하게 invoke, 실행되는 동안 모든 lambda가 connection을 맺게 되면 또 max_connection 초과
(해결 방안)
1) Connection 관리: handler 하나에 1 Connection / globel scope으로 connection 관리
2) RDS Proxy: Connection Pool은 Proxy가 가지고 있고, Lambda는 프록시를 통해 대신 Connection을 사용
3) API 호출 최적화: lambda가 동시에 적게 실행 + Connection이 빠르게 반환되게
그래도 가능하다면 DynamoDB나 AWS Aurora와 같이 Scale Out이 가능한 DB를 사용하는 것이 좋다.
Tip. Lambda 함수 트레이싱
- 필요한 이유("lambda는 실행 후 사라지는 개념..")
- 서버리스 아키텍처/애플리케이션 개발 시 Debug 편의성
- 서버리스 아키텍처/애플리케이션 동작 시 성능 문제 해결의 편의성
- 방법
- CloudWatch를 통한 Metrics 모니터링
- CloudWatch log 통한 log 분석
- log와 metric으로 부족한 경우:
- 전체 요청 처리 시 서버리스 함수 간의 관계 파악 확인
- 요청 처리 시 다른 리소스 접근에 대한 관계 파악 확인
- → X-ray 서비스 활용: 서버리스 아키텍처를 만들고 람다로 서비스 개발 시 전체 흐름 확인
Tip. Lambda 커스텀 런타임 사용
- Layer 기능을 활용하자!
'Cloud > AWS' 카테고리의 다른 글
[AWS] Lambda에 X-Ray 적용하기 (0) | 2022.11.06 |
---|---|
[AWS] Serverless Service - Lambda 편 (3) (0) | 2022.11.06 |
[AWS] Serverless Service - Lambda 편 (1) (0) | 2022.11.05 |
[AWS] API Gateway - Websocket API (0) | 2022.11.01 |
[AWS] Lambda Warm Start / Cold Start (0) | 2022.10.28 |