사내에서 Presigned URL을 통해서 서버 부하가 개선되었고, 썸네일 생성 역시 실시간 리사이징을 통해서 불필요한 썸네일 보관 비용을 낮추는데 큰 도움이 되었다.
실시간 리사이징을 위한 Cloudfront + Lambda edge의 비용이 폭증하였다. 하루 평균 2달러 부과되던 것이 하루에 88달러가 청구되었다. 왜 그랬을까?
람다 함수로 인해서 유럽 프랑크프루트만 234달러가 청구되었다.
일단 람다 엣지가 무엇이냐?
Lambda@Edge는 서버 관리 부담 없이 웹 애플리케이션을 전 세계로 배포하고 성능을 개선하여 효과를 향상해 줍니다. Lambda@Edge는 Amazon CloudFront 콘텐츠 전송 네트워크(CDN)에 의해 생성된 이벤트에 대한 응답으로 코드를 실행합니다. 코드를 업로드하기만 하면 AWS Lambda가 최종 사용자와 가장 가까운 AWS 로케이션에서 뛰어난 가용성으로 코드를 실행하고 확장하는 데 필요한 모든 작업을 처리합니다.
일단 람다 함수랑 동일하게 리소스와 실행시간에 따라서 비용이 부과되는데, CloudFront 이벤트에 의해 트리거 될 수 있다는 점이다.
- End User : 클라이언트
- CloudFront : CDN 서비스
- Origin Server : S3
아래 4가지 위치에서 람다 엣지를 트리거할 수 있다. 자세한 건 공식 문서 확인하세요
실시간 이미지 리사이징을 하기 위해서 Origin response에 Node js Sharp 라이브러리를 사용하여 image resizing할 수 있도록 람다 엣지를 구성해뒀다.
3번 리사이징할 때, 당연히 Origin Server에서 받은 이미지를 그대로 사용하면 될 것 같지만 사용할 수 없다고 한다. S3 GetObject로 이미지를 새로 받아야한다. 왜 그런지 궁금하지만 일단 넘어간다.
기존 이미지 처리 사양과 동일하게 하다보니 오버 스펙으로 적용했다는 것을 cloudwatch에서 확인할 수 있었다. 아래 쿼리를 cloudwatch insight에서 실행하면 잔여 메모리를 구할 수 있다. 하지만, lambda 함수는 메모리와 CPU사양을 따로 관리할 수 없다. 메모리 사양을 올리면 올릴 수록 CPU사양이 올라간다는 것만 알 수 있다. 그렇기 때문에 적절한 시도로 사양 선택을 할 필요가 있겠다.
filter @type = "REPORT"
| stats max(@memorySize / 1000 / 1000) as provisionedMemoryMB,
min(@maxMemoryUsed / 1000 / 1000) as smallestMemoryRequestMB,
avg(@maxMemoryUsed / 1000 / 1000) as avgMemoryUsedMB,
max(@maxMemoryUsed / 1000 / 1000) as maxMemoryUsedMB,
provisionedMemoryMB - maxMemoryUsedMB as overProvisionedMB
그리고 aws blog에 keet alive 설정을 하여 외부 엔드 포인트에 대한 연결을 유지함으로써 이미지 다운 받는 시간을 단축할 수 있다고 하여 이도 적용을 했다.
Lambda@Edge 호출에서 유지되는 외부 엔드포인트에 대한 영구 연결을 설정하는 것입니다. 이는 네트워크 호출 간 경과 시간이 끝점의 연결 유지 제한 시간보다 짧을 때 잘 작동합니다. 영구 연결을 사용하면 모든 호출에 대해 TCP/TLS 연결을 다시 설정하지 않아도 되므로 반복되는 연결의 대기 시간 비용이 제거됩니다.
12h동안 람다 엣지가 1초 이상/1초 이하 걸린 호출 수의 비중과 실제로 나온 한달 사용료를 매칭해보니 실제로 S3 ~ cloudfront edge location과 멀리 떨어져 있었을 때가 가장 많이 나왔다.
한국 이 외에는 모두 글로벌 서비스로 us-west-1 bucket을 사용하고 있다. 그로인해 거리적으로 먼 아시아나 유럽은 람다 실행시간이 늘어나고 비용이 커진다는 것을 알 수 있다.
일단은 유럽에서 많은 트래픽이 발생하고 비용도 절반 이상이다. 그래서 프랑크프루트 근처의 s3를 두어 그 근처에서 서비스를 이용하는 사람들은 해당 s3에 저장하도록 서비스를 개선해나가려고 한다.