우당탕탕 On-The-Fly Image resize 전환기

June·2024년 1월 6일
0

회사 서비스를 리뉴얼하며 이미지 처리 방식을 On-The-Fly image resizing 방식으로 전환하며 겪은 일들에 대한 공유이다.

기존 방식

기존의 서비스는 클라이언트에서 ruby on rails 서버에 form 데이터로 이미지를 전송하면 carrierwaveMiniMagick 를 사용해 각 도메인별로 필요한 버전(크기)을 생성한 뒤 s3에 업로드하는 방식

개선 필요성

  • 특정 도메인의 이미지들에 새로운 버전이 필요하게 되거나 버전의 크기 규칙이 바뀌는 경우 해당하는 모든 이미지들에 대해 다시 재생성해서 저장해야 하므로 디자이너나 기획자의 요구에 유연하게 대응하기 힘들다.
  • 하나의 이미지에 대해 여러가지 버전별 이미지를 모두 저장해야하기 때문에 S3 저장 용량이 대폭 증가한다.
  • 메인 api 서버에서 이미지 처리를 직접 처리하고 있었기 때문에 시스템 리소스의 부하가 심하다.
  • 리뉴얼을 진행하며 메인 api 서버를 framework를 Nest.js로 전환 함에 따라 메인 api 서버와 이미지 처리의 분리가 필요하다.

해결책 고려하기

  • Lambda@Edge 를 이용한 이미지 리사이징 : 당근마켓, 트레바리 등 다른 여러 서비스에서도 적용시키고 있는 방법이지만 Lambda@Edge 의 quotas 중 응답의 크기가 1MB를 넘을 수 없다는 제약사항이 존재했고, 썸네일 이미지 뿐만 아니라 4k 정도의 고화질의 이미지까지 다뤄야했기 때문에 이 방법은 사용불가
  • ECS 클러스터로 On-The-Fly 이미지 리사이징 서버 구현 :
    • Lambda를 사용하는 대신 직접 서버를 구축하고 ECS로 관리하면서 CDN에 캐시 될 수 있도록 구현했었으나, 이미지 프로세싱 특성상 많은 시스템 리소스를 사용하기 때문에 한 페이지에 수십개의 이미지가 존재하게 되면 (Cache miss의 경우) 시스템 리소스의 스파이크가 심했고, 응답 속도가 심하게 느려졌다. 응답속도를 위해 많은 태스크들을 24시간 운영하는 건 비용과 운영 측면 둘 다 배보다 배꼽이 더 큰 상황이라 사용불가 판정
  • Lambda로 직접 구현 (채택) : Lambda의 경우 최대 응답 크기가 6MB로 고화질의 이미지도 처리하기 충분하다고 판단했고 24시간 서버를 운영해야하는 부담도 없기 때문에 해당 방법을 채택

구현

  • AWS Solutions 에서 제공하는 예시 가 있긴 하지만 Amazon Rekognition까지 포함된 서비스를 CDK로 제공하고 있었고, Sharp의 다른 옵션들도 클라이언트가 요청할 수 있도록 확장할 수 있도록 직접 재구축
  • 예시에서는 AWS CDK로 구현되어 있으나 팀에 CDK에 익숙한 개발자가 없었고, 개인 경험상 lambda를 다룰 때는 serverless framework가 초기 러닝커브가 가장 작다고 판단하여 serverless framework로 인프라를 구축하도록 변경
  • 복잡한 쿼리 파라미터를 다루는 대신 이미지 요청 옵션을 base64 인코딩된 문자열을 path로 전달하고, Lambda함수에서 해당 옵션 객체를 다시 객체로 파싱하여 처리하는 방식을 사용
  • 고화질의 이미지 더 적은 용량으로 제공하기 위해 format을 webp로 전환하기로 결정했고, format 변환 여부도 옵션으로 전달하도록해서 클라이언트가 webp 지원여부에 따라 이미지를 선택적으로 요청할 수 있도록 가능성을 열어둠
    • // Image 요청 객체 타입
      export interface ImageEvent {
        bucket: string;
        key: string;
        edits?: {
          resize?: {
            fit: ImageFit;
            width: number;
            height: number;
          };
          format?: {
            type: ImageFormat; // jpeg, png, webp, gif ... 
            quality?: number;
          };
        };
      }

결과

  • 미술 도메인 특성상 이미지에 대한 기획자나 디자이너의 변경 요청이 잦은 편인데, 빠른 대응이 가능하게 됨
  • webp 지원으로 클라이언트에게 응답해야할 이미지 용량이 약 20% 감소
  • 버전별 이미지를 이미지당 5~7개 씩 저장하고 있던 S3의 이미지를 하나만 저장할 수 있게 되어 버킷 저장 공간이 약 45~50% 정도 절약 할 수 있게 되었고 그에 따라 인프라 비용도 감소

더 개선하기

  • 간헐적으로 4K 이상의 이미지의 경우 6MB가 넘는 경우가 있는데 이 경우 현재는 Lambda 함수에서 크기를 체크하여 재귀적으로 재호출하여 이미지 quality를 낮추는 방식으로 대응했으나 API Gateway의 응답 제한시간이 30초이고, 고화질의 이미지를 여러번 프로세싱하게되면 초기 응답속도가 매우 늦다는 단점이 존재
    • 이미지 업로드 시 이미지가 너무 큰 경우 크기를 줄여 저장하는 방식으로 변경 필요함

참고

0개의 댓글

관련 채용 정보