실무에서 이미지 리사이징을 위해 aws Lambda를 설정하는 업무를 맡았다.
s3에서 발생하는 이벤트를 확인하고 원본 파일이 저장되는 시점에 썸네일을 위한 이미지도 추가적으로 회사 내 규격에 맞게 리사이징해 저장하는 내용이었다.
첫번째로 시도한 내 작업 내용은 다음과 같다.
s3 트리거 설정
초반엔 람다 설정에 대해 깊게 고민하지 않고 서둘러서 기능구현을 한 뒤 모바일 팀에게 썸네일 경로를 넘겨 앱에서 테스트하고 이후 고도화를 하는 방향으로 작업을 진행했다.
python으로 리사이징 로직 구현
기존에 서버에서 사용하던 java가 아닌 python을 선택한 이유는, 이미지 처리와 관련된 다양한 라이브러리를 통해 상대적으로 빠르게 기능구현이 가능할 것이라고 생각했기 때문이다.
작업하면서 생각지도 못한 문제를 만나게 되었는데,
Temp 폴더에서 저장할때 ObjectCreated:Put 이벤트에도 반응을 하는 바람에 썸네일이 무한 생성되는 증상이 발생했다.
- 원본을 저장하면서 발생하는 ObjectCreated:Put 이벤트의 원본이미지 하위 디렉토리로 THUMBNAIL 디렉토리 생성 후 리사이징
- 리사이징하는 이미지를 저장하면서 발생하는 ObjectCreated:Put를 THUMBNAIL 디렉토리 생성 후 리사이징
- 그 이미지를 다시 리사이징....
이 증상은 원본이 임시 저장되는 temp가 아닌 실제 디렉토리에 저장될 때 발생하는 ObjectCreated:Copy 발생시에만 리사이징을 하는 것으로 수정해서 해결했다.
문제점 해결 후 의도했던대로 원본 폴더와 함께 썸네일이 생성되는 것을 확인했다.
동작을 확인했으니 성능테스트를 할 시간이 되었다.
성능테스트는 업로드 제한이 걸린 최대규모 기준으로 진행했다.
(최대 10MB, 7개까지 한번에 업로드 가능)
초반에 우려했던 리사이징이 비동기로 동작하기 때문에 게시글이 올라간 직후 해당 게시글의 썸네일 경로에 아직 리사이징 파일이 생성되지 않아 보이지 않는 경우는
게시글 업로드가 완료될때까지 앱에서 로딩 화면 조건을 걸어 문제를 피할 수 있었다.
사용자가 파일 업로드 시 리사이징에 걸린 시간은 평균 1600ms 였다. 이는 리사이징만 측정한것이었기 때문에 원본 업로드 후 썸네일 디렉토리에 리사이징된 파일이 생성되는데까지는 2000ms 정도 소요되었다.
앞서 설명한 것처럼 업로드 직후 이미지 호출에 대한 문제는 미리 방지해두었기에 지금상태로도 사용하는데 지장은 없었지만 좀 더 빠르게 동작하는 방법이 없는지 고민하게 되었다.
s3 트리거 설정변경
모든 이벤트 트리거 -> copy, delete 만 트리거하도록 변경.
이 전까진 모든 s3 이벤트를 확인하고 동작하도록 설계가 되어있었으나, 리사이징에 필요한 copy와 delete 이벤트만 트리거되도록 s3 트리거 설정을 수정했다.
리사이징 시 원본 copy기능 삭제
내가 사용했던 Pillow 라이브러리의 thumbnail 메서드는 메모리 내에서만 수행되는 작업으로, 원본 이미지 파일에는 영향을 미치지 않기 때문에 굳이 image.copy를 시행하지 않아도 된다는 것을 알게 되었다.
resized_image = image.copy()
resized_image.thumbnail(size)
-> image.thumbnail(size)
리사이징에 걸리는 시간을 평균 1600 ms에서 940 ms까지 단축시킬 수 있었다.