AWS 스토리지 완벽 가이드 🗄️¶
중학생도 이해할 수 있는 AWS 스토리지 설명서
📚 목차¶
1. 스토리지란 무엇인가요?¶
🎯 쉽게 이해하기¶
스토리지는 디지털 창고라고 생각하면 됩니다. 집에 물건을 보관하는 방법이 여러 가지인 것처럼, 클라우드에서도 데이터를 저장하는 방법이 여러 가지예요.
graph TB
A[클라우드 스토리지] --> B[블록 스토리지]
A --> C[파일 스토리지]
A --> D[객체 스토리지]
B --> B1["하드디스크처럼<br/>빠르고 직접 연결"]
B --> B2["예: EBS"]
C --> C1["폴더처럼<br/>여러 사람이 공유"]
C --> C2["예: EFS, FSx"]
D --> D1["사진첩처럼<br/>많은 파일 보관"]
D --> D2["예: S3"]
style A fill:#ff9999
style B fill:#99ccff
style C fill:#99ff99
style D fill:#ffcc99
📝 스토리지 유형 비교¶
| 유형 | 실생활 비유 | AWS 서비스 | 언제 사용? |
|---|---|---|---|
| 블록 스토리지 | 컴퓨터 하드디스크 | EBS | 프로그램이 빠르게 읽고 쓸 때 |
| 파일 스토리지 | 공유 폴더 (NAS) | EFS, FSx | 여러 컴퓨터가 같이 쓸 때 |
| 객체 스토리지 | 사진 앨범, 창고 | S3 | 많은 파일을 오래 보관할 때 |
2. 객체 스토리지 - Amazon S3¶
🎨 S3는 무엇인가요?¶
S3 = Simple Storage Service (간단한 저장소 서비스)
사진, 동영상, 문서 등을 무제한으로 저장할 수 있는 인터넷 창고예요!
graph LR
A[사용자] -->|파일 업로드| B[S3 버킷]
B -->|저장| C[객체 1]
B -->|저장| D[객체 2]
B -->|저장| E[객체 3]
C -.->|메타데이터| C1[파일명: photo.jpg<br/>크기: 2MB<br/>날짜: 2025-10-15]
style B fill:#ff9900
style C fill:#ffcc99
style D fill:#ffcc99
style E fill:#ffcc99
🏗️ S3의 핵심 구성요소¶
graph TD
A[S3 전체 시스템] --> B[버킷 Bucket]
B --> C[객체 Object]
C --> D[키 Key]
C --> E[값 Value]
C --> F[메타데이터]
B -.->|예시| B1["my-photo-bucket<br/>(전 세계에서 유일한 이름)"]
D -.->|예시| D1["2025/photos/vacation.jpg<br/>(파일 경로)"]
E -.->|예시| E1["실제 사진 파일 데이터"]
F -.->|예시| F1["파일 크기, 업로드 날짜<br/>사용자 정의 태그"]
style A fill:#ff6666
style B fill:#ff9999
style C fill:#ffcccc
실제 코드로 이해하기¶
# Python으로 S3에 파일 업로드하기
import boto3
# S3 연결 준비 (AWS와 연결하는 도구)
s3 = boto3.client('s3')
# 파일 업로드
s3.upload_file(
'my_photo.jpg', # 내 컴퓨터의 파일
'my-photo-bucket', # S3 버킷 이름 (창고 이름)
'2025/photos/vacation.jpg' # S3에 저장될 경로 (Key)
)
# ✅ 이렇게 하면 파일이 클라우드에 저장됩니다!
💰 S3 스토리지 클래스 (저장 방법 선택하기)¶
비유: 집에 물건을 보관할 때도 방법이 달라요
- 자주 쓰는 물건 → 책상 위 (빠르지만 공간 차지)
- 가끔 쓰는 물건 → 서랍 (중간)
- 거의 안 쓰는 물건 → 창고 (느리지만 저렴)
graph TB
A[S3 스토리지 클래스] --> B[Standard<br/>표준]
A --> C[Standard-IA<br/>자주 안씀]
A --> D[One Zone-IA<br/>한 곳에만]
A --> E[Glacier<br/>아카이브]
A --> F[Intelligent-Tiering<br/>자동 관리]
B -.->|특징| B1["💸 비용: 높음<br/>⚡ 속도: 빠름<br/>📊 사용: 매일"]
C -.->|특징| C1["💸 비용: 중간<br/>⚡ 속도: 빠름<br/>📊 사용: 월 1-2회"]
D -.->|특징| D1["💸 비용: 저렴<br/>⚡ 속도: 빠름<br/>⚠️ 위험: 한 곳만 저장"]
E -.->|특징| E1["💸 비용: 매우 저렴<br/>⏰ 속도: 느림<br/>📦 사용: 거의 안봄"]
F -.->|특징| F1["🤖 자동으로<br/>적절한 곳으로 이동"]
style B fill:#ff6666
style C fill:#ff9999
style D fill:#ffcc99
style E fill:#99ccff
style F fill:#99ff99
📊 스토리지 클래스 상세 비교¶
| 클래스 | 월 비용 (1GB 기준) | 꺼내는 시간 | 언제 사용? | 실생활 예시 |
|---|---|---|---|---|
| Standard | $0.023 | 즉시 | 매일 보는 파일 | 웹사이트 이미지 |
| Standard-IA | $0.0125 | 즉시 | 가끔 보는 파일 | 월별 보고서 |
| One Zone-IA | $0.01 | 즉시 | 다시 만들 수 있는 파일 | 임시 백업 |
| Glacier Instant | $0.004 | 즉시 | 자주는 아니지만 급할 수 있음 | 분기별 자료 |
| Glacier Flexible | $0.0036 | 1분~5시간 | 거의 안 봄 | 오래된 로그 |
| Glacier Deep Archive | $0.00099 | 12시간 | 법적 보관용 | 7년치 세금 자료 |
💡 현업 팁: 어떤 클래스를 선택해야 할까?¶
# 실제 현업에서 사용하는 수명주기 정책 예시
lifecycle_policy = {
"Rules": [
{
"Id": "자동 비용 절감 규칙",
"Status": "Enabled",
"Transitions": [
{
# 30일 후: 자주 안 쓰는 저장소로 이동
"Days": 30,
"StorageClass": "STANDARD_IA"
},
{
# 90일 후: 아카이브로 이동
"Days": 90,
"StorageClass": "GLACIER"
}
],
"Expiration": {
# 365일 후: 삭제
"Days": 365
}
}
]
}
# ✅ 이렇게 설정하면 자동으로 비용이 절감됩니다!
# 30일 지난 파일: 50% 절약
# 90일 지난 파일: 84% 절약
🔄 버전 관리 (Versioning)¶
비유: 워드 문서의 "변경 내용 추적" 기능과 같아요!
sequenceDiagram
participant User as 사용자
participant S3 as S3 버킷
User->>S3: report.pdf 업로드 (버전 1)
Note over S3: Version ID: abc123
User->>S3: report.pdf 수정 후 업로드 (버전 2)
Note over S3: Version ID: def456<br/>⚠️ 버전 1은 그대로 유지!
User->>S3: report.pdf 삭제
Note over S3: Delete Marker 생성<br/>⚠️ 실제로는 삭제 안됨!
User->>S3: 버전 1 복구 요청
S3-->>User: report.pdf (버전 1) 복원
코드로 버전 관리 활용하기¶
import boto3
s3 = boto3.client('s3')
# 1️⃣ 버전 관리 활성화
s3.put_bucket_versioning(
Bucket='my-bucket',
VersioningConfiguration={'Status': 'Enabled'}
)
# 2️⃣ 특정 버전 가져오기
response = s3.get_object(
Bucket='my-bucket',
Key='report.pdf',
VersionId='abc123' # 이전 버전 ID
)
# 3️⃣ 모든 버전 목록 보기
versions = s3.list_object_versions(
Bucket='my-bucket',
Prefix='report.pdf'
)
# ✅ 실수로 삭제해도 복구 가능!
🔐 S3 보안 및 권한 관리¶
mermaid
graph TD
A[S3 보안 계층] --> B[IAM 정책]
A --> C[버킷 정책]
A --> D[ACL]
A --> E[암호화]
B -.->|누가| B1["특정 사용자/역할만<br/>접근 가능"]
C -.->|무엇을| C1["버킷 전체 또는<br/>특정 폴더만 공개"]
D -.->|개별| D1["파일 하나하나<br/>권한 설정"]
E -.->|보호| E1["저장/전송 시<br/>암호화"]
style A fill:#ff6666
style B fill:#99ccff
style C fill:#99ff99
style D fill:#ffcc99
style E fill:#ff9999
실전 보안 설정 예시¶
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "웹사이트 이미지 공개",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-website-bucket/images/*"
},
{
"Sid": "관리자만 업로드 가능",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/admin"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-website-bucket/*"
}
]
}
설명:
- 첫 번째 규칙: 누구나 images 폴더의 사진을 볼 수 있음
- 두 번째 규칙: admin 사용자만 파일을 올릴 수 있음
🚀 S3 고급 기능¶
1. 정적 웹사이트 호스팅¶
graph LR
A[웹 브라우저] -->|http 요청| B[S3 버킷]
B -->|HTML 전송| A
B --> C[index.html]
B --> D[style.css]
B --> E[images/]
style B fill:#ff9900
<!-- index.html 예시 -->
<!DOCTYPE html>
<html>
<head>
<title>내 첫 S3 웹사이트</title>
</head>
<body>
<h1>안녕하세요! 👋</h1>
<p>이 페이지는 S3에서 호스팅됩니다.</p>
<img src="images/photo.jpg" alt="사진">
</body>
</html>
<!--
✅ 이 파일을 S3에 업로드하고
"정적 웹사이트 호스팅"을 활성화하면
웹사이트가 완성됩니다!
-->
2. 이벤트 알림¶
sequenceDiagram
participant User as 사용자
participant S3 as S3 버킷
participant Lambda as Lambda 함수
participant SNS as 이메일 알림
User->>S3: 사진 업로드
S3->>Lambda: 이벤트 발생!
Lambda->>Lambda: 썸네일 생성
Lambda->>S3: 썸네일 저장
Lambda->>SNS: 완료 알림
SNS->>User: 📧 이메일 전송
# Lambda 함수 예시 (자동 썸네일 생성)
import boto3
from PIL import Image
import io
def lambda_handler(event, context):
# S3에서 업로드된 파일 정보 가져오기
bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
# 원본 이미지 다운로드
s3 = boto3.client('s3')
response = s3.get_object(Bucket=bucket, Key=key)
image = Image.open(response['Body'])
# 썸네일 생성 (200x200 크기로)
image.thumbnail((200, 200))
# 썸네일 저장
buffer = io.BytesIO()
image.save(buffer, 'JPEG')
buffer.seek(0)
# S3에 썸네일 업로드
thumbnail_key = f"thumbnails/{key}"
s3.put_object(
Bucket=bucket,
Key=thumbnail_key,
Body=buffer,
ContentType='image/jpeg'
)
# ✅ 사진 업로드하면 자동으로 썸네일이 생성됩니다!
return {'statusCode': 200}
3. 파일 스토리지 - EFS & FSx¶
📁 EFS (Elastic File System)¶
비유: 학교 공유 폴더처럼 여러 컴퓨터가 동시에 같은 폴더를 사용할 수 있어요!
graph TD
A[EFS 파일 시스템] --> B[EC2 인스턴스 1]
A --> C[EC2 인스턴스 2]
A --> D[EC2 인스턴스 3]
B -.->|동시에| E["/shared/data"]
C -.->|접근| E
D -.->|가능| E
E --> F[파일1.txt]
E --> G[파일2.jpg]
E --> H[폴더/]
style A fill:#99ff99
style B fill:#99ccff
style C fill:#99ccff
style D fill:#99ccff
EFS 사용 예시¶
# EC2 인스턴스에 EFS 마운트하기
# 1️⃣ 필요한 도구 설치
sudo yum install -y amazon-efs-utils
# 2️⃣ 마운트 포인트 생성
sudo mkdir /mnt/efs
# 3️⃣ EFS 연결
sudo mount -t efs fs-12345678:/ /mnt/efs
# 4️⃣ 이제 /mnt/efs 폴더를 여러 서버가 공유합니다!
cd /mnt/efs
echo "안녕하세요" > shared_file.txt
# ✅ 다른 EC2에서도 이 파일을 볼 수 있어요!
🏢 FSx (다양한 파일 시스템)¶
graph TB
A[FSx 패밀리] --> B[FSx for Windows]
A --> C[FSx for Lustre]
A --> D[FSx for NetApp ONTAP]
A --> E[FSx for OpenZFS]
B -.->|용도| B1["Windows 서버<br/>파일 공유<br/>Active Directory"]
C -.->|용도| C1["머신러닝<br/>고성능 컴퓨팅<br/>대용량 분석"]
D -.->|용도| D1["기업용 NAS<br/>하이브리드 클라우드<br/>SAP, Oracle"]
E -.->|용도| E1["Linux/Unix<br/>DevOps<br/>스냅샷 관리"]
style A fill:#ff6666
style B fill:#99ccff
style C fill:#99ff99
style D fill:#ffcc99
style E fill:#ff9999
📊 EFS vs FSx vs EBS vs S3 비교¶
graph TB
A[저장소 선택 가이드] --> B{여러 서버가<br/>동시 접근?}
B -->|Yes| C{어떤 OS?}
B -->|No| D{무엇을 저장?}
C -->|Linux| E[EFS 추천]
C -->|Windows| F[FSx for Windows]
C -->|고성능 필요| G[FSx for Lustre]
D -->|디스크<br/>데이터베이스| H[EBS 추천]
D -->|파일<br/>백업| I[S3 추천]
style E fill:#99ff99
style F fill:#99ccff
style G fill:#ff9999
style H fill:#ffcc99
style I fill:#ff9900
| 기준 | EBS | EFS | FSx | S3 |
|---|---|---|---|---|
| 연결 방식 | 1:1 (한 서버만) | N:N (여러 서버) | N:N (여러 서버) | HTTP/API |
| 사용 예 | 데이터베이스 | 웹서버 공유 | Windows 공유 | 백업, 이미지 |
| 확장성 | 수동 | 자동 | 수동 | 무제한 |
| 비용 | 중간 | 높음 | 높음 | 저렴 |
| 속도 | 매우 빠름 | 빠름 | 매우 빠름 | 보통 |
4. 데이터 마이그레이션 도구¶
🚚 데이터를 클라우드로 옮기는 방법¶
graph TD
A[온프레미스<br/>데이터센터] --> B{데이터 크기}
B -->|작음<br/>1TB 이하| C[인터넷 직접 전송]
B -->|중간<br/>1TB~50TB| D[AWS DataSync]
B -->|큼<br/>50TB~PB| E[AWS Snowball]
B -->|초대형<br/>EB급| F[AWS Snowmobile]
C --> G[S3, EFS로 업로드]
D --> G
E --> H[물리적 장비 배송]
F --> H
style A fill:#ff6666
style C fill:#99ff99
style D fill:#99ccff
style E fill:#ffcc99
style F fill:#ff9999
🌉 Storage Gateway (하이브리드 스토리지)¶
비유: 집과 사무실을 연결하는 다리 같은 역할!
graph LR
A[온프레미스<br/>데이터센터] -->|네트워크| B[Storage Gateway]
B -->|암호화 전송| C[AWS 클라우드]
B --> B1[File Gateway]
B --> B2[Volume Gateway]
B --> B3[Tape Gateway]
B1 -.->|NFS/SMB| D[S3 버킷]
B2 -.->|iSCSI| E[EBS 스냅샷]
B3 -.->|가상 테이프| F[S3 Glacier]
style A fill:#ff9999
style B fill:#99ccff
style C fill:#99ff99
Storage Gateway 사용 예시¶
# File Gateway 설정 (Python SDK)
import boto3
# Storage Gateway 클라이언트 생성
sg = boto3.client('storagegateway')
# File Gateway 생성
response = sg.create_nfs_file_share(
GatewayARN='arn:aws:storagegateway:...',
LocationARN='arn:aws:s3:::my-backup-bucket',
Role='arn:aws:iam::...:role/StorageGatewayRole',
ClientList=['0.0.0.0/0'], # 접근 허용 IP
DefaultStorageClass='S3_STANDARD_IA' # 저장 클래스
)
# ✅ 이제 온프레미스에서 S3를 로컬 폴더처럼 사용 가능!
⚡ AWS DataSync (고속 데이터 전송)¶
sequenceDiagram
participant On as 온프레미스<br/>NFS 서버
participant Agent as DataSync<br/>에이전트
participant AWS as AWS<br/>S3/EFS
On->>Agent: 1. 파일 스캔
Agent->>Agent: 2. 변경된 파일만 선택
Agent->>AWS: 3. 암호화 전송 (10배 빠름)
AWS->>AWS: 4. 무결성 검증
AWS-->>Agent: 5. 완료 알림
Agent-->>On: 6. 동기화 완료
DataSync 설정 예시¶
# DataSync 작업 생성
import boto3
datasync = boto3.client('datasync')
# 소스 위치 (온프레미스 NFS)
source_location = datasync.create_location_nfs(
ServerHostname='192.168.1.100',
Subdirectory='/data',
OnPremConfig={
'AgentArns': ['arn:aws:datasync:...:agent/...']
}
)
# 대상 위치 (S3)
destination_location = datasync.create_location_s3(
S3BucketArn='arn:aws:s3:::my-bucket',
Subdirectory='/backup'
)
# 동기화 작업 생성
task = datasync.create_task(
SourceLocationArn=source_location['LocationArn'],
DestinationLocationArn=destination_location['LocationArn'],
Schedule={
'ScheduleExpression': 'cron(0 2 * * ? *)' # 매일 새벽 2시
}
)
# ✅ 매일 밤 자동으로 백업됩니다!
📦 AWS Snow 패밀리 (물리적 데이터 전송)¶
graph TB
A[Snow 패밀리] --> B[Snowcone<br/>8TB]
A --> C[Snowball Edge<br/>80TB]
A --> D[Snowmobile<br/>100PB]
B -.->|크기| B1["노트북만한 크기<br/>휴대 가능<br/>드론, IoT용"]
C -.->|크기| C1["여행가방 크기<br/>트럭 배송<br/>데이터센터용"]
D -.->|크기| D1["트럭 통째로<br/>엑사바이트급<br/>초대형 마이그레이션"]
style B fill:#99ff99
style C fill:#99ccff
style D fill:#ff9999
Snow 사용 시나리오¶
예시: 100TB의 영상 파일을 AWS로 옮기기
# ❌ 인터넷으로 전송 시
속도 = 100 Mbps # 일반적인 기업 인터넷
용량 = 100 TB = 100,000 GB = 800,000,000 Mb
시간 = 800,000,000 / 100 = 8,000,000초 = 92일 🐌
# ✅ Snowball 사용 시
배송 = 2일
복사 = 1일 (로컬 고속 네트워크)
반송 = 2일
총 시간 = 5일 🚀
# 💰 비용 비교
인터넷_전송비 = 약 $9,000 (S3 전송 요금)
Snowball_비용 = 약 $300 (10일 대여)
5. 현업 활용 가이드¶
🏆 가장 많이 사용하는 서비스 TOP 3¶
pie title 현업에서 가장 많이 사용하는 AWS 스토리지
"S3" : 50
"EBS" : 30
"EFS" : 15
"기타" : 5
📱 실전 사용 사례¶
1️⃣ 스타트업 웹 서비스¶
graph LR
A[사용자] -->|웹 접속| B[CloudFront CDN]
B --> C[S3<br/>정적 콘텐츠]
B --> D[EC2<br/>웹 서버]
D --> E[RDS<br/>데이터베이스]
D --> F[S3<br/>사용자 업로드]
style C fill:#ff9900
style F fill:#ff9900
사용 서비스:
- S3: 이미지, CSS, JS 파일 저장
- CloudFront: 전 세계 빠른 전송
- EBS: 데이터베이스용 디스크
# 사용자 프로필 사진 업로드 처리
def upload_profile_picture(user_id, file):
s3 = boto3.client('s3')
# 파일명 생성 (중복 방지)
filename = f"profiles/{user_id}/{uuid.uuid4()}.jpg"
# S3에 업로드
s3.upload_fileobj(
file,
'my-app-bucket', filename, ExtraArgs={ 'ContentType': 'image/jpeg', 'CacheControl': 'max-age=31536000', # 1년 캐싱 'ACL': 'public-read' # 공개 읽기 } )
# CloudFront URL 생성
url = f"https://cdn.myapp.com/{filename}"
# ✅ 사용자에게 URL 반환
return url
2️⃣ 미디어 & 엔터테인먼트¶
graph TB
A[원본 영상<br/>업로드] --> B[S3<br/>Standard]
B --> C[Lambda<br/>트리거]
C --> D[MediaConvert<br/>인코딩]
D --> E[S3<br/>Standard]
D --> F[S3<br/>Glacier]
E --> G[CloudFront<br/>스트리밍]
style B fill:#ff9900
style E fill:#ff9900
style F fill:#99ccff
워크플로우: 1. 고화질 원본 → S3 Standard 2. 자동 인코딩 (여러 해상도 생성) 3. 스트리밍용 → S3 Standard 4. 원본 백업 → S3 Glacier (저렴한 장기 보관)
# 영상 업로드 후 자동 처리
def process_video(event, context):
# S3 이벤트에서 파일 정보 가져오기
bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
# MediaConvert 작업 생성
mediaconvert = boto3.client('mediaconvert')
job = mediaconvert.create_job(
Role='arn:aws:iam::...:role/MediaConvertRole',
Settings={
'Inputs': [{
'FileInput': f's3://{bucket}/{key}'
}],
'OutputGroups': [
{
'Name': 'HLS 스트리밍',
'OutputGroupSettings': {
'Type': 'HLS_GROUP_SETTINGS',
'Destination': f's3://{bucket}/streaming/'
},
'Outputs': [
{'VideoDescription': {'Width': 1920, 'Height': 1080}}, # Full HD
{'VideoDescription': {'Width': 1280, 'Height': 720}}, # HD
{'VideoDescription': {'Width': 640, 'Height': 360}} # SD
]
}
]
}
)
# 원본은 30일 후 Glacier로 이동 (수명주기 정책)
# ✅ 자동으로 3가지 화질 생성!
3️⃣ 빅데이터 & 분석¶
graph LR
A[IoT 센서] -->|실시간| B[Kinesis]
B --> C[Lambda]
C --> D[S3 Data Lake]
E[웹 로그] --> D
F[데이터베이스<br/>백업] --> D
D --> G[Athena<br/>SQL 쿼리]
D --> H[Glue<br/>ETL]
H --> I[Redshift<br/>데이터 웨어하우스]
style D fill:#ff9900
데이터 레이크 구조:
s3://my-datalake/
├── raw/ # 원본 데이터
│ ├── 2025/10/15/
│ └── 2025/10/16/
├── processed/ # 처리된 데이터
│ └── parquet/
└── archive/ # 아카이브 (Glacier)
└── 2024/
# 데이터 레이크 쿼리 (Athena)
import boto3
athena = boto3.client('athena')
# SQL 쿼리 실행
response = athena.start_query_execution(
QueryString="""
SELECT date, count(*) as daily_users
FROM user_activity
WHERE year = 2025 AND month = 10
GROUP BY date
ORDER BY date
""",
QueryExecutionContext={
'Database': 'my_datalake'
},
ResultConfiguration={
'OutputLocation': 's3://my-results/athena/'
}
)
# ✅ S3에 저장된 페타바이트급 데이터를 SQL로 분석!
# 비용: 스캔한 데이터 1TB당 $5
4️⃣ 기업용 백업 & 재해복구¶
graph TB
A[온프레미스<br/>데이터센터] -->|Storage Gateway| B[S3<br/>Standard]
B -->|30일 후| C[S3<br/>Standard-IA]
C -->|90일 후| D[S3 Glacier<br/>Flexible]
D -->|365일 후| E[S3 Glacier<br/>Deep Archive]
B -.->|복제| F[다른 리전<br/>재해복구]
style B fill:#ff6666
style C fill:#ff9999
style D fill:#99ccff
style E fill:#6699ff
style F fill:#99ff99
# 백업 정책 자동화
backup_lifecycle = {
"Rules": [
{
"Id": "백업-보관-정책",
"Status": "Enabled",
"Filter": {
"Prefix": "backups/"
},
"Transitions": [
{
"Days": 30,
"StorageClass": "STANDARD_IA" # 💰 50% 절약
},
{
"Days": 90,
"StorageClass": "GLACIER_FLEXIBLE_RETRIEVAL" # 💰 84% 절약
},
{
"Days": 365,
"StorageClass": "DEEP_ARCHIVE" # 💰 95% 절약
}
],
"Expiration": {
"Days": 2555 # 7년 후 삭제 (규정 준수)
}
}
]
}
# ✅ 1년치 백업 비용 예시
# Standard 1TB: $23/월 × 12 = $276
# 정책 적용 시: $276 → $50 (82% 절감!)
💡 현업 베스트 프랙티스¶
1. 비용 최적화 전략¶
graph TD
A[비용 절감 체크리스트] --> B[스토리지 클래스 최적화]
A --> C[수명주기 정책 설정]
A --> D[불필요한 데이터 삭제]
A --> E[압축 및 중복 제거]
B --> B1["✅ Intelligent-Tiering 사용<br/>✅ 접근 패턴 분석"]
C --> C1["✅ 30일 후 IA로 이동<br/>✅ 90일 후 Glacier로"]
D --> D1["✅ 미완료 멀티파트 삭제<br/>✅ 오래된 버전 정리"]
E --> E1["✅ gzip 압축<br/>✅ 중복 파일 검사"]
style A fill:#ff6666
style B fill:#99ff99
style C fill:#99ccff
style D fill:#ffcc99
style E fill:#ff9999
# 비용 최적화 스크립트
import boto3
from datetime import datetime, timedelta
s3 = boto3.client('s3')
def optimize_bucket_costs(bucket_name):
"""버킷 비용 최적화"""
# 1️⃣ 미완료 멀티파트 업로드 삭제
multipart_uploads = s3.list_multipart_uploads(Bucket=bucket_name)
for upload in multipart_uploads.get('Uploads', []):
# 7일 이상 된 것만
if upload['Initiated'] < datetime.now() - timedelta(days=7):
s3.abort_multipart_upload(
Bucket=bucket_name,
Key=upload['Key'],
UploadId=upload['UploadId']
)
print(f"❌ 삭제: {upload['Key']}")
# 2️⃣ 오래된 버전 삭제 (90일 이상)
versions = s3.list_object_versions(Bucket=bucket_name)
for version in versions.get('Versions', []):
if not version['IsLatest']:
age = datetime.now() - version['LastModified'].replace(tzinfo=None)
if age.days > 90:
s3.delete_object(
Bucket=bucket_name,
Key=version['Key'],
VersionId=version['VersionId']
)
print(f"🗑️ 이전 버전 삭제: {version['Key']}")
# 3️⃣ Intelligent-Tiering 설정
s3.put_bucket_intelligent_tiering_configuration(
Bucket=bucket_name,
Id='AutoOptimize',
IntelligentTieringConfiguration={
'Id': 'AutoOptimize',
'Status': 'Enabled',
'Tierings': [
{
'Days': 90,
'AccessTier': 'ARCHIVE_ACCESS'
},
{
'Days': 180,
'AccessTier': 'DEEP_ARCHIVE_ACCESS'
}
]
}
)
print("✅ 비용 최적화 완료!")
# 실행
optimize_bucket_costs('my-production-bucket')
2. 보안 체크리스트¶
graph LR
A[보안 체크리스트] --> B[✅ 암호화]
A --> C[✅ 접근 제어]
A --> D[✅ 로깅]
A --> E[✅ 백업]
B --> B1["전송: TLS<br/>저장: SSE-S3/KMS"]
C --> C1["IAM 정책<br/>버킷 정책<br/>MFA Delete"]
D --> D1["CloudTrail<br/>S3 Access Log<br/>GuardDuty"]
E --> E1["버전 관리<br/>복제<br/>백업 Vault"]
style A fill:#ff6666
# 보안 강화 스크립트
def secure_bucket(bucket_name):
"""버킷 보안 강화"""
s3 = boto3.client('s3')
# 1️⃣ 퍼블릭 액세스 차단
s3.put_public_access_block(
Bucket=bucket_name,
PublicAccessBlockConfiguration={
'BlockPublicAcls': True,
'IgnorePublicAcls': True,
'BlockPublicPolicy': True,
'RestrictPublicBuckets': True
}
)
print("✅ 퍼블릭 액세스 차단")
# 2️⃣ 암호화 활성화 (기본 암호화)
s3.put_bucket_encryption(
Bucket=bucket_name,
ServerSideEncryptionConfiguration={
'Rules': [{
'ApplyServerSideEncryptionByDefault': {
'SSEAlgorithm': 'AES256' # SSE-S3
},
'BucketKeyEnabled': True # 비용 절감
}]
}
)
print("✅ 암호화 활성화")
# 3️⃣ 버전 관리 활성화
s3.put_bucket_versioning(
Bucket=bucket_name,
VersioningConfiguration={'Status': 'Enabled'}
)
print("✅ 버전 관리 활성화")
# 4️⃣ 로깅 활성화
s3.put_bucket_logging(
Bucket=bucket_name,
BucketLoggingStatus={
'LoggingEnabled': {
'TargetBucket': f'{bucket_name}-logs',
'TargetPrefix': 'access-logs/'
}
}
)
print("✅ 액세스 로깅 활성화")
# 5️⃣ 객체 잠금 (규정 준수용)
s3.put_object_lock_configuration(
Bucket=bucket_name,
ObjectLockConfiguration={
'ObjectLockEnabled': 'Enabled',
'Rule': {
'DefaultRetention': {
'Mode': 'COMPLIANCE', # 또는 'GOVERNANCE'
'Days': 365 # 1년간 삭제 불가
}
}
}
)
print("✅ 객체 잠금 설정")
# 실행
secure_bucket('my-sensitive-data')
3. 성능 최적화¶
graph TB
A[성능 최적화] --> B[멀티파트 업로드]
A --> C[Transfer Acceleration]
A --> D[CloudFront CDN]
A --> E[S3 Select]
B -.->|언제?| B1["100MB 이상 파일<br/>병렬 업로드로 10배 빠름"]
C -.->|언제?| C1["글로벌 사용자<br/>50% 이상 속도 향상"]
D -.->|언제?| D1["정적 콘텐츠<br/>캐싱으로 지연 감소"]
E -.->|언제?| E1["대용량 JSON/CSV<br/>필터링으로 비용 절감"]
style A fill:#ff6666
style B fill:#99ff99
style C fill:#99ccff
style D fill:#ffcc99
style E fill:#ff9999
# 성능 최적화 예시
# 1️⃣ 멀티파트 업로드 (대용량 파일)
def upload_large_file(file_path, bucket, key):
"""100MB 이상 파일 고속 업로드"""
import boto3
from boto3.s3.transfer import TransferConfig
# 설정: 10MB 단위로 분할, 10개 병렬
config = TransferConfig(
multipart_threshold=1024 * 1024 * 10, # 10MB
max_concurrency=10,
multipart_chunksize=1024 * 1024 * 10,
use_threads=True
)
s3 = boto3.client('s3')
s3.upload_file(
file_path, bucket, key,
Config=config,
Callback=ProgressPercentage(file_path) # 진행률 표시
)
# ✅ 1GB 파일 업로드: 10분 → 1분!
# 2️⃣ S3 Select (데이터 필터링)
def query_large_csv(bucket, key):
"""대용량 CSV에서 필요한 데이터만 가져오기"""
s3 = boto3.client('s3')
response = s3.select_object_content(
Bucket=bucket,
Key=key,
Expression="SELECT * FROM s3object s WHERE s.age > 30",
ExpressionType='SQL',
InputSerialization={
'CSV': {'FileHeaderInfo': 'USE'}
},
OutputSerialization={
'JSON': {}
}
)
# 결과만 받아오기
for event in response['Payload']:
if 'Records' in event:
print(event['Records']['Payload'].decode())
# ✅ 1GB CSV → 10MB만 전송 (90% 절감!)
# 3️⃣ CloudFront 캐싱
cloudfront_config = {
"OriginConfig": {
"S3OriginConfig": {
"OriginAccessIdentity": "..." # S3 직접 접근 차단
}
},
"CacheBehaviors": {
"PathPattern": "images/*",
"ViewerProtocolPolicy": "redirect-to-https",
"Compress": True, # 자동 압축
"CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6" # CachingOptimized
}
}
# ✅ 이미지 로딩: 2초 → 0.1초!
📊 실제 비용 비교¶
시나리오: 스타트업 웹 서비스 (월 트래픽 1TB)¶
graph TB
A[월간 비용 비교] --> B[온프레미스<br/>$1,500]
A --> C[AWS 최적화 전<br/>$500]
A --> D[AWS 최적화 후<br/>$150]
B -.->|항목| B1["서버: $800<br/>스토리지: $400<br/>네트워크: $300"]
C -.->|항목| C1["S3 Standard: $230<br/>EC2: $200<br/>데이터 전송: $70"]
D -.->|항목| D1["S3 IA/Glacier: $50<br/>EC2: $80<br/>CloudFront: $20"]
style B fill:#ff6666
style C fill:#ffcc99
style D fill:#99ff99
최적화 전략:
# 비용 분석 및 최적화
monthly_costs = {
"최적화 전": {
"S3_Standard": 230,
"EC2_m5.large": 200,
"데이터_전송": 70,
"합계": 500
},
"최적화 후": {
"S3_Intelligent_Tiering": 50, # 78% 절감
"EC2_t3.medium_Spot": 80, # 60% 절감
"CloudFront_캐싱": 20, # 71% 절감
"합계": 150
}
}
절감률 = (500 - 150) / 500 * 100
print(f"💰 월 ${500-150} 절감 ({절감률}%)")
print(f"💰 연간 ${(500-150)*12} 절감!")
# 결과: 연간 $4,200 절감! 🎉
🎓 학습 로드맵¶
graph TD
A[AWS 스토리지 학습 로드맵] --> B[1단계: 기초]
A --> C[2단계: 중급]
A --> D[3단계: 고급]
A --> E[4단계: 전문가]
B --> B1["✅ S3 기본 사용<br/>✅ 버킷 생성/업로드<br/>✅ 스토리지 클래스 이해"]
C --> C1["✅ 수명주기 정책<br/>✅ 버전 관리<br/>✅ CloudFront 연동"]
D --> D1["✅ 비용 최적화<br/>✅ 보안 강화<br/>✅ DataSync/Snow"]
E --> E1["✅ 대규모 아키텍처<br/>✅ 데이터 레이크<br/>✅ 멀티 리전 복제"]
style A fill:#ff6666
style B fill:#99ff99
style C fill:#99ccff
style D fill:#ffcc99
style E fill:#ff9999
🛠️ 실습 프로젝트 아이디어¶
프로젝트 1: 개인 클라우드 포토 갤러리¶
# 간단한 사진 갤러리 백엔드
from flask import Flask, request, jsonify
import boto3
import uuid
app = Flask(__name__)
s3 = boto3.client('s3')
BUCKET = 'my-photo-gallery'
@app.route('/upload', methods=['POST'])
def upload_photo():
"""사진 업로드"""
file = request.files['photo']
filename = f"photos/{uuid.uuid4()}.jpg"
# S3에 업로드
s3.upload_fileobj(
file,
BUCKET,
filename,
ExtraArgs={
'ContentType': 'image/jpeg',
'Metadata': {
'uploaded-by': request.form['user_id'],
'timestamp': str(datetime.now())
}
}
)
# 썸네일 생성 (Lambda 트리거)
# CloudFront URL 반환
url = f"https://cdn.mygallery.com/{filename}"
return jsonify({'url': url})
@app.route('/photos', methods=['GET'])
def list_photos():
"""사진 목록"""
response = s3.list_objects_v2(
Bucket=BUCKET,
Prefix='photos/'
)
photos = [{
'url': f"https://cdn.mygallery.com/{obj['Key']}",
'size': obj['Size'],
'date': obj['LastModified'].isoformat()
} for obj in response.get('Contents', [])]
return jsonify(photos)
# ✅ 실행: flask run
프로젝트 2: 로그 분석 파이프라인¶
graph LR
A[웹 서버] -->|로그 생성| B[S3 raw/]
B -->|Glue Crawler| C[Data Catalog]
C --> D[Athena]
D -->|SQL 분석| E[QuickSight<br/>대시보드]
B -->|30일 후| F[S3 Glacier]
style B fill:#ff9900
style F fill:#99ccff
# 로그 분석 자동화
import boto3
from datetime import datetime
def analyze_logs():
"""매일 로그 분석"""
athena = boto3.client('athena')
# 어제 로그 분석
yesterday = (datetime.now() - timedelta(days=1)).strftime('%Y/%m/%d')
query = f"""
SELECT
hour,
COUNT(*) as requests,
AVG(response_time) as avg_response_time,
SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END) as errors
FROM
access_logs
WHERE
date = '{yesterday}'
GROUP BY
hour
ORDER BY
hour
"""
# 쿼리 실행
response = athena.start_query_execution(
QueryString=query,
QueryExecutionContext={'Database': 'logs'},
ResultConfiguration={
'OutputLocation': 's3://my-logs/analysis/'
}
)
# ✅ 결과는 S3에 자동 저장되고 QuickSight로 시각화!
return response['QueryExecutionId']
# Lambda로 매일 자동 실행
📈 모니터링 및 알람¶
# CloudWatch 알람 설정
import boto3
cloudwatch = boto3.client('cloudwatch')
# S3 비용 알람
cloudwatch.put_metric_alarm(
AlarmName='S3-고액-청구-알람',
ComparisonOperator='GreaterThanThreshold',
EvaluationPeriods=1,
MetricName='EstimatedCharges',
Namespace='AWS/Billing',
Period=86400, # 1일
Statistic='Maximum',
Threshold=100.0, # $100 초과 시
ActionsEnabled=True,
AlarmActions=[
'arn:aws:sns:ap-northeast-2:...:billing-alerts'
],
AlarmDescription='S3 비용이 $100 초과했습니다!'
)
# S3 버킷 크기 모니터링
cloudwatch.put_metric_alarm(
AlarmName='S3-버킷-용량-알람',
ComparisonOperator='GreaterThanThreshold',
EvaluationPeriods=1,
MetricName='BucketSizeBytes',
Namespace='AWS/S3',
Period=86400,
Statistic='Average',
Threshold=1099511627776, # 1TB
Dimensions=[
{
'Name': 'BucketName',
'Value': 'my-production-bucket'
},
{
'Name': 'StorageType',
'Value': 'StandardStorage'
}
]
)
# ✅ 임계값 초과 시 이메일/SMS 알림!
🎯 최종 정리: 선택 가이드¶
graph TD
Start[데이터 저장 필요] --> Q1{어떤 데이터?}
Q1 -->|파일| Q2{누가 사용?}
Q1 -->|디스크| EBS[EBS 추천]
Q1 -->|백업/아카이브| S3[S3 Glacier 추천]
Q2 -->|한 서버만| EBS
Q2 -->|여러 서버| Q3{OS?}
Q3 -->|Linux| EFS[EFS 추천]
Q3 -->|Windows| FSx[FSx for Windows 추천]
Q3 -->|고성능 필요| Lustre[FSx for Lustre 추천]
style EBS fill:#ffcc99
style S3 fill:#ff9900
style EFS fill:#99ff99
style FSx fill:#99ccff
style Lustre fill:#ff9999
📚 추가 학습 자료¶
공식 문서: - AWS S3 문서 - AWS 스토리지 블로그
실습 환경:
# AWS CLI 설치 (Mac)
brew install awscli
# 설정
aws configure
# AWS Access Key ID: [입력]
# AWS Secret Access Key: [입력]
# Default region: ap-northeast-2
# Default output format: json
# S3 버킷 생성
aws s3 mb s3://my-first-bucket-20251015
# 파일 업로드
aws s3 cp photo.jpg s3://my-first-bucket-20251015/
# 파일 목록
aws s3 ls s3://my-first-bucket-20251015/
# ✅ 이제 클라우드 스토리지를 사용할 수 있어요!
🎉 마무리¶
핵심 포인트 요약¶
- S3: 가장 많이 사용 (50%), 백업/웹 콘텐츠/데이터 레이크
- EBS: EC2 디스크, 데이터베이스용
- EFS: 여러 서버가 파일 공유
- 비용 최적화: 수명주기 정책으로 70-90% 절감 가능
- 보안: 암호화 + 버전 관리 + 로깅 필수
다음 단계¶
graph LR
A[지금] --> B[S3 버킷 만들기]
B --> C[파일 업로드/다운로드]
C --> D[수명주기 정책 설정]
D --> E[Lambda 연동]
E --> F[실전 프로젝트]
style A fill:#ff6666
style F fill:#99ff99
직접 해보세요! 🚀
# 여러분의 첫 S3 프로젝트
import boto3
# TODO: 여기에 여러분만의 코드를 작성해보세요!
s3 = boto3.client('s3')
# 1. 버킷 생성
# 2. 파일 업로드
# 3. 공개 URL 생성
# 4. 수명주기 정책 적용
# 완성하면 여러분은 AWS 스토리지 전문가! 🎓
Happy Cloud Storage! ☁️