物件業務的修改資料介面

jackieathome發表於2024-06-09

依據AWS S3,沒有定義修改資料的操作,修改資料時,均需要重新上傳物件的資料和後設資料。

本文有如下假定:

  • 物件儲存服務基於檔案語義實現。

介面定義

依據前述,業界主流物件儲存服務比如AWS S3並未定義修改物件資料的操作,而國內的各家公有云物件儲存服務,提供了物件的修改物件資料的操作。

國內的公有云物件儲存服務,相關操作的文件的連結(排名不分先後),如下:

  • 華為雲OBS

華為雲OBS修改寫物件為例,介面定義如下:

PUT /ObjectName?modify&position=Position HTTP/1.1
Host: bucketname.obs.region.myhuaweicloud.com
Content-Type: type
Content-Length: length
Authorization: authorization
Date: date
<object Content>

本介面的關鍵引數,如下:

  • 物件名,指定修改資料的物件名。
  • 操作名,引數名為modify,不需要指定引數值。
  • 修改位置,引數名為position,依據實際情況指定。
  • 操作指標,HTTP頭部Content-Length,本次操作修改的資料的長度。

實現思路

修改資料的範圍

對於普通物件,即使用PUT或者複製方式上傳的物件,物件大小的範圍為[1, 5GiB],因此

  • 假如position的位置小於1或者大於5GiB,則校驗失敗。
  • 假如Content-Length的取值小於1或者大於5GiB,則校驗失敗。
  • 假如positionContent-Length的和大於5GiB,則校驗失敗。

對於使用多段方式上傳的物件,涉及的API,如下:

  • CreateMultipartUpload
  • UploadPart
  • UploadPartCopy
  • CompleteMultipartUpload

段的數量上限為10000,每個段大小的範圍為[1, 5GiB],因此物件整體的範圍可到達到[1, 48.8TiB],因此

  • 假如position的位置小於1或者大於48.8TiB,則校驗失敗。
  • 假如Content-Length的取值小於1或者大於48.8TiB,則校驗失敗。
  • 假如positionContent-Length的和大於48.8TiB,則校驗失敗。

物件大小的規格,參見AWS S3文件

ETag

參考AWS S3資料一致性ETag基於物件的資料,使用MD5演算法計算得到。

服務端校驗資料一致的流程

  • 客戶端使用本次上傳的資料,基於MD5演算法計算得到MD5X1
  • 客戶端在請求中附帶的Content-MD5為使用本次資料計算到的MD5X1
  • 物件儲存服務端收到資料後,基於MD5演算法計算得到本次操作的MD5X2
  • 服務端執行MD5X1X2的比較。
    • 二者一致,則判定資料一致,本次寫入操作成功。
    • 二者不一致,則判定資料不一致,本次寫入操作失敗。
  • 服務端在返回的響應中增加ETag欄位,使用服務端計算的MD5X2填充。

客戶端校驗資料一致的流程

  • 客戶端發起請求,並在讀資料、寫資料的過程中,使用本次上傳的資料,基於MD5演算法計算得到MD5X1
  • 物件儲存服務端收到資料後,基於MD5演算法計算得到本次操作的MD5X2
  • 服務端在返回的響應中增加ETag欄位,使用服務端計算的MD5X2填充。
  • 客戶端使用本地計算的X1和服務端返回的ETag進行比較。
    • 二者一致,則判定資料一致,本次寫入操作成功。
    • 二者不一致,則判定資料不一致,本次寫入操作失敗。考慮到服務端已成功寫入,因此需要增加必要的修復措施。

服務端物件的MD5值
由於變更了部分資料,因此物件的ETag值和資料已不一致,需要設計補救方案。

對於普通物件,即使用PUT或者複製方式上傳的物件,考慮在後臺任務中讀取全量資料,計算物件資料的MD5值,儲存至ETag欄位的值儲存下來。

對於使用多段方式上傳的物件,涉及的API,如下:

  • CreateMultipartUpload
  • UploadPart
  • UploadPartCopy
  • CompleteMultipartUpload

依據Checking object integrity的介紹,該類物件的ETag值樣例為C9A5A6878D97B48CC965C1E41859F034-14,由所有的段的MD5值計算得到,因此修復操作相對複雜一些。

  • 依據修改點起始位置positionContent-Length計算涉及變化的段的清單。
  • 依據最新的資料,計算涉及變化的段的MD5值。
  • 使用所有的段的MD5值,按照多段物件的ETag值的生成規則,重新計算,得到最終的結果。

物件儲存服務在實現時,有如下需求:

  • 多段物件的系統後設資料中保留所有的段的清單。
  • 段的後設資料中記錄自身的MD5值,資料的起始位置、段的長度。

多版本

按照AWS S3多版本中的說明,多版本特性的開關作用在桶級,包含如下狀態:

Buckets can be in one of three states:

  • Unversioned (the default)
  • Versioning-enabled
  • Versioning-suspended

介面定義中未提供versionId,因此只支援修改當前版本,不支援修改歷史版本。

分級

參考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:ObjectDataUpdated:Put

併發一致性

依據AWS S3 data consistency model的說明,物件儲存服務提供read-after-write的模型。

當多客戶端對相同物件併發的發起修改資料的操作時,參照檔案語義,提供最終一致性。

相關文章