조건부 쓰기를 통해 객체 덮어쓰기를 방지하는 방법 - Amazon Simple Storage Service

조건부 쓰기를 통해 객체 덮어쓰기를 방지하는 방법

조건부 쓰기를 사용하면 WRITE 요청에 헤더를 더 추가하여 Amazon S3 작업에 사전 조건을 지정할 수 있습니다. 조건부로 객체를 작성하려면 HTTP If-None-Match 또는 If-Match 헤더를 추가합니다.

If-None-Match 헤더는 버킷에 이미 같은 키 이름을 가진 객체가 없는지 확인하여 기존 데이터를 덮어쓰지 않도록 방지합니다.

또는 객체를 쓰기 전에 If-Match 헤더를 추가하여 객체의 엔터티 태그(ETag)를 확인할 수 있습니다. 이 헤더를 사용하여 Amazon S3는 제공된 ETag 값을 S3에 있는 객체의 ETag 값과 비교합니다. 이때 ETag 값이 일치하지 않으면 작업이 실패합니다.

버킷 소유자는 버킷 정책을 사용하여 업로드된 객체에 조건부 쓰기를 강제 적용할 수 있습니다. 자세한 내용은 Amazon S3 버킷에 조건부 쓰기 강제 적용 섹션을 참조하세요.

참고

조건부 쓰기를 사용하려면 HTTPS(TLS)를 통해 요청을 수행하거나 AWS Signature Version 4를 사용하여 요청에 서명해야 합니다.

키 이름을 기반으로 객체 덮어쓰기를 방지하는 방법

HTTP If-None-Match 조건부 헤더를 사용하여 객체를 생성하기 전에 키 이름을 기반으로 지정된 버킷에 객체가 이미 존재하는지 확인할 수 있습니다. Amazon S3에 객체를 업로드할 때 키 이름, 즉 버킷에 있는 객체의 고유한 식별자(대소문자 구분)를 지정합니다. HTTP If-None-Match 헤더가 없으면 버전이 지정되지 않았거나 버전 지정이 일시 중지된 버킷에 동일한 키 이름을 가진 객체를 업로드하면 해당 객체가 덮어쓰입니다. 버전이 지정된 버킷에서는 가장 최근에 업로드한 객체가 최신 버전이 됩니다. HTTP If-None-Match 헤더가 포함된 조건부 쓰기는 WRITE 작업 중에 객체의 존재 여부를 확인합니다. 버킷에 동일한 키 이름이 있는 경우 작업이 실패합니다. 키 이름 사용에 대한 자세한 내용은 Amazon S3 객체 이름 지정 섹션을 참조하세요.

HTTP If-None-Match 헤더가 포함된 조건부 쓰기를 수행하려면 s3:PutObject 권한이 있어야 합니다. 이를 통해 호출자는 버킷에 객체가 있는지 확인할 수 있습니다. If-None-Match 헤더에는 *(별표) 값이 필요합니다.

If-None-Match 헤더를 다음 API와 함께 사용할 수 있습니다.

다음 put-object 예시 명령은 키 이름이 dir-1/my_images.tar.bz2인 객체에 대해 조건부 쓰기를 수행하려고 시도합니다.

aws s3api put-object --bucket amzn-s3-demo-bucket --key dir-1/my_images.tar.bz2 --body my_images.tar.bz2 --if-none-match "*"

자세한 정보는 AWS CLI 명령 참조put-object 섹션을 참조하세요.

AWS CLI에 대한 자세한 내용은 AWS Command Line Interface 사용 설명서AWS Command Line Interface란 무엇입니까?를 참조하세요.

객체가 변경된 경우 덮어쓰기를 방지하는 방법

객체의 ETag는 객체에 고유한 문자열이며 객체의 콘텐츠에 대한 변경 사항을 반영합니다. If-Match 헤더를 사용하여 Amazon S3 버킷에 있는 객체의 ETag 값을 WRITE 작업 중에 제공한 값과 비교할 수 있습니다. 이때 ETag 값이 일치하지 않으면 작업이 실패합니다. ETag에 대한 자세한 내용은 Content-MD5 및 ETag를 사용하여 업로드된 객체 확인 섹션을 참조하세요.

HTTP If-Match 헤더가 포함된 조건부 쓰기를 수행하려면 s3:PutObjects3:GetObject 권한이 있어야 합니다. 그러면 호출자가 ETag를 확인하고 버킷에 있는 객체의 상태를 확인할 수 있습니다. If-Match 헤더에는 ETag 값이 문자열로 필요합니다.

If-Match 헤더를 다음 API와 함께 사용할 수 있습니다.

다음 put-object 예시 명령은 제공된 ETag 값 6805f2cfc46c0f04559748bb039d69ae를 사용해 조건부 쓰기를 수행하려고 시도합니다.

aws s3api put-object --bucket amzn-s3-demo-bucket --key dir-1/my_images.tar.bz2 --body my_images.tar.bz2 --if-match "6805f2cfc46c0f04559748bb039d69ae"

자세한 정보는 AWS CLI 명령 참조put-object 섹션을 참조하세요.

AWS CLI에 대한 자세한 내용은 AWS Command Line Interface 사용 설명서AWS Command Line Interface란 무엇입니까?를 참조하세요.

조건부 쓰기 동작

If-None-Match 헤더가 포함된 조건부 쓰기

If-None-Match 헤더가 포함된 조건부 쓰기는 버킷의 기존 객체와 비교해 평가합니다. 버킷에 동일한 키 이름을 가진 기존 객체가 없는 경우 쓰기 작업이 성공하여 200 OK 응답이 반환됩니다. 기존 객체가 있는 경우 쓰기 작업이 실패하여 412 Precondition Failed 응답이 반환됩니다.

버전 관리가 활성화된 버킷의 경우 이름이 같은 현재 객체 버전이 없거나 현재 객체 버전이 삭제 마커인 경우 쓰기 작업이 성공합니다. 그렇지 않으면 412 Precondition Failed 응답과 함께 쓰기 작업이 실패하게 됩니다.

동일한 객체 이름에 대해 조건부 쓰기가 여러 번 발생하는 경우 가장 먼저 완료되는 쓰기 작업이 성공합니다. 그런 다음 Amazon S3에서 412 Precondition Failed 응답과 함께 후속 쓰기 작업이 실패합니다.

요청이 동시에 발생하는 경우에도 객체에 대한 조건부 쓰기 작업이 완료되기 전에 객체에 대한 삭제 요청이 성공하면 409 Conflict 응답이 반환될 수 있습니다. PutObject와 함께 조건부 쓰기를 사용하는 경우 409 Conflict 오류가 발생한 후 업로드가 재시도될 수 있습니다. CompleteMultipartUpload를 사용하는 경우 409 Conflict 오류가 발생한 후 객체를 다시 업로드하려면 CreateMultipartUpload로 멀티파트 업로드를 다시 시작해야 합니다.

If-Match 헤더가 포함된 조건부 쓰기

If-Match 헤더는 버킷의 기존 객체와 비교해 평가합니다. 버킷에 동일한 키 이름 및 일치하는 ETag를 가진 기존 객체가 있는 경우 쓰기 작업이 성공하여 200 OK 응답이 반환됩니다. ETag가 일치하지 않으면 412 Precondition Failed 응답과 함께 쓰기 작업이 실패합니다.

동시 요청의 경우에도 409 Conflict 응답을 받을 수 있습니다.

객체에 대한 조건부 쓰기 작업이 완료되기 전에 해당 객체에 대한 동시 삭제 요청이 성공하는 경우 객체 키가 더 이상 존재하지 않으므로 404 Not Found 응답이 반환됩니다. 404 Not Found 응답을 받으면 객체를 다시 업로드해야 합니다.

이름이 같은 현재 객체 버전이 없거나 현재 객체 버전이 삭제 마커인 경우 작업이 404 Not Found 오류와 함께 실패합니다.

조건부 쓰기 시나리오

두 클라이언트가 같은 버킷에서 작업을 실행하는 다음 시나리오를 생각해 보세요.

멀티파트 업로드 중 조건부 쓰기

진행 중인 멀티파트 업로드 요청은 아직 완전히 쓴 객체가 아니므로 조건부 쓰기는 진행 중인 멀티파트 업로드 요청을 고려하지 않습니다. 클라이언트 1이 멀티파트 업로드를 사용하여 객체를 업로드하는 다음 예를 살펴보세요. 멀티파트 업로드 중에 클라이언트 2는 조건부 쓰기 작업을 통해 동일한 객체를 성공적으로 쓸 수 있습니다. 이후 클라이언트 1이 조건부 쓰기를 사용하여 멀티파트 업로드를 완료하려고 하면 업로드가 실패합니다.

참고

이 시나리오에서는 If-None-MatchIf-Match 헤더 모두에 대해 412 Precondition Failed 응답이 반환됩니다.

동일한 키 이름으로 항목을 쓰는 두 클라이언트의 예시입니다. 하나는 MPU용 UploadPart를 사용하고 다른 하나는 PutObject와 조건부 쓰기를 사용합니다. 이후에 시작되는 CompleteMultipartUpload 작업은 실패합니다.
멀티파트 업로드 중 동시 삭제

조건부 쓰기 요청이 완료되기 전에 삭제 요청이 성공하면 Amazon S3는 쓰기 작업에 대해 409 Conflict 또는 404 Not Found 응답을 반환합니다. 이전에 시작된 삭제 요청이 조건부 쓰기 작업보다 우선하기 때문입니다. 이 경우 새 멀티파트 업로드를 시작해야 합니다.

참고

이 시나리오에서 If-None-Match 헤더에 대해서는 409 Conflict 응답이, If-Match 헤더에 대해서는 404 Not Found 응답이 반환됩니다.

멀티파트 업로드를 사용하는 클라이언트와 MPU가 시작된 후 삭제 요청을 보내는 클라이언트 두 개의 예입니다. 조건부 쓰기가 시작되기 전에 삭제 요청이 완료됩니다.
참고

스토리지 비용을 최소화하려면 AbortIncompleteMultipartUpload 작업을 사용하여 특정 기간이 지나면 불완전한 멀티파트 업로드를 삭제하는 수명 주기 규칙을 구성하는 것이 좋습니다. 불완전한 멀티파트 업로드를 삭제하기 위한 수명 주기 규칙을 만드는 방법과 관련하여 자세한 내용은 불완전한 멀티파트 업로드를 삭제하도록 버킷 수명 주기 구성 설정을 참조하십시오.