Lambda Function URL을 활용한 개선된 아키텍처
<aside> 🚫
초 단위의 변환 소요 시간으로 인해 이미지 업로드 직후에는 조회 불가한 경우 발생
</aside>
어드민 메뉴 사진 업로드
변환 작업 속도를 개선하는 방안을 찾지 못해 임시 방편으로 변환이 완료되기 전까지는 원본을 조회하는 방법을 구현하기 위해 삽질하다가, 이미지 사이즈(폭, 높이)를 줄인 이후 포맷을 변환했을 때 획기적으로 시간이 줄어듦을 확인했다
cloudfront function에서 반환할 이미지 데이터 없는 경우 원본 s3 presigned URL 발급 → aws sdk 사용 불가
람다 함수 맨 처음에 원본을 webp 버킷에 COPY하는 로직 추가
copy_object()
인자로 CacheControl
설정하여 원본 이미지인 경우 캐시 기간 짧게 설정CloudFront 원본으로 Lambda Function URL 지정
<aside> 💡
S3 트리거를 사용한 기존 람다는 그대로 유지하고, 변환 완료 전에 원본을 조회하는 로직을 담은 신규 람다 배포
</aside>
Cache-Control
설정으로 CloudFront의 캐시 기간 조절 가능원본 사진 용량 제한을 더 낮게 → 사용자 경험을 위해 하는 작업인데, 더 큰 제약을 가하는 역설적인 방안
람다 메모리 할당량 증가 → 현재 더 이상 높일 수 없음
변환 품질을 더 낮게 → 속도는 비슷하고, 결과물의 용량만 더 낮아졌다
nodejs + sharp로 구현 → 성능 비슷, 익숙하지 않은 언어로 유지보수 불편
포맷 변환 전에 리사이징 ✅
<aside> 🛠
원본 8.5MB 이미지 기준 500X500px로 줄였을 때 약 3s → 약 500ms
대부분의 경우 원래 사이즈보다 훨씬 작은 형태로 노출되기 때문에 좋은 방법
</aside>
from io import BytesIO
from PIL import Image
image = Image.open(BytesIO(image_data))
output_buffer = BytesIO()
image.convert("RGB").save(output_buffer, format="WEBP", quality=80)
output_buffer.seek(0)
from io import BytesIO
from PIL import Image
image = Image.open(BytesIO(image_data))
image.thumbnail((500, 500)) <------------------------------------------
output_buffer = BytesIO()
image.convert("RGB").save(output_buffer, format="WEBP", quality=80)
output_buffer.seek(0)
<aside>
변환본을 S3에 저장하지 않고, CloudFront로 컨텐츠 조회 요청이 왔을 때 On Demand로 이미지 변환 후 Edge Location에 캐싱