如下是官方文件中針對後設資料的說明。
After you upload the object, you cannot modify object metadata. The only way to modify object metadata is to make a copy of the object and set the metadata.
物件的後設資料僅在上傳物件時或者複製物件時支援修改,在某些場景下使用不方便,因此提供更新後設資料能力成為一種剛需。
本文有如下假定:
- 物件儲存服務基於檔案語義實現。
介面定義
依據前述,業界主流物件儲存服務比如AWS S3並未定義修改物件後設資料的操作,而國內的各家公有云物件儲存服務,提供了物件的修改物件後設資料的操作。
國內的公有云物件儲存服務,相關操作的文件的連結(排名不分先後),如下:
- 華為雲OBS
- 火山引擎
以華為雲OBS的修改物件後設資料為例,介面定義如下:
PUT /ObjectName?metadata HTTP/1.1
Host: bucketname.obs.region.myhuaweicloud.com
Content-Type: application/xml
Content-Length: length
Authorization: authorization
Date: date
<Optional Additional Header>
<object Content>
本介面的關鍵引數,如下:
- 物件名,指定修改後設資料的物件名。
- 操作名,引數名為
metadata
,不需要指定引數值。 - 物件版本,引數名為
versionId
,依據實際情況指定。 - 操作指標,HTTP頭部
x-obs-metadata-directive
,支援REPLACE_NEW
或REPLACE
。
本介面允許修改的後設資料,比如:
- HTTP協議的標準頭部
Cache-Control
Expires
Content-Encoding
Content-Disposition
Content-Type
Content-Language
- 使用者後設資料
x-obs-website-redirect-location
x-obs-meta-*
- 系統後設資料
x-obs-storage-class
x-obs-expires
考慮到物件的tagging支援修改,因此不需要在本介面中再提供額外的實現。
實現思路
ETag
參考AWS S3資料一致性,ETag
基於物件的資料,使用MD5
演算法計算得到。
修改後設資料的操作不涉及資料的變更,因此無需更新MD5
值。
多版本
按照AWS S3多版本中的說明,多版本特性的開關作用在桶級,包含如下狀態:
Buckets can be in one of three states:
- Unversioned (the default)
- Versioning-enabled
- Versioning-suspended
修改後設資料的操作不涉及資料的變更,因此不涉及物件版本的資料的變更。
分級
參考AWS S3 歸檔和AWS S3 分級中的說明,處於歸檔狀態的物件,需要先取回才能訪問。
顯而易見,此處為了維護物件語義,照顧物件儲存服務的實現,當物件處於歸檔狀態時,不允許更新物件的後設資料。
WORM
參考AWS S3 Object Lock中的說明,開啟WORM後:
- 在保護期內的物件,不允許修改,不允許刪除。
- 在保護期外的物件,不允許修改,允許刪除。
因此從維護物件語義的角度講,在保護期內的物件、保護期外的物件,均不允許修改物件的後設資料。
生命週期
參考AWS S3 Lifecycle,修改後設資料操作的物件可能符合生命週期規則,從而被恰好正在執行的後臺任務刪除掉。
此時有如下選擇:
- 生命週期的後臺任務具備更高的優先順序,提前中斷操作,正常刪除掉物件,物件儲存服務對客戶應用返回操作失敗。
- 生命週期的後臺任務優先順序相對較低,跳過當前物件,待下次執行時再決策是否刪除。
資料加密
依據SSE-C的說明,客戶應用在執行PUT/GET/Head/Copy操作時,均需要提供加密資料的金鑰。
即在發起請求時,提供如下頭部:
x-amz-copy-source-server-side-encryption-customer-algorithm
x-amz-copy-source-server-side-encryption-customer-key
x-amz-copy-source-server-side-encryption-customer-key-MD5
從而加密本次修改的後設資料。
事件通知
依據AWS S3 事件通知中的說明,物件儲存服務可以提供事件通知,目前支援的事件型別見文件,顯然不包括修改後設資料操作,可以擴充套件事件名,比如s3:ObjectMetadataUpdated:Put
。
依據AWS S3 訊息格式,為了適配修改後設資料操作,可以考慮在object中增加擴充套件物件metadata,使用KV格式,用於說明修改後設資料操作。
在官方樣例基礎上增加必要的欄位,得到如下樣例:
{
"Records":[
{
"eventVersion":"2.2",
"eventSource":"aws:s3",
"awsRegion":"us-west-2",
"eventTime":"The time, in ISO-8601 format, for example, 1970-01-01T00:00:00.000Z, when Amazon S3 finished processing the request",
"eventName":"event-type",
"userIdentity":{
"principalId":"Amazon-customer-ID-of-the-user-who-caused-the-event"
},
"requestParameters":{
"sourceIPAddress":"ip-address-where-request-came-from"
},
"responseElements":{
"x-amz-request-id":"Amazon S3 generated request ID",
"x-amz-id-2":"Amazon S3 host that processed the request"
},
"s3":{
"s3SchemaVersion":"1.0",
"configurationId":"ID found in the bucket notification configuration",
"bucket":{
"name":"bucket-name",
"ownerIdentity":{
"principalId":"Amazon-customer-ID-of-the-bucket-owner"
},
"arn":"bucket-ARN"
},
"object":{
"key":"object-key",
"size":"object-size in bytes",
"eTag":"object eTag",
"versionId":"object version if bucket is versioning-enabled, otherwise null",
"sequencer": "a string representation of a hexadecimal value used to determine event sequence, only used with PUTs and DELETEs",
"metadata":[
{
name:"Cache-Control",
value:""
},
{
name:"Expires",
value:""
},
{
name:"Content-Encoding",
value:""
},
{
name:"Content-Disposition",
value:""
},
{
name:"Content-Type",
value:""
},
{
name:"Content-Language",
value:""
}
]
}
}
}
]
}
併發一致性
依據AWS S3 data consistency model的說明,物件儲存服務提供read-after-write
的模型。
當多客戶端對相同物件併發的發起修改後設資料的操作時,以最後一次請求的操作結果為準。