[CLOUD-006][기초] 객체 저장소와 CDN 캐시 흐름 이해하기
페이지 정보

본문
[이번 수업]
객체 스토리지는 바이트 데이터, 고유한 키(key: 객체를 찾는 이름), 메타데이터를 묶어 저장합니다. CDN은 원본(origin)과 사용자 사이의 엣지에 응답을 보관해 가까운 곳에서 전달합니다. 두 기술로 정적 파일을 배포하는 흐름을 익힙니다.
[선수지식]
HTTP 요청·응답과 CLOUD-002의 리전·엣지를 알면 좋습니다. 클라우드 계정 없이 Python 3만 사용합니다.
[학습목표]
1. 컨테이너, 객체 키, 데이터, 메타데이터의 관계를 설명한다.
2. CDN의 캐시 적중(hit), 부적중(miss), TTL을 구분한다.
3. 내용 해시 파일명에 긴 캐시 시간을 안전하게 적용한다.
[핵심개념]
객체는 보통 컨테이너 안에서 키로 식별됩니다. `assets/logo.png` 전체가 하나의 키이며 슬래시가 실제 폴더인지는 구현에 따라 다릅니다. 메타데이터는 `Content-Type`, 크기, 캐시 정책처럼 데이터를 설명합니다.
사용자가 URL을 요청하면 엣지는 캐시 키를 확인합니다. HTTP 표준에서 캐시 키는 최소한 요청 메서드와 대상 URI를 바탕으로 하며 `Vary`가 지정한 헤더도 구분할 수 있습니다. 신선한 응답이 있으면 hit, 없거나 만료되면 miss로 원본에서 가져옵니다. `Cache-Control: max-age=3600`은 3600초의 TTL을 뜻합니다. 만료 후 ETag로 변경 여부를 재검증할 수 있습니다.
수정 가능한 `app.js`에 긴 TTL을 주면 새 배포가 늦게 보입니다. `app.a1b2c3.js`처럼 내용 해시를 넣어 새 내용은 새 URL로 배포하세요. 불변 URL은 긴 TTL, 이를 참조하는 HTML은 짧은 TTL이나 재검증 정책을 씁니다.
[따라하기]
아래를 `object_cdn_lab.py`로 저장합니다.
```python
from hashlib import sha256
from pathlib import Path
data = b"hello object storage\n"
full_hash = sha256(data).hexdigest()
key = f"assets/message.{full_hash[:12]}.txt"
path = Path("origin") / key
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(data)
metadata = {
"Content-Type": "text/plain; charset=utf-8",
"Cache-Control": "public, max-age=31536000, immutable",
"ETag": f'"{full_hash}"',
}
print("key:", key)
print("size:", path.stat().st_size)
print("cache:", metadata["Cache-Control"])
```
macOS·Linux는 `python3 object_cdn_lab.py`, Windows PowerShell은 `python object_cdn_lab.py`로 실행합니다. 예상 결과입니다.
```text
key: assets/message.d15ab86e6247.txt
size: 21
cache: public, max-age=31536000, immutable
```
`origin/assets`에 파일이 생깁니다. `Path`가 운영체제별 경로 구분자를 처리합니다. 이 키를 URL로 제공하고 같은 Cache-Control을 응답 메타데이터로 설정하면 내용이 같은 동안 엣지가 재사용할 수 있습니다.
[흔한 실수]
키의 슬래시를 일반 폴더와 같다고 가정하지 않습니다. 파일을 바꾸면서 키는 그대로 두고 긴 TTL을 적용하지 않습니다. 캐시 여부는 상태, 헤더, 정책과 구현에 따라 달라집니다. 개인별·로그인 응답을 공유 캐시에 저장하지 않습니다.
[보안 주의]
저장소는 기본 비공개로 두고 읽기·쓰기 권한을 나눕니다. 비공개 파일은 만료 시간이 짧은 서명 URL 등으로 전달합니다. 업로드의 확장자와 Content-Type만 믿지 말고 허용 목록, 실제 형식, 크기를 검증하며 서버가 만든 이름을 씁니다. 악성 파일 검사와 웹 실행 경로 분리도 검토합니다. 개인정보·인증 응답은 `private` 또는 `no-store` 등 알맞은 정책으로 공유 CDN에 남지 않게 합니다. 실습은 본인 소유 로컬·격리 환경에서만 수행합니다.
[직접 해볼 과제]
`data`를 `b"hello CDN\n"`으로 바꿔 다시 실행하세요. 키가 달라지는 이유와 HTML에는 `Cache-Control: no-cache`를 적용하는 이유를 세 문장으로 적습니다.
[확인문제]
1. 객체의 키와 메타데이터는 각각 무엇을 나타내나요?
2. CDN 캐시의 hit와 miss는 어떤 차이가 있나요?
3. 내용 해시 파일명에 긴 TTL을 적용하면 배포 오류가 줄어드는 이유는 무엇인가요?
[다음 학습]
CLOUD-007에서는 관리형 데이터베이스와 인메모리 캐시의 역할, 직접 운영과의 차이, 선택 기준을 배웁니다.
[공식 참고 자료]
- 객체 스토리지 API 개요: https://docs.openstack.org/swift/latest/api/object_api_v1_overview.html
- 객체 스토리지 특성과 메타데이터: https://docs.openstack.org/swift/latest/admin/objectstorage-characteristics.html
- HTTP 캐싱 표준 RFC 9111: https://www.rfc-editor.org/rfc/rfc9111.html
- HTTP 의미론 표준 RFC 9110: https://www.rfc-editor.org/rfc/rfc9110.html
- 파일 업로드 보안 지침: https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html
객체 스토리지는 바이트 데이터, 고유한 키(key: 객체를 찾는 이름), 메타데이터를 묶어 저장합니다. CDN은 원본(origin)과 사용자 사이의 엣지에 응답을 보관해 가까운 곳에서 전달합니다. 두 기술로 정적 파일을 배포하는 흐름을 익힙니다.
[선수지식]
HTTP 요청·응답과 CLOUD-002의 리전·엣지를 알면 좋습니다. 클라우드 계정 없이 Python 3만 사용합니다.
[학습목표]
1. 컨테이너, 객체 키, 데이터, 메타데이터의 관계를 설명한다.
2. CDN의 캐시 적중(hit), 부적중(miss), TTL을 구분한다.
3. 내용 해시 파일명에 긴 캐시 시간을 안전하게 적용한다.
[핵심개념]
객체는 보통 컨테이너 안에서 키로 식별됩니다. `assets/logo.png` 전체가 하나의 키이며 슬래시가 실제 폴더인지는 구현에 따라 다릅니다. 메타데이터는 `Content-Type`, 크기, 캐시 정책처럼 데이터를 설명합니다.
사용자가 URL을 요청하면 엣지는 캐시 키를 확인합니다. HTTP 표준에서 캐시 키는 최소한 요청 메서드와 대상 URI를 바탕으로 하며 `Vary`가 지정한 헤더도 구분할 수 있습니다. 신선한 응답이 있으면 hit, 없거나 만료되면 miss로 원본에서 가져옵니다. `Cache-Control: max-age=3600`은 3600초의 TTL을 뜻합니다. 만료 후 ETag로 변경 여부를 재검증할 수 있습니다.
수정 가능한 `app.js`에 긴 TTL을 주면 새 배포가 늦게 보입니다. `app.a1b2c3.js`처럼 내용 해시를 넣어 새 내용은 새 URL로 배포하세요. 불변 URL은 긴 TTL, 이를 참조하는 HTML은 짧은 TTL이나 재검증 정책을 씁니다.
[따라하기]
아래를 `object_cdn_lab.py`로 저장합니다.
```python
from hashlib import sha256
from pathlib import Path
data = b"hello object storage\n"
full_hash = sha256(data).hexdigest()
key = f"assets/message.{full_hash[:12]}.txt"
path = Path("origin") / key
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(data)
metadata = {
"Content-Type": "text/plain; charset=utf-8",
"Cache-Control": "public, max-age=31536000, immutable",
"ETag": f'"{full_hash}"',
}
print("key:", key)
print("size:", path.stat().st_size)
print("cache:", metadata["Cache-Control"])
```
macOS·Linux는 `python3 object_cdn_lab.py`, Windows PowerShell은 `python object_cdn_lab.py`로 실행합니다. 예상 결과입니다.
```text
key: assets/message.d15ab86e6247.txt
size: 21
cache: public, max-age=31536000, immutable
```
`origin/assets`에 파일이 생깁니다. `Path`가 운영체제별 경로 구분자를 처리합니다. 이 키를 URL로 제공하고 같은 Cache-Control을 응답 메타데이터로 설정하면 내용이 같은 동안 엣지가 재사용할 수 있습니다.
[흔한 실수]
키의 슬래시를 일반 폴더와 같다고 가정하지 않습니다. 파일을 바꾸면서 키는 그대로 두고 긴 TTL을 적용하지 않습니다. 캐시 여부는 상태, 헤더, 정책과 구현에 따라 달라집니다. 개인별·로그인 응답을 공유 캐시에 저장하지 않습니다.
[보안 주의]
저장소는 기본 비공개로 두고 읽기·쓰기 권한을 나눕니다. 비공개 파일은 만료 시간이 짧은 서명 URL 등으로 전달합니다. 업로드의 확장자와 Content-Type만 믿지 말고 허용 목록, 실제 형식, 크기를 검증하며 서버가 만든 이름을 씁니다. 악성 파일 검사와 웹 실행 경로 분리도 검토합니다. 개인정보·인증 응답은 `private` 또는 `no-store` 등 알맞은 정책으로 공유 CDN에 남지 않게 합니다. 실습은 본인 소유 로컬·격리 환경에서만 수행합니다.
[직접 해볼 과제]
`data`를 `b"hello CDN\n"`으로 바꿔 다시 실행하세요. 키가 달라지는 이유와 HTML에는 `Cache-Control: no-cache`를 적용하는 이유를 세 문장으로 적습니다.
[확인문제]
1. 객체의 키와 메타데이터는 각각 무엇을 나타내나요?
2. CDN 캐시의 hit와 miss는 어떤 차이가 있나요?
3. 내용 해시 파일명에 긴 TTL을 적용하면 배포 오류가 줄어드는 이유는 무엇인가요?
[다음 학습]
CLOUD-007에서는 관리형 데이터베이스와 인메모리 캐시의 역할, 직접 운영과의 차이, 선택 기준을 배웁니다.
[공식 참고 자료]
- 객체 스토리지 API 개요: https://docs.openstack.org/swift/latest/api/object_api_v1_overview.html
- 객체 스토리지 특성과 메타데이터: https://docs.openstack.org/swift/latest/admin/objectstorage-characteristics.html
- HTTP 캐싱 표준 RFC 9111: https://www.rfc-editor.org/rfc/rfc9111.html
- HTTP 의미론 표준 RFC 9110: https://www.rfc-editor.org/rfc/rfc9110.html
- 파일 업로드 보안 지침: https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html
- 이전글[DEVOPS-006][기초] 파드·디플로이먼트·서비스 연결하기 26.09.02
- 다음글[NET-006][기초] 라우터와 NAT로 공인·사설 IP 구분하기 26.09.01
댓글목록
등록된 댓글이 없습니다.
