- Amazon S3는 2006년에 등장한 초기 클라우드 기술로 파일 저장에는 강하지만, Unix 파일 API를 그대로 대체하는 파일 시스템은 아님
- Unix 파일 API는
open,read,write,seek,close같은 좁은 인터페이스 뒤에 버퍼링, 페이지 캐시, 권한, IO 스케줄링을 감춘 깊은 모듈에 가까움 - S3는
GetObject와PutObject중심으로 단순해 보이지만,Range를 통한 부분 읽기만 가능하고 부분 덮어쓰기는 지원하지 않음 - Postgres, SQLite, MySQL, MongoDB, Elasticsearch 같은 데이터베이스는 페이지 단위 덮어쓰기에 의존하므로, SQLite나 DuckDB 파일을 S3에 그대로 올리는 방식은 작은 데이터셋 외에는 맞기 어려움
- 높은 읽기·쓰기 대역폭과 낮은 운영 부담은 S3의 강점이지만, rename/move 부재, 느린 목록 조회, XML 전용 API, 로컬 테스트 환경 부재 같은 제약을 함께 고려해야 함
S3는 파일을 저장하지만 파일 시스템은 아님
- S3는 2006년에 등장한 초기 클라우드 기술이며, 당시 유행하던 표현에 따라 “object store”로 불렸음
- 실제로는 파일 저장소로 널리 쓰이지만, 이를 “Amazon Cloud Filesystem”처럼 이해하면 일부만 맞음
- 파일 저장은 잘하지만, 기존 파일 시스템의 동작과 기대를 그대로 대신하지는 못함
Unix 파일 API와 깊은 모듈
- Unix 파일 API의 핵심은 다음 다섯 가지 호출로 요약됨
open(filepath): 파일을 엶file.read(size=100): 현재 위치에서 읽고 위치를 앞으로 이동함file.write("hello, world"): 현재 위치에 쓰고 위치를 앞으로 이동함file.seek(94): 위치를 특정 바이트로 이동함file.close(): 파일을 닫음
- 이 호출들은 실제 시스템 호출 전체 중 핵심에 해당하며, 파일 읽기와 쓰기에 필요한 최소 기능에 가까움
- 좁은 인터페이스 뒤에서 많은 처리가 이뤄지기 때문에 Unix 파일 API는 깊은 모듈(deep module) 로 볼 수 있음
- 버퍼링과 페이지 캐시
- 단편화 처리
- 권한 관리
- IO 스케줄링
- SD 카드의 wear-levelling 같은 기능도 사용자가 직접 신경 쓰지 않아도 혜택을 얻음
얕은 모듈과 YAML, ORM
- 얕은 모듈은 처리해 주는 기능에 비해 API 표면이 상대적으로 큼
- 오늘날 얕은 모듈을 알아보는 단서 중 하나는 인터페이스가 YAML인 경우임
- YAML은 마크업 언어처럼 보이지만, 실제로는 거의 어떤 의미론도 얹을 수 있는 재사용 문법처럼 쓰임
- DevOps 영역에서는 YAML이 “프로그래밍 언어”처럼 동작하는 경우가 많음
- YAML 미니 언어가 반복 구조를 제공하면 튜링 완전할 가능성이 있음
- 얕은 모듈이 항상 나쁜 것은 아님
- SQL ORM은 본질적으로 새는 추상화이며 SQL 이해 없이 쓰기 어려움
- 어떤 경우에는 얕은 모듈이 가능한 최선의 형태일 수 있음
- 같은 조건이라면 더 깊은 모듈이 더 나음
S3 API는 단순하지만 파일 API와 다름
- Unix 파일 API는 1970년대 초반에 자리 잡았고, 호환성을 위해 인터페이스는 유지된 채 내부 구현은 여러 번 바뀌었음
- Amazon S3는 Unix 파일 시스템 API를 다시 구현하지 않음
- S3의 기본 조작은 Unix 파일 API와 일부만 대응됨
GetObject(Bucket, Key, Range=None): 객체 전체 또는 일부를 읽음PutObject(Bucket, Key): 객체 전체를 씀
- 버킷이라는 추가 개념은 있지만, 기능 대비 인터페이스 비율만 보면 S3가 Unix 파일 API보다 더 단순하다고 볼 수 있음
- 결정적인 차이는 부분 덮어쓰기의 부재임
GetObject의Range인자로 객체 일부 읽기는 가능함- 객체 일부만 덮어쓰는 것은 불가능함
- 덮어쓰기는 파일 전체 단위로 해야 함
- 이 차이 때문에 S3는 기존 파일 사용 사례 중 일부에만 잘 맞음
데이터베이스는 S3에 그대로 이식되기 어려움
- 여러 데이터베이스는 데이터를 파일 시스템 위의 파일에 저장함
- Postgres는 테이블마다 2~3개 파일과 여러 관리용 파일을 유지함
- SQLite는 모든 데이터를 단일 파일에 저장하는 것으로 알려져 있음
- MySQL, MongoDB, Elasticsearch도 데이터를 파일에 저장함
- 문제는 데이터베이스가 대체로 페이지 단위 부분 덮어쓰기에 의존한다는 점임
- 데이터는 보통 4KB 또는 8KB 같은 페이지로 저장됨
- heap 파일 안에는 수천 개의 페이지가 있을 수 있음
- 필요한 데이터 저장을 위해 페이지가 부분적으로 덮어써짐
- S3에 SQLite 데이터베이스를 두면 쓰기마다 전체 데이터베이스 파일을 다시 써야 함
- S3는 큰 쓰기를 빠르게 처리할 수 있지만, 가장 작은 데이터셋을 제외하면 매번 전체 파일을 덮어쓰는 전략은 감당하기 어려움
- 매번 데이터베이스 파일을 다시 쓰면 데이터베이스 구현자가 만든 트랜잭션 무결성도 활용하기 어려워짐
- S3에서는 마지막 쓰기가 이김
S3가 잘하는 것과 못하는 것
- S3의 강점은 읽기와 쓰기의 대역폭이 매우 높다는 점임
- 온라인에서 S3에 초당 10GB 이상 쓰거나 읽은 사례를 찾기 어렵지 않음
- S3 쓰기 작업으로 금융 고객사의 사무실 네트워크를 포화시킨 경험도 있음
- 부분 덮어쓰기 부재 외에도 파일 시스템과 다른 제약이 있음
- S3에는 rename 또는 move 연산이 없음
- 이름 변경은
CopyObject후DeleteObject로 처리됨 CopyObject는 파일 크기에 비례하는 선형 시간이 걸림- 파일을 잘못된 위치에 많이 쓴 뒤 되돌리는 작업은 매우 느림
- 이름 변경은
- 파일 목록 조회는 느림
- 읽기·쓰기 대역폭은 매우 높지만, 저장된 항목을 나열하는 작업은 훨씬 느림
- 느린 로컬 파일 시스템보다도 느릴 수 있음
- 대신 파일 시스템보다 운영 부담은 낮음
- 버킷과 키 이름만 지정하면 나머지는 클라우드가 처리함
- 백업, 오프사이트 복제, 프로비저닝 같은 반복 작업 부담을 줄임
- 프로비저닝은 용량뿐 아니라 IO 작업에도 해당함
조직 간 인터페이스에서는 깊은 모듈이 더 중요함
- S3가 첫 번째 인기 클라우드 API였다는 점은 깊은 API의 장점과 연결됨
- 깊은 API는 단일 시스템 내부 모듈 간 복잡성을 감추는 데 유용하며, 두 기업 간 상호작용처럼 비용이 높은 관계에서는 더 중요함
- 기업 간 컴퓨터 시스템 연결은 전통적으로 integration이라고 불렸고, 고통의 대명사처럼 다뤄짐
- SAP 같은 대형 엔터프라이즈 소프트웨어는 깊은 모듈이 아님
- 조직 거의 전체가 SAP를 이해해야 함
- 기존 업무 방식과 계속 조정해야 함
- SAP 통합 프로젝트는 비싸고 거대하며 실패 사례도 반복됨
- S3 내부 복잡성이 SAP 설치보다 훨씬 적은 것은 아님
- Amazon은 S3를 “Simple Storage Service”라고 불렀지만 실제 S3의 복잡성은 큼
- 큐잉 이론, IO 경합, 샤딩, 파일 시스템이 처리하는 여러 문제를 포함함
- S3의 “simple”은 실제 단순함보다 깊은 인터페이스에 가까움
S3에 맞는 예외와 남는 제약
- S3가 사용 사례에 비해 비싸다는 문제를 배제하는 것은 아님
- 깊은 모듈과 얕은 모듈 개념은 John Ousterhout의 A Philosophy of Software Design에서 온 것임
- S3 API를 저장 계층으로 쓰도록 처음부터 설계된 데이터베이스도 있음
- Snowflake는 그런 사례임
- 다만 투명한 이식이 아니라 초기 설계 결정이 필요함
- Snowflake는 적어도 2016년까지는 이 결정을 매우 일찍 내린 사례임
- 데이터베이스만 S3에서 어려움을 겪는 것은 아님
- 많은 파일 형식은 저렴한
seek를 가정함 - Zip 파일은 S3보다 디스크에서 더 성능이 좋은 대표 사례임
- 많은 파일 형식은 저렴한
S3에서 아쉬운 점
- S3 API는 XML 전용임
- JSON은 2006년에도 존재했지만 당시에는 XML이 우세했음
- Amazon이 SOAP에서 REST로 전환할 때 JSON 버전을 내지 않은 점은 아쉬움
- Amazon은 XSD schema 유지도 중단함
- XML API의 핵심 장점 중 하나가 스키마인데, 현재 표준 문서는 웹사이트임
- Amazon은 로컬 테스트 환경을 제공하지 않음
- Python에서는 성실한 테스트를 위해 moto 라이브러리를 쓰는 경우가 있음
- moto는 상용 서비스 테스트 도구임에도 자원봉사자들이 유지함
- Amazon S3는 checksum을 지원하지만 기본값으로 켜져 있지 않음
- Amazon은 내구성에 대해 여러 주장을 함
- 실제 문제가 있었다는 이야기는 듣지 못했지만, 그런 주장이 테스트된 사례도 보지 못함
- 과거 S3에는 eventual consistency 함정이 있었음
- 파일을 읽고 덮어쓴 뒤 다시 읽으면 아직 바뀌지 않은 내용을 볼 수 있었음
- 짧은 시간 동안 가끔 발생해 혼란을 만들었음
- 다른 S3 구현체들은 이 특성을 복제하지 않았고, Amazon도 몇 년 전 strong read-after-write consistency로 수정함