조건부 쓰기를 통해 객체 덮어쓰기를 방지하는 방법
조건부 쓰기를 사용하면 쓰기 요청에 헤더를 추가하여 S3 작업에 사전 조건을 지정할 수 있습니다. 이렇게 하면 버킷에 이미 같은 키 이름을 가진 기존 객체가 없는지 확인하여 기존 데이터를 덮어쓰지 않도록 방지할 수 있습니다. 조건부 쓰기는 범용 버킷과 디렉터리 버킷에 대한 API 요청을 대상으로 작동합니다.
Amazon S3에 객체를 업로드할 때 키 이름을 지정합니다. 키 이름은 버킷에 있는 객체의 고유한 대소문자 구분 식별자입니다. 버전이 지정되지 않았거나 버전이 일시 중단된 버킷에 동일한 키 이름을 가진 객체를 업로드하면 해당 객체가 덮어쓰여집니다. 버전이 지정된 버킷에서는 가장 최근에 업로드한 객체가 최신 버전이 됩니다.
조건부 쓰기는 WRITE
작업 중에 객체의 존재 여부를 확인합니다. 버킷에 동일한 키 이름이 있는 경우 WRITE
작업이 실패합니다. 조건부 쓰기를 사용하면 기존 객체를 덮어쓸 가능성 없이 여러 클라이언트가 동일한 버킷에 쓰도록 할 수 있습니다.
조건부 쓰기를 수행하려면 s3:PutObject
권한이 있어야 합니다. 이 권한을 통해 호출자는 버킷에 객체가 있는지 확인할 수 있습니다. AWS SDK에서 미리 서명된 URL과 함께 조건부 쓰기를 사용할 수 있습니다.
참고
조건부 쓰기를 사용하려면 HTTPS(TLS)를 통해 요청을 수행하거나 AWS Signature Version 4를 사용하여 요청에 서명해야 합니다.
지원되는 API
다음 S3 API는 조건부 쓰기 사용을 지원합니다.
다음 헤더를 사용하여 객체 키 이름에 따라 객체를 쓸 수 있습니다. 객체 키 이름에 대한 정보는 Amazon S3 객체 이름 지정 섹션을 참조하세요.
PutObject
-
If-None-Match
- 지정된 버킷에 동일한 키 이름을 가진 기존 객체가 이미 없는 경우에만 객체를 업로드합니다. 이 파라미터에는 *(별표) 값을 사용해야 합니다.
다음 put-object
예제 명령은 AWS CLI를 통해 if-none-match
파라미터를 사용하여 조건부 쓰기 헤더가 있는 객체를 업로드하는 방법을 보여줍니다.
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란 무엇입니까?를 참조하세요.
이 헤더에 대한 자세한 내용은 Amazon Simple Storage Service API 참조의 PutObject 섹션을 참조하세요.
CompleteMultipartUpload
-
If-None-Match
- 지정된 버킷에 동일한 키 이름을 가진 기존 객체가 이미 없는 경우에만 업로드를 완료합니다. 이 파라미터에는 *(별표) 값을 사용해야 합니다.
다음 complete-multipart-upload
예제 명령은 AWS CLI를 통해 if-none-match
파라미터를 사용하여 조건부 쓰기 헤더가 있는 멀티파트 업로드를 완료하는 방법을 보여줍니다.
aws s3api complete-multipart-upload --multipart-upload file://mpustruct --bucket
amzn-s3-demo-bucket
--key dir-1/my_images.tar.bz2 --upload-iduploadID
--if-none-match "*"
자세한 정보는 AWS CLI 명령 참조의 complete-multipart-upload 섹션을 참조하세요.
AWS CLI에 대한 자세한 내용은 AWS Command Line Interface 사용 설명서의 AWS Command Line Interface란 무엇입니까?를 참조하세요.
이 헤더에 대한 자세한 내용은 Amazon Simple Storage Service API 참조의 CompleteMultipartUpload 섹션을 참조하세요.
조건부 쓰기 동작
조건부 쓰기는 버킷의 기존 객체를 기준으로 평가합니다. 버킷에 동일한 키 이름을 가진 기존 객체가 없는 경우 쓰기 작업이 성공하여 200
응답이 반환됩니다. 기존 객체가 있는 경우 쓰기 작업이 실패하여 412 Precondition Failed
응답이 반환됩니다. 버전 관리가 활성화된 버킷의 경우 S3는 조건부 평가의 일환으로 이름이 같은 현재 객체 버전이 있는지 확인합니다. 이름이 같은 현재 객체 버전이 없거나 현재 객체 버전이 삭제 마커인 경우 쓰기 작업이 성공합니다. 그렇지 않으면 412 Precondition Failed
응답과 함께 쓰기 작업이 실패하게 됩니다.
동일한 객체 이름에 대해 조건부 쓰기가 여러 번 발생하는 경우 가장 먼저 완료되는 쓰기 작업이 성공합니다. 그러면 Amazon S3는 412 Precondition
Failed
응답과 함께 후속 쓰기에 실패합니다.
요청이 동시에 발생하는 경우에도 객체에 대한 조건부 쓰기 작업이 완료되기 전에 객체에 대한 삭제 요청이 성공하면 409 Conflict
응답이 반환될 수 있습니다. 삭제 요청이 이전에 시작된 조건부 쓰기 작업보다 우선하기 때문입니다. PutObject
와 함께 조건부 쓰기를 사용하는 경우 409
오류가 발생한 후 업로드가 재시도될 수 있습니다. CompleteMultipartUpload
를 사용하는 경우 409
오류가 발생한 후 객체를 다시 업로드하려면 CreateMultipartUpload
로 멀티파트 업로드를 다시 시작해야 합니다.
두 클라이언트가 같은 버킷에서 작업을 실행하는 다음 시나리오를 생각해 보세요.
412 Precondition Failed 응답
진행 중인 멀티파트 업로드 요청은 아직 완전히 쓴 객체가 아니므로 조건부 쓰기는 진행 중인 멀티파트 업로드 요청을 고려하지 않습니다. 클라이언트 1이 멀티파트 업로드를 사용하여 객체를 업로드하는 다음 예를 살펴보세요. 멀티파트 업로드 중에 클라이언트 2는 조건부 쓰기 작업을 통해 동일한 객체를 성공적으로 쓸 수 있습니다. 이후 클라이언트 1이 조건부 쓰기를 사용하여 멀티파트 업로드를 완료하려고 하면 객체가 이미 존재하므로 업로드가 실패합니다.
409 Conflict 응답
조건부 쓰기 요청이 완료되기 전에 삭제 요청이 성공하면 Amazon S3는 쓰기 작업에 대한 409 Conflict
응답을 반환합니다. 이전에 시작된 삭제 요청이 조건부 쓰기 작업보다 우선하기 때문입니다. puppy.txt
파일이 버킷에 있는 다음 예를 살펴보세요. 클라이언트 1은 조건부 쓰기로 멀티파트 업로드를 완료하기 위해 puppy.txt
라는 동일한 이름을 가진 다른 파일의 멀티파트 업로드를 시작합니다. 업로드 중에 클라이언트 2는 버킷에서 puppy.txt
를 삭제합니다. 클라이언트 1이 CompleteMultipartUpload
를 사용하여 조건부 쓰기로 자체 puppy.txt
파일을 업로드하려고 하면 409
Conflict
응답과 함께 실패합니다. 이 경우 새 멀티파트 업로드를 시작해야 합니다.
참고
스토리지 비용을 최소화하려면 AbortIncompleteMultipartUpload
작업을 사용하여 특정 기간이 지나면 불완전한 멀티파트 업로드를 삭제하는 수명 주기 규칙을 구성하는 것이 좋습니다. 불완전한 멀티파트 업로드를 삭제하기 위한 수명 주기 규칙을 만드는 방법과 관련하여 자세한 내용은 불완전한 멀티파트 업로드를 삭제하도록 버킷 수명 주기 구성 설정을 참조하십시오.