🔥 S3란 무엇인가: 오브젝트 스토리지의 구조

2099자
20분

16:9 가로 표지 일러스트레이션. 흰 배경. 평면 위에 작은 큐브 무리가 떠 있고, 각 큐브에 짧은 키 이름(avatar.png, 2026/04/log.json)이 적혀 있다. 큐브 무리 아래에 AWS 오렌지(#ff9900) S3 버킷 실루엣. 위쪽 흐릿한 회색 텍스트 99.999999999%. 옆쪽에 세 작은 비교 아이콘. 슬레이트 색 원기둥(Block), 에메랄드 폴더 트리(File), 오렌지 큐브 무리(Object). 좌상단 Amazon S3 다크 슬레이트 산세리프, 그 아래 Object Storage Service 작은 회색. 모던 플랫 에디토리얼 디자인.

지금까지 S3라는 이름이 어디서 처음 등장했는지 돌아보면, 정작 어느 글에서도 주인공으로 다룬 적이 없다. 다섯 섹션을 끌어오는 동안 S3는 매번 조연이었다. Lambda 트리거 종류에서 EventNotification 의 source 로, Logs: 구조화 로그와 인덱싱 관점에서 IA storage 의 가격 구조를 닮은 비교 대상으로, Synthetics: 엔드포인트 가용성 모니터링의 Canary 청구서 한 줄로, NAT Gateway: Private Subnet의 외부 연결에서는 Gateway Endpoint 무료 길의 종착지로 등장했다.

그런데 그 한 서비스가 무엇인지는 한 번도 들여다보지 않은 셈이다. 다섯 섹션 동안 partner 로만 보이던 것이 처음으로 주인공이 되는 글이다.

Object storage라는 한 단어

AWS S3 Developer Guide 의 첫 문장이 정의를 한 줄로 끝낸다.

Amazon Simple Storage Service (Amazon S3) is an object storage service that offers industry-leading scalability, data availability, security, and performance.

여기서 멈춰서 읽어야 하는 단어는 object storage service 한 묶음이다. 한국어로 바꾸면 객체 스토리지. 그런데 객체 스토리지가 무엇인지는 한 줄짜리 코드를 봐야 분명하다.

s3://my-app-uploads-2026/users/u-12345/avatar.png 이 키를 한눈에 보면 디렉토리 경로 같다. users/ 폴더 안에 u-12345/ 가 있고 그 안에 avatar.png 가 있는 구조처럼 머리에 한 번 그 형태를 잡는다. 그런데 S3에는 mkdir 도 없고, cd 도 없다. 슬래시 사이의 칸은 디렉토리가 아니라 키 한 줄 안의 문자다. ListObjects 호출에 prefix=users/u-12345/ 를 주면 그 문자로 시작하는 키들이 답으로 돌아와서 디렉토리처럼 느껴질 뿐이다.

처음 이 사실을 봤을 때 나는 한 번 멈췄다. 슬래시가 디렉토리가 아니라면, 그럼 폴더 이름을 바꾸려고 aws s3 mv 를 돌리면 무슨 일이 일어나는가? 답은 이렇다. 각 객체를 새 키로 CopyObject 한 다음 옛 키를 DeleteObject 한다. 1억 개 객체가 들어 있는 폴더를 옮기면 1억 번의 CopyObject 와 1억 번의 DeleteObject 가 발생한다. 디렉토리 추상이 깨지고 그제서야 평면 네임스페이스라는 단어가 무게를 얻었다.

버킷 my-app-uploads-2026users/u-12345/avatar.pngusers/u-67890/avatar.png2026/04/30/access.logbackups/db-2026-04-30.sql.gz키 한 줄 = 한 객체 (디렉토리 없음, 평면)파일시스템 트리users/├─ u-12345/└─ avatar.png└─ u-67890/ └─ avatar.pngS3에는 디렉토리가 없다
평면 네임스페이스. 슬래시는 디렉토리 구분자가 아니라 키 한 줄 안의 문자다.

세 단어로 끝나는 데이터 모델

공식 doc 이 객체 스토리지의 데이터 모델을 세 줄로 정의한다.

A bucket is a container for objects.
An object is a file and any metadata that describes the file.
An object key (or key name) is the unique identifier for an object within a bucket.

세 단어, 버킷·객체·키. 파일시스템 추상은 디렉토리·파일·inode·권한·시간·하드링크·심볼릭링크 일곱 갈래로 나뉘는 데 비해 S3는 세 갈래만 둔다.

이 단순함은 그냥 멋 부린 디자인이 아니라 운영 비용 절감과 직결한다는 점이 핵심이다. 버킷 하나, 키 하나로 객체에 접근한다. PUT 으로 올리고 GET 으로 받는다. 즉 파일시스템이 아니라 HTTP API다. 1억 개 객체가 같은 버킷 안에 평면으로 늘어서 있고, 키만 알면 바로 GET 한 번에 응답이 돌아온다.

여기서 한 가지 단서가 따라온다. 버킷 이름은 글로벌 unique 다. 공식 bucket naming rules 페이지가 이렇게 적는다.

General purpose buckets exist in a global namespace, which means that each bucket name must be unique across all AWS accounts in all the AWS Regions within a partition.

그래서 test-bucket 같은 이름은 S3 가 출시된 2006년 어느 해에 누가 가져가서 평생 다시 못 쓴다. 내가 S3를 처음 만질 때 aws s3 mb s3://my-test 를 쳤다가 그대로 BucketAlreadyExists 를 받았는데, 그 이유를 이 한 줄에서 알게 된다. 길이는 3에서 63자, 소문자 a-z, 숫자, 점, 하이픈만 받는 DNS 호환 이름이다. URL 안에 그대로 들어가야 하기 때문이다.

Block, File, Object를 같은 기준으로 비교하기

S3가 왜 파일시스템이 아닌지를 풀려면 다른 두 유형을 옆에 두고 봐야 한다. 같은 스토리지라는 우산 아래 AWS는 세 유형을 따로 판매한다. Block(EBS), File(EFS), Object(S3).

Block 은 인스턴스에 attach 되는 raw 디스크다. OS가 위에 파일시스템(ext4·xfs 같은)을 깔아야 비로소 파일이 된다. EBS vs Instance Store: 디스크는 어디 붙어 있는가 에서 본 구조 그대로, AZ 단위로 묶여 있어 다른 AZ 인스턴스에는 attach 되지 않는다.

File 은 NFSv4 같은 파일 공유 protocol 을 그대로 쓴다. 여러 인스턴스가 동시에 mount 해서 공유한다. POSIX 권한과 디렉토리 구조가 그대로 살아 있다.

Object 는 HTTP REST API다. 인스턴스에 mount 하지 않고, SDK 또는 HTTPS 호출로 다룬다. lifecycle 이 인스턴스와 완전히 분리되어 있어, EC2 한 대가 종료돼도 객체는 그대로 남는다.

Block (EBS)단위: 블록 (raw 디스크)접근: kernel mount공유: 1 인스턴스 (AZ 고정)lifecycle: 인스턴스에 묶임예: DB · OS bootio2 / gp3 / st1 / sc1File (EFS)단위: 파일 (POSIX)접근: NFSv4 mount공유: 다중 인스턴스lifecycle: 인스턴스 무관예: 공유 콘텐츠 · 워크스페이스Standard / IA / One ZoneObject (S3)단위: 객체 (데이터 + 메타)접근: HTTP API (PUT/GET)공유: 어디서나 (URL)lifecycle: EC2 와 완전 분리예: 업로드 · 백업 · 정적 자산Standard / IA / Glacier · Express
같은 스토리지라는 우산 아래 세 유형. 단위·접근·공유·lifecycle 네 줄에서 결정 기준을 나눈다.

세 유형의 차이를 한 시나리오로 풀어 두면 이렇게 된다. 한 회사가 사용자 업로드 이미지 1억 개를 운영한다고 해 보자. EBS 에 넣으면 인스턴스 한 대에 묶여서, 16TB io2 한 볼륨이 가득 차면 다음 볼륨으로 옮겨야 한다. 인스턴스 다운타임 동안 이미지가 GET 되지 않는다. EFS 에 넣으면 여러 인스턴스가 NFS 로 동시에 본다. 그런데 1억 개 작은 파일은 NFS metadata 서버에 부담이 된다. S3 에 넣으면 객체 하나당 키 하나, 인스턴스와 무관하게 HTTPS GET. 사용자 업로드와 백업과 정적 자산은 거의 항상 답이 S3로 향한다.

그럼 hot 데이터베이스 파일은 왜 EBS 인가? 데이터베이스 파일은 한 바이트를 자주 부분 update 해야 한다. S3 는 객체 단위로만 PUT 한다. 1KB 만 바꿔도 객체 전체를 다시 PUT 해야 한다. 한 객체가 GB 짜리이면 한 바이트 수정에 GB 짜리 PUT 이 발생한다는 뜻이다. 그래서 트랜잭션이 자주 일어나는 DB 파일에는 S3 가 답이 아니다.

11 9's: 확률을 시간으로 바꿔 읽기

S3 의 영구성을 한 문장으로 정의하는 곳은 Data Protection 페이지다.

Designed to provide 99.999999999% durability and 99.99% availability of objects over a given year.

99.999999999%. 9 가 11개. 11 9's. 한 객체가 1년 안에 손실될 확률이 10⁻¹¹ 이라는 뜻이다.

이 숫자가 어디서 오는가는 같은 페이지의 다음 줄이 짚는다.

S3 Standard, S3 Intelligent-Tiering, S3 Standard-IA, S3 Glacier Instant Retrieval, S3 Glacier Flexible Retrieval, and S3 Glacier Deep Archive redundantly store objects on multiple devices across a minimum of three Availability Zones in an AWS Region.

기본 storage class 들은 최소 3개 AZ 에 redundant 로 분산해 둔다. AZ 하나가 통째로 무너져도 나머지 둘에서 객체를 재구성한다.

그럼 11 9's 가 운영적으로 무슨 뜻인가? 천만 개 객체를 1년 동안 저장하면 기대 손실은 10⁷ × 10⁻¹¹ = 10⁻⁴ 개다. 1만 년에 1개. 회사 자산이 1조 개 객체라면 1년에 10¹² × 10⁻¹¹ = 10개. 36일에 1개씩 잃는 셈이다. 처음 이 환산을 봤을 때 나는 한 박자 멈췄다. 천만 개를 가지는 회사는 흔하지 않지만, 1조 개 객체를 굴리는 회사들은 분명히 있다. 11 9's 는 거대 데이터셋 운영자에게도 겸손한 보장임을 알았다.

가용성은 또 다른 숫자다. 같은 문장에서 99.99% availability 라고 따로 적었다. 한 해 동안 누적 약 53분 가량 GET 이 503 으로 끊길 수 있다는 설계 목표라는 뜻이다 (4 nines = 0.01% × 8,766시간 ≈ 0.876시간). 그 53분 동안에도 객체 자체는 사라지지 않는다. 영구성과 가용성은 다른 함수다. 잠깐 못 받아오는 일과 영영 사라지는 일은 다른 사건이라는 한 줄이 SLA 두 숫자를 따로 적게 만든다.

S3 SLA 페이지 가 그 두 숫자를 어떻게 환불 정책으로 풀었는지도 한 번 볼 만하다. Standard 의 경우 월 가용성이 99.9% 미만이면 10% 크레딧, 95% 미만이면 100% 크레딧이다 (SLA 환불 임계는 99.99% 설계값보다 9 한 개 느슨한 99.9%).

8가지 storage class 를 한 줄씩

Object Storage Classes 페이지 가 8가지를 모두 적는다. 자세한 결정 기준은 뒤이어 다루지만, 한 줄씩 미리 묶어 둔다.

  • S3 Standard. 기본값. ms 단위 응답. 자주 읽는 객체.
  • S3 Standard-IA. 한 달에 한 번 미만 접근. ms 응답. 3 AZ.
  • S3 One Zone-IA. 같은 구조, 단일 AZ. 더 싸지만 AZ 손실에 약하다.
  • S3 Intelligent-Tiering. 접근 패턴이 모를 때. 자동으로 단계 이동. 30·90·180일 후 cold tier.
  • S3 Glacier Instant Retrieval. 분기에 한 번. ms 응답. 90일 minimum.
  • S3 Glacier Flexible Retrieval. 연 한 번. 분~시간 retrieval. 90일 minimum.
  • S3 Glacier Deep Archive. 1년에 한 번 미만. 시간 단위 retrieval. 180일 minimum.
  • S3 Express One Zone. 단일 AZ, single-digit ms latency, hot transactional.

여덟 갈래 모두 11 9's durability 다. 차이는 가용성·retrieval 시간·가격 셋이다. 한 표 안에서 결정 기준이 정리되는 단계는 뒤이어 다룬다.

어디서 S3 가 답이 아닌가

지금까지 붙잡아 온 질문 중 하나가 “언제 이 서비스를 쓰지 말아야 하는가” 였다. S3 도 답이 아닌 곳이 분명하게 있다.

자주 부분 update 가 일어나는 데이터. 한 바이트만 바꾸려고 객체 전체를 다시 PUT 하는 건 hot DB 파일에는 비싸다. 답은 EBS gp3 / io2.

POSIX 파일 mount 가 필요한 레거시 앱. /data/files/ 형태로 파일을 읽는 코드가 있으면 EFS 가 답이다. S3 는 mount 되지 않는다 (s3fs-fuse 같은 wrapper 가 있긴 하지만 production 에 권하지 않는다).

매우 낮은 latency 가 필요한 hot 데이터. 단일 자릿수 ms 가 필요하면 EBS io2 또는 S3 Express One Zone (2023-11 re:Invent 출시) 이 그 갭을 메우러 들어왔다. 일반 Standard 는 수~수십 ms 응답이 기본이다.

그리고 partner 로 잘 어울리는 곳은 앞 다섯 섹션에서 본 그대로다. Lambda 호출 페이로드가 메시지 한도를 넘을 때 Claim check 패턴: 1MB 초과 페이로드의 lift-up으로 객체를 S3 에 잠깐 PUT 한 뒤 URL 만 메시지로 보냈고, Logs: 구조화 로그와 인덱싱 관점 의 IA class 가 같은 storage 가격 구조를 닮으려 했고, Load Balancer: ALB·NLB·GWLB의 역할 의 Health Check Logs (2025-11 출시) 가 통째로 S3 로 향할 수 있게 됐다. 앞 단계의 절반이 S3 위에서 돌아가고 있었다는 뜻이다.

그래서 영구 스토리지의 첫 형태

인스턴스 한 대를 끄면 EBS 볼륨도 그 인스턴스에 그대로 따라간다. 그 인스턴스가 다시 켜질 때까지 데이터에 닿을 수 없다. 인스턴스가 사라지면 (EBS 가 detach 된 상태로 남아 있더라도) 새 인스턴스에 attach 하기 전까지는 그대로 머문다.

S3 객체는 EC2 가 사라져도 그 위치에 그대로 남는다. URL 한 줄만 알면 어디서든 GET 한 번에 받아올 수 있다. 영구 스토리지의 첫 번째 형태는 거기서 시작한다. 인스턴스 lifecycle 을 떠나는 일.

뒤이어 버킷과 키, 평면 네임스페이스가 왜 평면인가, 그리고 큰 prefix 를 쓰면 무슨 일이 벌어지는가를 본다.

참고 자료

YouTube 영상

채널 보기
AI 추천 시스템의 원리, 벡터 사이의 각도와 코사인 유사도 | 선형대수학
스칼라 곱셈과 내적의 기하학적 의미 | 선형대수학
숫자 하나가 AI 모델의 운명을 바꾼다? | 선형대수학
벡터의 정의와 덧셈 연산 | 선형대수학
AI는 왜 수백 차원의 벡터를 사용할까? 고차원 공간과 행렬 | 선형대수학
트라이(Trie)에서 단어를 삭제하는 방법 | Trie 자료구조 이야기
마지막편, 트라이 노드를 50% 이상 줄이는 방법? 압축 트라이 성능 분석 | Trie 자료구조 이야기
트라이(Trie) 자료구조: 파이썬으로 삽입(Insert) 연산 구현하기 | Trie 자료구조 이야기