오브젝트 스토리지와 S3 · S3 API 핵심(버킷·키·ETag·멀티파트) · 이론
멀티파트 업로드와 ETag 의 산수
한 줄 요약
멀티파트 ETag 는 내용의 md5 가 아니다. 각 파트 md5 의 이진값을 이어 붙여 다시 md5 한 뒤 -파트수 를 붙인 값이다.
왜 이게 필요했나
5GB 파일을 한 번의 PUT 으로 올리다가 90% 지점에서 연결이 끊기면 처음부터 다시 해야 합니다. 그리고 하나의 TCP 연결로는 대역폭을 다 쓰지 못합니다.
멀티파트 업로드가 이 둘을 해결합니다. 업로드를 시작해 UploadId 를 받고, 파일을 파트로 나눠 병렬로 올리고, 마지막에 파트 목록으로 완료를 알립니다. 중간에 끊기면 그 파트만 다시 올리면 됩니다.
어떻게 동작하나
규칙에 숫자가 있습니다. 파트는 최대 10,000개이고, 마지막 파트를 제외한 각 파트는 최소 5MiB 여야 합니다. 파트 최대 크기는 5GiB 입니다. 이 셋을 곱하면 단일 객체의 최대 크기가 나옵니다 — 5GiB x 10,000 = 약 5TB 입니다.
파트 크기 선택은 트레이드오프입니다. 작으면 요청 수가 늘고(요청당 과금이 있는 서비스에서는 비용), 크면 재전송 비용이 커집니다. 실무에서는 8~64MiB 사이를 많이 씁니다. 파일 크기를 10,000 으로 나눈 값보다는 커야 합니다.
ETag 계산이 흥미로운 지점입니다. 단일 파트면 내용의 md5 그대로입니다. 멀티파트면 이렇게 계산합니다.
1. 각 파트의 md5 를 이진(16바이트)으로 구한다2. 그것들을 순서대로 이어 붙인다 (파트 5개면 80바이트)3. 그 80바이트의 md5 를 구한다4. 뒤에 "-5" 를 붙인다그래서 ETag 에 하이픈이 있으면 멀티파트로 올라간 객체이고, 로컬 파일의 md5 와 절대 같지 않습니다. "ETag 로 무결성 검증했는데 안 맞는다"는 문의의 대부분이 이것입니다. 검증하려면 같은 파트 크기로 나눠 같은 계산을 해야 합니다.
현장에서 만나는 모습
중단된 멀티파트 업로드는 조용히 돈을 먹습니다. 완료되지 않은 업로드의 파트들은 저장 공간을 차지하지만 목록에는 객체로 보이지 않습니다. 클라이언트가 죽거나 배포 중에 끊긴 업로드가 몇 달 쌓이면 청구서에 이유 없는 수백 GB 가 나타납니다. AWS 에서 흔한 비용 누수 항목입니다.
대응은 둘입니다. 애플리케이션이 실패 시 명시적으로 중단(abort)하는 것, 그리고 버킷 수명주기 규칙에 AbortIncompleteMultipartUpload 를 7일 정도로 걸어 두는 것입니다. 후자를 기본으로 걸어 두는 것이 안전합니다.
다음 실습에서 할 것
24MiB 파일을 5MiB 파트로 나눠 직접 멀티파트 업로드합니다. UploadId 를 받고, 파트를 올리고, 완료하고, 그다음 멀티파트 ETag 를 손으로 계산해 서버 값과 맞춰 봅니다. 마지막에 업로드를 시작만 하고 중단하는 것까지 해 봅니다.