S3

Tue, 20 Aug 2024 04:32:47 GMT

Amazon S3는 객체(파일)를 버킷(폴더)에 담는 클라우드 저장소이다.

### 버킷

> Amazon S3의 UI는 폴더 구조처럼 보이겠지만 절대 폴더 구조가 아님을 명심하자!

`**버킷**`은 최상위 폴더라 생각하면 된다. 버킷의 이름은 유일해야 하고 (다른 사람들이랑도 겹치면 안됨), 아래 규칙을 만족해야 한다.

- 대문자, 언더바 안됨

- 3~63자 사이

- IP 안됨

- 소문자 혹은 숫자로 시작

### 객체

객체는 실제 내용을 담는다. 최대 용량은 5TB이지만 한 번에 5GB 이상 업로드할 수 없으므로 "multi-part upload"를 사용해야 한다.

- **키** - 객체의 전체 주소이다. 이때 유의해야 하는 게, S3에는 폴더의 개념이 없다. 그냥 `/`를 포함하는 엄청 긴 이름일 뿐라는 것을 명심해야 한다.

- **메타 데이터** - key-value pair로 되어 있는 추가 정보이다.

- **태그** - 최대 10개까지 설정할 수 있고 보안이나 생명 주기 관리에 유용하다.

- **버전 ID** - 버전 관리를 한다면 버전 ID도 쓰인다.

![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134025_N0SklJyBP5qoAQN5Zv?q=80&s=1280x180&t=outside&f=webp)

### 파티셔닝

S3는 prefix의 가장 첫 글자를 가지고 파티셔닝한다. 따라서 `chapter1`보다 `1chapter`를 사용하면 객체를 좀 더 골고루 분산시킬 수 있다. 혹은 ID 값 같이 1씩 증가하는 숫자의 경우 역순으로 배열하여 분산시킬 수 있다.

아니면 앞 몇 글자를 해싱할 수도 있다. 보통 많아야 2~3개를 사용하는데, 4자를 파티션으로 분할하면 총 65,536개의 경우의 수가 나오고 이만큼 파티션을 만들면 초당 수백만 건의 요청을 처리하기 때문에 불필요하다.

### 버전 관리

S3는 버전 관리 기능을 지원한다. 버킷 단위로 활성화/비활성화 할 수 있다. 파일이 들어왔을 때, 같은 키를 가진 파일이 있다면 버전은 1이 올라가고 덮어씌워 진다. 물론 버전별로 다 복구가 가능하다. 처음부터 버전 관리 기능을 활성하지 않으면 버전은 null이 된다. 중간에 비활성화하면 이전 버전은 유지하되 이후 파일들은 버전을 매기지 않는다.

- 동시에 한 파일에 여러 업데이트가 들어오면, 최종 타임 스탬프를 지닌 요청만 따른다.

### 암호화

Amazon은 S3 객체를 암호화하기 위한 방법으로 4가지를 제공한다.

- **SSE-S3**: Amazon S3가 제공하는 key로 암호화한다. 서버 단에서 AES-256 방식으로 암호화한다. 클라이언트는 헤더에 `"x-amz-server-side-encryption": "AES256"`을 포함해 객체를 업로드해야 한다.

- **SSE-KMS**: 키 관리 서비스에서 관리하는 key로 암호화한다. 서버단에서 동작하고, 누가 언제 접근했는지 기록이 남는다. 헤더에 `"x-amz-server-side-encryption": "aws:kms"`

- **SSE-C:** 고객에 제공하는 키로 암호화한다. S3는 키를 저장하지 않고 고객이 HTTPS로 계속 제공해야 한다.

- **Client Side Encryption** - 클라이언트에서 암호화해서 S3로 보낸다. Amazon S3 Encryption Client라는 라이브러리를 주로 쓰며, 키와 암호 주기를 고객이 관리해야 한다.

### 보안

유저가 버킷이나 객체에 접근할 때 아래 두 가지 방법 중 하나로 허용할 수 있다. 다만 둘 중 하나가 유저를 차단할 때는 접근할 수 없다.

- **유저 기반** - IAM 정책이 허용

- **리소스 기반** - 버킷 콘솔에서 계정을 허용할 때

공개 접근을 허용/차단할 수도 있다. 최대한 S3를 프로아빗으로 놔두고 다른 방식으로 접근해야 한다.

- **네트워크** - VPC 엔드포인트를 지원한다.

- **로그, 감사** - S3 접근 로그는 다른 S3 버킷에 저장되고, API 요청은 CloudTrail에 저장할 수 있다.

- **유저 보안** - 객체를 지울 때 MFA를 요구하거나, 제한 시간 동안만 접근이 가능한 URL를 제공할 수도 있다.

### CORS

origin은 스키마(프로토콜)과 호스트(도메인)과 포트이다. CORS는 아래 그림처럼 다른 서버의 지시를 받아서 온 요청들을 허용할 지 설정하는 것이다. Cross Origin에 CORS를 걸지 말지 결정하는 것이다.

![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134026_3BwFDT1PgtAKps5Q7A?q=80&s=1280x180&t=outside&f=webp)

### MFA Delete

S3에서 버전 관리를 할 때, 영구 삭제나 버전 관리 중단 등의 결정을 할 때 추가 인증을 한다. 버킷 소유자(루트 계정)만이 MFA Delete를 활성/비활성화 할 수 있고 CLI를 통해서만 가능하다.

### S3 암호화

암호화를 강제하는 방법에는 2가지가 있다.

- default encryption 설정

- Bucket Policy를 설정해, 암호화되지 않은 헤더로 객체를 PUT하는 API 요청을 거절(Deny)한다.

버킷 정책에서 명시한 암호화 정책이 우선되며 명시하지 않았다면 default encrytion의 정책을 따른다.

### 접근 로그

감사를 목적으로 S3에 접근하는 로그를 남기고 나중에 분석하고 싶다. 로깅 버킷을 만들고 메인 버킷의 로그를 거기에 저장하면 된다. 주의해야 할게 절대 우리가 모니터링하는 버킷과 로그 버킷을 하나로 합쳐서는 안된다!! 재귀가 발생해 버킷이 무한정 증식할 것이다.

![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134026_f9PZaz9XeSUjhS03bJ?q=80&s=1280x180&t=outside&f=webp)

### S3 복제 (CRR & SRR)

S3를 복제하려면 무조건 버전 관리 기능이 활성화 되어 있어야 한다. 비동기로 복사되며 메타데이터가 유지된다. 또한 복사된 버킷에 적절한 IAM 권한을 할당해야 한다. 복사 방식에는 두 가지가 있는데,

- Cross Region Replication (CRR) - 지연 시간 줄이기, 규정 준수

- Same Region Replication (SRR) - 로그 모으기, 테스트/개발 계정 간의 복제

복제가 활성화되면, 이후 새로 들어오는 객체에 대해서만 복제가 수행된다. 이전의 자료들은 복제하지 않는다. "제거" 명령의 경우, 먼저 delete marker를 복사할지 말지는 설정할 수 있다. 그리고 버전 ID로 삭제할 때는 악의적인 삭제를 방지하기 위해 복제되지 않는다.

복제의 "Chaining"은 지원하지 않는다. 버킷 1을 버킷2가 복제하고, 버킷2를 버킷3이 복제한다고 가정하자. 이때 버킷 1에 새 객체가 만들어지면 버킷 2에는 복제가 된지만, 버킷 3까지는 복제가 안된다. 복제 활성화는 원본 버킷에서 설정해야 한다!!

### Pre-signed URL

SDK나 CLI를 통해 미리 서명된 URL를 생성해 비공개 버킷에 접근할 수 있다. 이 URL은 기본적으로 3600초까지 유지되며 그 이후에는 동작하지 않는다. 유저는 이 URL을 통해 읽고 쓰는 권한을 할당해 줄 수 있다. 미리 서명된 URL은 임시 접근이 필요할 때나, 유튜브 프리미엄처럼 특정 계정만 볼 수 있는 영상을 제공할 때 등 자주 쓰인다.

```
aws s3 presign s3://mybucket/myobject --region my-region --expires-in 300
aws configure set default.s3.signature_version s3v4 # 만약 오류가 생기면 실행
```

### 스토리지 클래스

- **S3 Standard - General Purpose**: 여러 AZ에 저장하고 복원률, 가용성 등이 준수하다.

- **S3 Standard - Infrequent Access (IA)**: 평소에는 접근 안하다가 갑자기 접근 많이 하는 상황에 적합하다

- **S3 One Zone - Infrequent Access (IA)**: IA 똑같지만 하나의 AZ에 저장된다. AZ가 부서지면 데이터는 날아가지만 지연 시간이 낮고 쓰루풋이 높다. 또한 IA보다 싸다

- **Intelligent tiering**: 패턴을 분석해 성능/가격이 가장 적절한 티어로 자동으로 옮긴다. 모니터링과 티어를 옮기는 비용은 있지만, 검색 비용은 없다.

- **Amazon Glacier**: 10년씩 장기 보관되는 데이터를 위하며, 자기 테이프에 저장되기 때문에 내구도가 높다. 각각의 아이템을 Archive라 부르고, Archive는 Vaults에 저장된다. Glacier는 저장 기간에 따라 Glacier와 Glacier Deep Archive로 나뉜다.

**Glacier**는 3가지 retrieval(검색) 조건이 있는데, 조건별로 각 시간만 파일들을 볼 수 있다. 그 외에는 저장은 되어 있지만 볼 수 없다.

- 신속(expedited, 1~5분)

- 표준(standard, 3~5시간)

- 거대(bulk, 5~12시간)

- 최소 90일 이상 보관해야 함

**Glacier Deep Archive**는 더 길게 보관하는 스토리지이다. 검색을 하기 위해서는 아래와 같은 시간이 필요하다.

- 표준 (12시간)

- 거대 (48시간)

- 최소 180일 이상 보관해야 함

![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134027_JJFYgC6WJZjKugM98h?q=80&s=1280x180&t=outside&f=webp)

![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134028_cmq11RldUL8022PsOP?q=80&s=1280x180&t=outside&f=webp)

### 수명주기 규칙

- 전환 작업: "며칠 뒤 이 파일을 Standard IA 클래스로 옮겨라"

- 만료 작업: "며칠 뒤 이 파일을 지워라"

특정 태그를 기준으로, 특정 접두사(폴더 느낌)를 기준으로 규칙을 정할 수 있다.

### 분석

Standard와 standard_IA에서만 동작하며, 언제 전환 작업을 해야 하는지 결정하는 것을 도와준다. 매일 업데이트되고 24/48시간 후에 시작하게 할 수 있다.

### 성능

S3는 적어도 접두사별로 시간당 3500 PUT/COPY/POST/DELETE 요청, 5500 GET/HEAD 요청 의 성능을 보인다.

만약 암호화 방법으로 SSE-KMS를 쓴다면 성능에 제약이 생길 수 있다. 업로드할 때는 GenerateDataKey KMS API를 호출하고 다운받을 때는 Decrypt KMS API를 호출하는데, 이 호출이 성능에 꽤 크게 제약을 가한다.

그럼 어떻게

- **Multi-Part upload**: 여러 파일로 나눠 올리면 병렬 처리 능력을 최대한으로 쓸 수 있기 때문에 실실적인 대역폭이 늘어난다.

- **Transfer Acceleration**: 엣지 로케이션(아마존 자체 네트워크)를 사용해 업로드한다.

아니면 파일의 특정 바이트 범위만 요청할 수도 있다. GET 요청밖에 적용할 수 없지만, 딱 그 범위만 가져오기 때문에 굉장히 효율적이다.

### S3 Select & Glacier Select

S3에 파일들을 요청할 때, SQL로 특정 파일만 가져오도록 필터를 걸어 네트워크 트래픽을 줄인다. 서버-사이드에서 연산을 하기 때문에 또 굉장히 빠르다. S3는 필터를 거쳐 만들어진 csv 파일을 유저에게 보낸다. 다만 정말 간단한 문법만 지원한다.

### 이벤트 알림

S3에 특정 이벤트가 발생했을 때, 이벤트를 다른 서비스로 보낼 수 있다. 다만, 버전 관리를 활성화해야 한다.

### 요청자 지불

원래는 그림처럼 버킷 주인이 저장 비용과 네트워크 비용을 모두 지불했다. 하지만 '요청자 지불'을 활성화하면 요청하는 사람이 비용을 지불한다. 단 요청자는 AWS가 결제 수단을 인지하고 있어야 한다.

![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134028_lNbHKVkK3iixRaaoN7?q=80&s=1280x180&t=outside&f=webp)

### Amazon Athena

S3 객체를 분석하기 위한 서비리스 쿼리이다. 기본 SQL 문법을 사용하고 CSV, JSON, ORG, Avro, Parquet 형식으로 반환한다. 테라바이트당으로 계산하기 때문에 데이터를 최대한 압축하는 것이 좋다.

### Glacier Vault Lock

WORM(Write Once Read Many)일 때 적합하고, 규정 준수와 데이터 보유를 위해 편집을 막는다. S3는 버전을 지우는 걸 특정 기간 동안 혹은 영원히 막을 수 있다. 또 특정 권한 (governance mode)을 가진 사람만 지울 수 있거나 아무도 (compliance mode)지울 수 없도록 만들 수 있다.