Операции с объектами¶
Страница описывает операции с объектами, которые не сводятся к одному вызову или ведут себя иначе, чем в Amazon S3: условные запросы, загрузку большими объёмами, контрольные суммы, чтение части объекта, копирование и массовое удаление. Она нужна разработчику клиентского приложения. Полный перечень операций приведён в таблице Поддерживаемые операции.
Разделы идут в порядке: запись, чтение, копирование, удаление. Каждый раздел содержит описание, пример и перечень особенностей и ограничений. Примеры приведены для AWS CLI; тот же порядок действий воспроизводится любым SDK, работающим по протоколу S3.
Ключи объектов и логическая структура¶
Ключ объекта — произвольная строка.
Символ / в ключе образует логическую структуру директорий: перечисление с
разделителем / возвращает объекты текущего уровня в Contents, а вложенные
уровни — в CommonPrefixes.
aws s3api list-objects-v2 --bucket documents --prefix проекты/ --delimiter /
Перечисление одного уровня не требует обхода всех ключей бакета: строки директорий создаются при записи объекта и удаляются фоновым процессом, когда директория становится пустой.
Префикс служит также единицей разграничения доступа.
Политика бакета с ресурсом
arn:aws:s3:::documents/проекты/* действует на всю вложенную директорию, в том
числе при массовом удалении, где право проверяется
для каждого ключа отдельно.
Метаданные объекта¶
Пользовательские метаданные передаются
заголовками x-amz-meta-* и возвращаются в ответах GET и HEAD.
Сохраняются также заголовки Content-Type, Content-Encoding,
Content-Disposition, Content-Language, Cache-Control и Expires.
aws s3api put-object --bucket documents --key report.pdf --body report.pdf \
--content-type application/pdf \
--metadata 'author=alice,department=finance'
aws s3api head-object --bucket documents --key report.pdf
При копировании метаданные по умолчанию переносятся,
а параметр --metadata-directive REPLACE заменяет их значениями из запроса.
Условная запись объекта¶
Условные заголовки позволяют выполнить запись или чтение, только если объект
находится в ожидаемом состоянии. PutObject принимает два условных заголовка:
| Заголовок | Запись разрешена, если |
|---|---|
If-None-Match: * |
ключа ещё нет |
If-Match: "<etag>" |
текущее содержимое объекта имеет указанный ETag |
На этих двух проверках строятся взаимное исключение и оптимистическое обновление без внешнего координатора.
# Создать, только если ключа нет
aws s3api put-object --bucket documents --key lock --body /dev/null \
--if-none-match '*'
# Второй такой же вызов вернёт PreconditionFailed (412)
# Обновить, только если содержимое не менялось
aws s3api put-object --bucket documents --key state.json --body new.json \
--if-match '"d41d8cd98f00b204e9800998ecf8427e"'
Особенности и ограничения
- Запрос с
If-Matchк отсутствующему ключу возвращаетNoSuchKey(404), а не 412. - Те же два заголовка принимает
CompleteMultipartUpload(см. Составная загрузка).
Условное чтение¶
GetObject и HeadObject поддерживают условные заголовки If-Match,
If-None-Match, If-Modified-Since и If-Unmodified-Since.
| Не выполнено условие | Ответ |
|---|---|
If-Match или If-Unmodified-Since |
412 (PreconditionFailed) |
If-None-Match или If-Modified-Since |
304 (Not Modified) без тела, с заголовком ETag объекта |
Условия проверяются в порядке, который задаёт RFC 9110: сначала If-Match,
затем If-Unmodified-Since, затем If-None-Match и If-Modified-Since. Из
этого следует:
- запрос, для которого не выполнены условия
If-Unmodified-SinceиIf-None-Match, получает ответ 412; - условие
If-Unmodified-Sinceне проверяется, если заданIf-Match; - условие
If-Modified-Sinceне проверяется, если заданIf-None-Match.
Потоковая загрузка¶
Поддерживаются клиенты, которые подписывают тело запроса частями
(Content-Encoding: aws-chunked,
x-amz-content-sha256: STREAMING-AWS4-HMAC-SHA256-PAYLOAD).
Особенности и ограничения
- Тело запроса не накапливается в памяти целиком: данные кодируются и передаются на диски по мере поступления. Поэтому размер объекта ограничен только свободным местом.
Составная загрузка¶
При составной загрузке клиент
передаёт объект частями, а хранилище собирает части в единое целое. Как
правило, клиент выполняет составную загрузку автоматически: aws s3 cp
переходит на неё для файлов больше порога multipart_threshold. Явная
последовательность вызовов:
# 1. Начать загрузку
aws s3api create-multipart-upload --bucket documents --key big.bin
# { "UploadId": "0197f2c1..." }
# 2. Передать части
aws s3api upload-part --bucket documents --key big.bin \
--upload-id 0197f2c1... --part-number 1 --body part1.bin
# { "ETag": "\"9b2c...\"" }
# 3. Собрать объект
aws s3api complete-multipart-upload --bucket documents --key big.bin \
--upload-id 0197f2c1... \
--multipart-upload '{"Parts":[{"PartNumber":1,"ETag":"\"9b2c...\""}]}'
Часть можно взять из существующего объекта, не передавая её по сети:
aws s3api upload-part-copy --bucket documents --key merged.bin \
--upload-id 0197f2c1... --part-number 2 \
--copy-source documents/source.bin --copy-source-range bytes=0-5242879
Незавершённые загрузки можно просмотреть и отменить:
aws s3api list-multipart-uploads --bucket documents
aws s3api list-parts --bucket documents --key big.bin --upload-id 0197f2c1...
aws s3api abort-multipart-upload --bucket documents --key big.bin \
--upload-id 0197f2c1...
Особенности и ограничения
- Номера частей лежат в диапазоне от 1 до 10000.
- Все части, кроме последней, должны иметь размер не менее 5 МиБ, иначе
завершение загрузки возвращает ошибку
EntityTooSmall. ETagсобранного объекта имеет вид"<md5 склеенных md5 частей>-<число частей>"и намеренно не совпадает с MD5 содержимого, как и в Amazon S3.CompleteMultipartUpload, как иPutObject, принимает условные заголовкиIf-MatchиIf-None-Match(см. Условная запись объекта). Условие проверяется в момент публикации собранного объекта.- Незавершённую загрузку, начатую раньше чем
mpu_abort_incomplete_after_sсекунд назад, прерывает фоновый процессmpugc, и её части освобождаются. Параметр задаёт администратор (см. Сервис s3r_storage). Тот же результат даёт правило жизненного циклаAbortIncompleteMultipartUpload.
Контрольные суммы S3¶
Клиент может передать контрольную сумму содержимого при записи и получить её
при чтении. Поддерживаются CRC64/NVME и SHA-256. Значения ChecksumSHA256 и
ChecksumCRC64NVME передаются в кодировке Base64.
sha256=$(openssl dgst -sha256 -binary report.pdf | base64 -w0)
aws s3api put-object --bucket documents --key report.pdf \
--body report.pdf --checksum-sha256 "$sha256"
aws s3api head-object --bucket documents --key report.pdf \
--checksum-mode ENABLED
aws s3api get-object-attributes --bucket documents --key report.pdf \
--object-attributes Checksum
Если переданное значение не совпадает с принятым содержимым, запрос завершается
ответом 400 BadDigest и запись не публикуется.
Когда вычисляется SHA-256¶
При записи всегда вычисляется контрольная сумма CRC64/NVME. Вычисление SHA-256 занимает заметную долю процессорного времени записи, поэтому эта сумма вычисляется, только если для бакета включена дедупликация или клиент запросил её одним из способов:
- передал значение
ChecksumSHA256в запросеPutObjectилиUploadPart, в заголовке или в завершающем заголовке (x-amz-trailer) после тела запроса; - указал алгоритм
SHA256в параметреChecksumAlgorithmзапросаPutObject,UploadPart,CreateMultipartUploadилиCopyObject.
Что возвращается при чтении¶
GetObjectиHeadObjectвозвращают контрольные суммы только приChecksumMode=ENABLEDи только те, которые были вычислены при записи объекта: CRC64/NVME всегда, SHA-256 — при условиях из предыдущего раздела. Так же отвечает Amazon S3.- Ответ на чтение диапазона или части не содержит контрольной суммы всего объекта, потому что содержит только часть его данных.
GetObjectAttributesс атрибутомChecksumвозвращает те же суммы без чтения содержимого.
Объекты из нескольких частей и копии¶
- Составная контрольная сумма SHA-256 возвращается для объекта из нескольких
частей, если загрузка создана запросом
CreateMultipartUploadс алгоритмомSHA256. Тогда SHA-256 вычисляется для каждой части, а составная сумма равна сумме SHA-256 от последовательности двоичных сумм SHA-256 всех частей в кодировке Base64 с суффиксом-<число частей>. - Для загрузки, созданной без алгоритма, контрольная сумма объекта не возвращается.
- Составная сумма CRC64/NVME сейчас не возвращается.
- Копия всего объекта, созданная одним запросом
CopyObjectилиUploadPartCopy, получает контрольные суммы источника. Если копии нужна сумма SHA-256, которой у источника нет, она вычисляется при копировании.
Чтение диапазона¶
GetObject возвращает часть объекта, заданную диапазоном байтов или номером
части.
aws s3api get-object --bucket documents --key big.bin \
--range bytes=1048576-2097151 part.bin
Для объекта, собранного составной загрузкой, диапазон можно задать номером части:
aws s3api get-object --bucket documents --key big.bin --part-number 3 part3.bin
Особенности и ограничения
- Поддерживаются диапазоны вида
bytes=начало-конец,bytes=начало-иbytes=-длина. - Ответ содержит заголовок
Content-Range, а ответ на запрос по номеру части дополнительно содержит заголовокx-amz-mp-parts-count. - С дисков читаются только те части полос, в которые попадает диапазон.
- Ответ не содержит контрольной суммы всего объекта (см. Что возвращается при чтении).
Атрибуты объекта¶
GetObjectAttributes возвращает запрошенные сведения об объекте одним ответом,
без чтения содержимого.
aws s3api get-object-attributes --bucket documents --key big.bin \
--object-attributes ETag ObjectSize StorageClass ObjectParts
Особенности и ограничения
- Для объекта, собранного составной загрузкой, атрибут
ObjectPartsперечисляет части с номерами и размерами и поддерживает постраничный обход с параметрами--max-partsи--part-number-marker. - В отличие от Amazon S3, поле
ETagв ответе этой операции сейчас возвращается в кавычках: так значение представляет используемая библиотека протокола. Для проверки содержимого используйте атрибутChecksum.
Копирование объекта¶
Копия создаётся на стороне сервера, и содержимое объекта по сети не передаётся.
aws s3api copy-object --bucket archive --key report-2026.pdf \
--copy-source documents/report.pdf
Источником может служить конкретная версия объекта:
aws s3api copy-object --bucket archive --key report-old.pdf \
--copy-source 'documents/report.pdf?versionId=0000019874f3a1c2'
Особенности и ограничения
- По умолчанию метаданные копируются (
--metadata-directive COPY). ЗначениеREPLACEзаменяет пользовательские метаданные и тип содержимого значениями из запроса. Аналогично работает параметр--tagging-directiveдля тегов. Другие значения этих параметров отклоняются с ошибкойInvalidArgument. - Для условного копирования используются заголовок
x-amz-copy-source-if-matchи родственные ему заголовки. - Копирование объекта в самого себя допускается только с параметром
--metadata-directive REPLACE, иначе возвращается ошибкаInvalidRequest. - Та же ошибка
InvalidRequestвозвращается, еслиversionIdисточника вCopyObjectилиUploadPartCopyуказывает на маркер удаления. - Контрольные суммы копии описаны в разделе Объекты из нескольких частей и копии.
Проверка владельца бакета¶
Заголовок x-amz-expected-bucket-owner защищает операцию над бакетом, который
пересоздан другим владельцем: при несовпадении владельца сервер возвращает
AccessDenied. Для бакета-источника в CopyObject и UploadPartCopy
применяется заголовок x-amz-source-expected-bucket-owner.
Особенности и ограничения
- В отличие от Amazon S3, ожидаемым значением служит имя пользователя Picodata, которому принадлежит бакет, а не идентификатор учётной записи AWS.
Массовое удаление¶
DeleteObjects удаляет несколько объектов или версий одним запросом.
cat > delete.json <<'EOF'
{"Objects": [{"Key": "a.txt"}, {"Key": "b.txt", "VersionId": "0000019874f3a1c2"}],
"Quiet": false}
EOF
aws s3api delete-objects --bucket documents --delete file://delete.json
Особенности и ограничения
- Один запрос принимает до 1000 ключей.
- Права проверяются для каждого ключа отдельно, поэтому часть ключей в ответе
может оказаться в списке
Deleted, а часть — в спискеErrors.