🔥 EBS vs Instance Store: 디스크는 어디 붙어 있는가

1664자
18분

16:9 가로 강의 표지 일러스트레이션. 흰 배경. 가운데 EC2 인스턴스를 나타내는 둥근 모서리 박스와 그 박스 안에 들어 있는 작은 NVMe 카드가 emerald 색으로 Instance Store 라벨, 박스 오른쪽으로 점선 화살표가 별도 노드 위 EBS 실린더로 AWS 오렌지 색으로 EBS 라벨. 위쪽 띠에 EBS vs Instance Store 라벨. 절제된 sans-serif. 프로페셔널 IT 강의 표지 스타일

EC2 인스턴스를 한 번 stop했다가 다시 켰는데, /var/log가 통째로 비어 있었다. 처음에는 SSH 키가 잘못 들어갔거나 로그 rotation이 너무 셌나 의심했다. 그게 아니었다. 그 인스턴스는 d 옵션이 붙은 패밀리(c5d.large)였고, /var/log가 EBS가 아니라 instance store 위에 마운트돼 있었다. stop 명령 한 줄이 SSD 데이터를 통째로 지웠다.

그날부터 디스크가 어디에 붙어 있는지를 매번 의심하게 됐다. 같은 m6i.xlarge처럼 보여도 d가 붙은 m6id.xlarge는 인스턴스를 멈추는 순간 데이터를 모두 잃는다. EC2 위에 디스크를 붙이는 길은 두 갈래뿐이고, 두 갈래의 차이는 물리적으로 어디에 있느냐 한 줄에서 시작한다.

EBS는 네트워크 너머에, Instance Store는 호스트 안에

EBS vs Instance Store 물리 구조 다이어그램. AZ 박스 안에 호스트 머신 박스가 있고, 그 안의 EC2 instance 안에 Instance Store NVMe 카드가 들어 있다. 호스트 박스 밖에는 별도 storage 노드가 있고 그 안에 EBS gp3 볼륨과 EBS io2 Block Express 볼륨이 있으며, EC2와 EBS 사이가 점선 네트워크 연결로 그려져 있다.

EBS는 인스턴스가 도는 호스트 머신과는 별도의 네트워크 노드에 붙어 있다. AZ 단위로 묶인 별개 객체이고, 인스턴스에서 보면 iSCSI 같은 블록 프로토콜로 연결된 원격 디스크에 가깝다. AWS 콘솔에서 Volume을 detach하고 다른 인스턴스에 attach할 수 있는 까닭이 여기서 나온다. 볼륨과 인스턴스의 lifecycle이 분리돼 있어서다.

Instance Store는 인스턴스 타입: CPU·메모리·네트워크의 조합에서 본 d 옵션 글자(c5d, m5d, r5d, m7gd)나 I 패밀리(i3, i3en, i4i, i7i, i7ie)에 붙어 오는 호스트 머신 내부 NVMe 카드다. 같은 물리 서버 안에 들어 있는 SSD라서 네트워크 hop이 없다. AWS I3en은 인스턴스당 최대 60 TB의 NVMe를 2백만 IOPS·16 GB/s 처리량으로 제공하고, I7ie는 그 두 배에 가까운 120 TB까지 제공한다. 같은 GB-월 단가의 EBS로는 그 throughput을 만들기 어렵다.

다만 가까이 있다는 사실에는 대가가 따른다. 같은 m6id.xlarge 두 인스턴스가 있다고 해 보자. 한쪽은 인스턴스 stop을 한 번도 호출하지 않는 batch worker, 다른 한쪽은 매일 밤 자동 hibernate가 도는 dev 인스턴스다. 첫 인스턴스의 instance store는 reboot 사이클만 도는 한 살아 있지만, 두 번째 인스턴스의 instance store는 매일 hibernate 한 번에 모든 내용을 잃는다. EBS였다면 양쪽 다 매일 살아 돌아온다.

인스턴스가 멈출 때 살아남는 디스크와 그러지 못하는 디스크

인스턴스 lifecycle 이벤트와 디스크 데이터 보존 표. 가로 축에 EBS Volume과 Instance Store 두 열. 세로 축에 Reboot, Stop, Hibernate, Terminate, Underlying host disk failure 다섯 행. EBS는 다섯 이벤트에서 거의 모두 보존, Instance Store는 reboot에서만 보존하고 나머지 네 이벤트에서는 데이터를 모두 잃는다.

이 차이가 운영의 결정 손잡이다. EBS는 인스턴스 reboot·stop·hibernate에서 데이터를 그대로 보존한다. terminate 시점에만 DeleteOnTermination 플래그에 따라 결과가 다르다. 플래그가 true이면 볼륨이 인스턴스와 같이 없어지고, false면 인스턴스가 사라져도 볼륨은 그대로 남는다. 그래서 콘솔에서 detach해 다른 인스턴스에 attach하는 길이 가능하다.

Instance Store는 정확히 한 가지 상황에서만 살아남는다. 그 한 상황은 인스턴스 reboot이다. AWS 공식 문서가 한 줄로 잘라서 적어 둔다. "The data persists even if the instance is rebooted. However, the data does not persist if the instance is stopped, hibernated, or terminated." 그리고 한 줄을 더 적어 둔다. "When the instance is stopped, hibernated, or terminated, every block of the instance store volume is cryptographically erased." Nitro 시스템이 stop 시점에 SSD 블록을 암호 키 단위로 지운다. 같은 호스트의 다음 사용자에게 데이터가 새지 않게 하기 위함이지만, 결과적으로 stop 한 번에 데이터를 복구 불가능하게 잃는다는 뜻이기도 하다.

여기에 한 가지가 더 있다. underlying disk failure다. 호스트 머신의 NVMe 카드 자체가 고장 나면 인스턴스가 stop·terminate되지 않아도 데이터가 같이 날아간다. AWS는 status check failure 알람으로 호스트 fail을 감지할 수 있게 해 주지만, 그 알람이 울리는 시점엔 이미 디스크가 죽어 있다. 그래서 instance store 위에 데이터의 유일한 사본만 두는 구성은 운영에서 거의 대부분 잘못된 구성이다.

EBS 볼륨 네 가지: SSD 두 종, HDD 두 종

EBS 안에서도 새 볼륨을 만들 때 고를 수 있는 주력 타입은 네 가지다 (legacy로 gp2 / io1 / standard 매그네틱도 그대로 쓸 수는 있지만, 새 볼륨은 후속 타입을 권장).

볼륨 타입매체워크로드Max IOPS / volMax Throughput / vol서울 GB-월
gp3 (General Purpose SSD)SSD기본값으로 부팅 디스크, 일반 DB, 웹앱에 적합80,0002,000 MiB/s$0.0912
io2 Block Express (Provisioned IOPS SSD)SSD99.999% durability 필요한 미션 크리티컬 DB, SAP HANA256,0004,000 MiB/s$0.1278
st1 (Throughput Optimized HDD)HDDKafka, Spark/EMR, 데이터 웨어하우스의 큰 sequential 읽기(throughput 모델)500 MiB/s$0.051
sc1 (Cold HDD)HDD거의 안 읽는 백업·아카이브로 가장 싸다(해당 없음)250 MiB/s$0.0174

(AWS 공식 EBS 가격 페이지 ap-northeast-2 기준, 2026-04 스냅샷)

EBS 볼륨 네 가지의 성능 vs GB-월 단가 사분면. 가로축은 최대 IOPS와 처리량, 세로축은 GB-월 단가. sc1과 st1은 HDD 영역에 낮은 가격으로, gp3는 가운데에 default 위치로 80K IOPS · 2 GiB/s · $0.0912, io2 Block Express는 우상단 256K IOPS · $0.1278에 미션 크리티컬 영역으로 표시.

기억할 기준은 두 줄이다. SSD인가 HDD인가에 따라 random I/O와 sequential I/O 적합도가 다르다. General Purpose냐 Provisioned IOPS냐에 따라 기본 워크로드와 미션 크리티컬 워크로드의 답이 다르다. gp3가 default고, io2 Block Express는 진짜 필요한 곳에만, st1·sc1은 순차 읽기 또는 cold 데이터에만 둔다.

gp3는 baseline 무료, 그 위는 청구서에 매달 추가

gp3 가격 모델 다이어그램. 왼쪽에 baseline 무료 영역(3,000 IOPS · 125 MB/s 처리량으로 100 GB × $0.0912 = $9.12), 오른쪽에 provisioned 영역(추가 IOPS·throughput 단가). PostgreSQL 5K IOPS · 200 MB/s 워크로드의 청구서 두 줄이 합계 $23.5/월로 스토리지 단가의 약 2.6배다.

gp3는 모든 볼륨에 3,000 IOPS + 125 MB/s 처리량을 무료로 묶어 준다. 데이터 한도는 서울 기준 GB-월 $0.0912의 GB 단가만 내면 거기까지는 추가 청구가 없다. 이 baseline이 대부분의 부팅 디스크·중간 트래픽 웹앱에는 충분하다.

문제는 baseline을 넘어가는 구간이다. 가령 PostgreSQL DB가 평소 5,000 IOPS로 돈다고 해 보자. baseline 3,000을 빼면 2,000 IOPS가 추가 프로비저닝 영역이 된다. 서울 리전 추가 IOPS-월 단가는 $0.0057. 30일 풀가동 기준으로 2,000 × $0.0057 = $11.4가 매달 청구서에 추가로 올라간다. 같은 인스턴스에 throughput을 200 MB/s로 잡으면 (200 - 125) × $0.04 ≈ $3가 또 추가로 붙는다. 관리형이 감추는 비용은 보통 이 두 항목에서 나온다. 모니터링 대시보드에는 안 잡히고 청구서에만 매끈하게 누적하는 IOPS·throughput 단가다.

io2 Block Express는 단계 가격: 256K IOPS의 우상향 곡선

io2는 AWS 공식 문서 기준 2025-04-30 이후 신규·기존 모든 io2 볼륨을 io2 Block Express로 옮겨 두었고, 볼륨 단위로 단계별 IOPS 가격을 적용한다. 서울 리전 기준으로 첫 32,000 IOPS는 IOPS-월 $0.0666, 32,001–64,000 구간은 단가가 내려가서 약 $0.046, 64,000 초과는 한 단계 더 내려간다. 단계 구분은 볼륨 한 개 단위로 적용한다. 그러니 같은 32,000 IOPS를 두 개의 io2 볼륨에 16,000씩 나눠 잡으면 둘 다 1단계 단가가 적용 대상이다. IOPS를 한 볼륨에 몰면 그만큼 단가가 낮다는 의미다.

worked example 한 개로 감각을 잡아 보자. 60,000 IOPS짜리 io2 볼륨 한 개를 한 달 풀가동하면 IOPS 청구서는 32,000 × $0.0666 + 28,000 × $0.046 ≈ $3,419가 된다. 사실 같은 60,000 IOPS는 gp3에서도 만들 수 있다. 2025 spec 업데이트로 gp3 vol당 한도가 80,000 IOPS / 2,000 MiB/s까지 올라간 결과다. 그래도 io2가 답인 경우가 따로 있는 건 평균 500 μs 이하 latency(Nitro 인스턴스에 16 KiB I/O 기준)와 99.999% durability가 같이 필요할 때다. SAP HANA, Oracle, 핀테크 거래 DB가 io2의 원래 용도다. 그렇지 않은 곳에는 거의 항상 gp3가 답이다.

서울과 us-east-1의 차이도 짚고 가자. us-east-1 gp3는 GB-월 $0.08, 서울은 $0.0912로 약 14% 더 비싸다. io2도 비슷한 비율(서울 $0.1278 vs us-east-1 $0.125)로 비싸다. 서울 리전(ap-northeast-2) 기준의 가격이 우리 청구서의 진짜 숫자라는 점을 잊지 않는 편이 낫다. 한국 사용자에게 latency를 맞춰야 하는 서비스라면 다른 선택지가 별로 없다.

Instance Store는 영속성이 필요 없는 곳에서만

이쯤 되면 한 가지 의문이 떠오를 수 있다. EBS gp3가 vol당 16,000 IOPS인데 Instance Store는 I3en에서 2백만 IOPS를 친다. 그렇게 빠르고 (인스턴스 단가에 포함돼) 싼 디스크를 안 쓸 까닭이 있나?

답은 위 lifecycle 표에 그대로 들어 있다. stop 한 번이면 데이터가 모두 날아간다는 사실 하나가 사용처를 정확히 한정한다. 운영에서 검증된 다음 세 가지 패턴에서만 instance store가 정답이 된다.

캐시 / 임시 buffer. 데이터가 사라져도 다른 곳에서 다시 만들 수 있는 연산의 부산물. Spark/EMR이 셔플 단계에 임시 파일을 쓰는 곳이 대표 예다. EMR 워커가 죽으면 잡 자체가 다른 워커에서 retry되니, 셔플 파일이 사라져도 정답에 영향이 없다. AWS EMR 공식 문서도 instance store가 buffer·cache·scratch 같은 임시 데이터에 적합하다고 명시한다.

복제본을 다른 노드에 들고 있는 NoSQL replica. Cassandra·ScyllaDB 같은 분산 DB는 같은 데이터를 보통 3개 노드에 복제한다. 한 노드의 instance store가 사라져도 나머지 두 노드에 데이터가 남아 있고, 그 노드를 새로 띄운 뒤 다른 노드에서 streaming으로 복구한다. ScyllaDB 공식 문서가 I3en / I7ie / Storage Optimized I 패밀리를 첫 권장 인스턴스로 적어 둔 이유가 그래서다.

ML 학습 / 추론의 임시 데이터셋. 학습 셋 원본은 S3에 있고, 학습 시작 시점에 instance store로 복사해서 빠르게 읽는 패턴. 인스턴스가 죽어도 S3가 source of truth이므로 복구가 가능하다. 호스트 직결 NVMe의 read latency가 네트워크 attached EBS보다 한 단계 낮으므로 학습 시간이 줄어든다.

이 세 가지에서 벗어난 곳에 instance store를 단독으로 쓰면, 언젠가 (한 달 안일 가능성이 높다) stop 한 번에 데이터를 모두 잃는 사건이 발생한다. 첫 단락의 내 사례가 정확히 그런 종류의 손실이다.

디스크를 붙일 때 한 줄을 자문한다

EC2에 디스크를 붙일 때 매번 한 줄을 자문한다. 이 데이터가 인스턴스보다 오래 살아남아야 하는가? 답이 "그렇다"면 거의 항상 EBS gp3가 default고, IOPS·durability가 진짜 모자라는 곳에서만 io2 Block Express로 올라간다. 답이 "아니다 — 다른 곳에 복제본이 있거나 다시 만들 수 있다"면 instance store가 빠르고 싸다. 그 한 줄이 볼륨 타입 표 전체보다 결정에 더 가깝다.

다음 단계로 Spot, On-Demand, Reserved: 세 가지 가격 모델로 넘어간다. 디스크를 정했으니 이제 인스턴스 시간을 어떻게 사느냐를 본다.

참고 자료

YouTube 영상

채널 보기
인공지능은 세상을 어떻게 숫자로 읽는가? - 이미지, 소리 그리고 텍스트가 행렬이 되는 원리 | 선형대수학
AI는 데이터를 어떻게 분류할까? 벡터의 거리와 KNN 알고리즘 | 선형대수학
AI를 위한 선형대수학 - 소개 | 선형대수학
Trie 자료구조 파이썬 구현: Search와 Starts With 연산 | Trie 자료구조 이야기
트라이(Trie)에서 단어를 삭제하는 방법 | Trie 자료구조 이야기
트라이(Trie)를 이용한 자동 완성 알고리즘 | Trie 자료구조 이야기
마지막편, 트라이 노드를 50% 이상 줄이는 방법? 압축 트라이 성능 분석 | Trie 자료구조 이야기
내적의 기하학적 의미와 코사인 유사도 원리 | 선형대수학