team logo icon
article content thumbnail

S3, 이미지 용량 관리를 어떻게 할 수 있을까?

S3의 용량을 조금이라도 관리하고 줄여볼 수 있을까? 에서 시작된 고민의 과정

1. AWS S3


AWS S3 즉, Amazon Simple Storage

AWS 에서 제공하는 객체 스토리지 서비스다.

파일 혹은 이미지 저장을 경험해 보거나 고민해본 사람은 한번쯤을 들어봤을 것이고,

Palmspring 또한 이 S3를 이용하여 이미지를 저장하고 관리하고 있다.

2. S3 용량의 고민


블로그를 운영해보면 다들 알겠지만, 맘에 들어서 작성하던 글이, 마음에 들지 않아 뒤로 가기를 누르거나 엎어버리는 일이 있었을 것이다.

개발에 있어 사용자의 경험이 중요하기도 하고,

특히 이 글을 작성하는 나부터 그러했기에 쌓이게 두어서는 안된다고 판단했다.


그렇게 Palmspring의 한가지 고민이 여기서 시작됐다.

  • 이미지의 용량 관리를 어떻게 할 수 있을까?


각 글을 작성하며 썸네일에


쓰지 않는 이미지를 한 두장 들어가게 한다고 문제가 있을까?”

싶을 수도 있겠지만

이 글이 백개 아니 만개가 된다면? 적지 않은 용량을 차지하게 될것이다.

2-1. Palmspring의 이미지 저장


우선 앞서 말한 바와 같이, 사용자의 경험에 빗대어 만약 내가 이 햄스터 이미지를 글에 넣었다고 가정 해보자.


만약 여러분들이 이 이미지 링크를 눌러 확인해본다면, 해당 사진이 s3 이름이 붙어있는 것을 확인 할 수 있다.


예상한 바와 같이, Palmspring은 유저가 이미지를 넣기를 누르는 순간에, S3에 이미지를 저장하여 그 링크를 보여주고 있다.


예를 들어 VelogNotion같은 대표적인 서비스들을 이용하던 도중

이미지를 확인하면 나의 블로그 이름/아티클 이름이 붙는 것을 알 수 있다.


나 또한 이렇게 바로 저장하도록 구현한다면 괜찮을까?

만약 내 썸네일이 마음에 들지 않아 여러번 바꾼다면,

이 사진들의 용량은 어떻게 되는걸까?

2-2. 확인


유저 경험으로 돌아가보자.

타 블로그를 사용하는 여러분이 만약 이미지를 넣은 채로 뒤로 간다면, 예를 들어 약 3달 전에 발행하지 않고 뒤로가기 했던 타 블로그의 사진 링크를 확인해보았다.



어디의 블로그인지 얘기 하지 않으려 사진만 가져왔으나,

약 3달전인데도 해당 링크로 이미지가 접속 가능한 것을 확인할 수 있었다.

이로써 구현 방법에 대한 힌트를 얻지 못한채로

즉, 우리는 Palmspring 만의 용량 관리 방법을 찾아야 했다.

3. S3 용량을 줄이는 방법


사실 S3에는 S3 수명주기 라는 용량을 줄이는 방법이 이미 존재한다.

AWS S3 수명주기

S3 Lifecycle – Configure a lifecycle configuration to manage your objects and store them cost effectively throughout their lifecycle. You can transition objects to other S3 storage classes or expire objects that reach the end of their lifetimes.


짧게 설명하자면 주기 설정을 통하여 전환, 혹은 만료가 되도록 할 수 있는 기능이다.

그렇다면 이걸 사용하면 되지 않은가?


3-1. 사용하고 있는지, 사용하지 않고 있는지 어떻게 확인 할 수 있을까?



사용하더라도, 우리는 이 사진이 유저가 사용하고 있는지의 여부를 확인 할 수 있어야 한다.


얼마나 될지 모르는 유저가 작성한 모든 글을 하나하나 비교하며 삭제할 수는 없다.

그렇다면 어떤 방법이 있을까?


물론 더 좋은 방법들이 많고, 아직 더 연구해야할 방법은 많지만 당시 상상으로 가설만 세웠을때는 이러했다.

1. 넣은 이미지를 리스트에 넣고 해쉬맵으로 전송한 사진만 true로 바꾸어 전송하면, 서버에서 해당 사진만 S3에 저장한다.

2. 사진을 가지고 있다가 뒤로가기를 하는 경우 해당 사진 url을 받아 삭제한다.

3. 처음엔 delete라는 폴더에 저장했다가 실제 저장 이미지만 실제 도메인 이름이 달린 폴더로 이미지를 복사해 넣고, delete라는 폴더는 주기적으로 삭제해준다.


나는 이중 3번을 선택하게 되었다.

4. 해결의 과정


앞서 말한 과정을 구현하기 위해서는 먼저, 이미지를 복사 해줘야 한다.

🚨 우선 해당 코드는 제 Bucket 이름에 맞게 구성되었기 때문에 복사하시는 분들은 본인들의 Bucket에 맞게 작성해야 한다는 부분을 먼저 알립니다 🚨


S3에는 CopyObjectRequest 라는 이름의 복제 기능을 가지고 있다.

   public String copyImage(String imageUrl, String url) {

        String orgKey = imageUrl.substring(68);

        String copyKey = url + "/" + orgKey.substring(7);

        CopyObjectRequest copyObjectRequest = new CopyObjectRequest(this.bucket, orgKey, this.bucket, copyKey);

        this.amazonS3Client.copyObject(copyObjectRequest);

        return imageUrl.substring(0,68) + copyKey;
    }


CopyObjectRequest에는 우선 3가지 요소가 필요하다.

  1. bucket 이름

  2. orgKey

  3. copyKey

4-1. Key란?


S3 에서 Key란 이미지의 고유한 경로, 혹은 식별자라고 볼 수 있을것 같다.

여기서 공식 문서를 언급하자면

An object key (or key name) is the unique identifier for an object within a bucket. Every object in a bucket has exactly one key. The combination of a bucket, object key, and optionally, version ID (if S3 Versioning is enabled for the bucket) uniquely identify each object. So you can think of Amazon S3 as a basic data map between "bucket + key + version" and the object itself.


S3를 버킷 + 키 + 버전으로 기본 데이터 맵으로 생각할 수 있다.

라고 언급한 바와 같이


orgKey기존의 버킷이름이 붙은 url을 제외한 복사하고 싶은 사진의 url이고 copyKey내가 붙여놓고 싶은 사진의 url이다.

이게 말이 어려운데


만약 우리가

https://palm-example-bucket.s3.ap-northeast-2.amazonaws.com/images/hamster.jpg

라는 이름의 S3 URL을 가지고 있고


위와 같은 URL을 가진 이미지를 복사하고 싶다 고 가정하자.

그렇다면 orgKeyimages/hamster.jpg 가 되고

copyKey 는 예상한 바와 같이 내가 넣고 싶은 이미지의 식별자가 된다.


나는 기존 이미지를 추가 할 경우엔 delete/에 넣어줬고, 이를 최종으로 넣을 경우에는

블로그 이름을 붙여서


이와 같이 만들어줬다.

자 복사는 되었다. 아마 이 글을 보고 이미지를 누르게 된다면

그러면 여러분은 이와 같은 에러를 마주할것이다.


4-2. 왜 Access가 불가할까?


분명히 여러분들은 S3 Bucket을 생성할때 유저가 접근할 수 있도록 접근 권한을 부여했을 것이다.

그렇지만 왜 복사한 객체는 같은 버킷의 S3임에도 접근할 수 없을까?


이와 관련하여 AWS에 들어가본다면,

Requirements for replication…

• Amazon S3 must have permissions to replicate objects from the source bucket to the destination bucket or buckets on your behalf. For more information about these permissions, see Setting up permissions. …


와 같이 확인할 수 있다.

즉, 복제는 내가 하는것이 아닌 Amazon S3가 하는 것이므로, 관련된 권한을 부여한다고 되어있다.


우리는 위 코드에서 접근 권한은 부여했지만, 코드에서 Access 허용 권한은 해주지 않았다.

copyObjectRequest.setCannedAccessControlList(CannedAccessControlList.PublicRead);

Copy를 하는 경우 접근 권한은 PublicRead로 설정하도록 해준다면,

해당 에러는 사라지고 사진의 접근이 가능해진다.

5. 수명주기


자 이제 사진은 복사했고, 이제 S3 관리를 시작해보자.

다시 AWS에 들어가서


S3에서 관리를 누르고 수명주기 규칙 생성을 눌러주자


수명 주기 규칙의 이름을 주고,

필터 처리를 하고 싶은 접두사를 작성해주자.

나는 폴더링을 삭제할 이미지는 delete/ 하위에 놓았기 때문에 이렇게 작성해줬다.


이후 나는 이 폴더의 객체가 생성된 후 7일이 지났을때, 객체가 삭제되도록 작성해줬다.

이렇게 처리한 후, 이제 7일 후에 S3에 들어가보면...


여러분은 폴더가 사라진 것을 확인할 수 있을 것이다.

5-1. 무시할 수 없는 가격


여기까지 읽는다면 한가지 생각이 들 수 있다.

생명주기에 값이 지나치게 많이 들지 않을까?

아마 따로 변환하지 않았으면 Storage Class는 모두 동일하게 Standard 등급일 것이다.


그리고 Standard는 수명주기 요청에 특별한 가격이 들지 않는다.

이렇게 우리는 주기적으로 필요없는 S3 객체의 저장도 막으면서 정말 사용하고 있는 사진만을관리할 수 있게 되었다.

6. 마치며


최대한 정확하게 전달하고자 했지만,

물론 제가 모르는 방법이나 사용하고 있는 방법이 적합하지 않을수도 있습니다.

피드백을 주신다면 감사히 받겠습니다.

Reference


AWS Simple Storage - https://docs.aws.amazon.com/ko_kr/s3/

최신 아티클
palms.blog 팀원 초대해서 팀블로그로 사용하기
김대덕
|
2024.06.05
palms.blog 팀원 초대해서 팀블로그로 사용하기
팀원 초대해서 팀블로그 만드는 방법과 각 팀원 권한에 대한 설명
Article Thumbnail
김대덕
|
2024.01.13
팜스프링팀에게 보내는 글 (23.07.02)
합숙이 시작되기도 전, 새벽 감성에 젖어 팀원들에게 보냈던 슬랙 메시지
Article Thumbnail
김서현
|
2024.01.09
장명지와 김서현의 10시간의 릴리즈 대장정
장명지와 김서현의 10시간 릴리즈 대장정에 대한 후기, 그리고 팀 팜스프링...