本文標題中提到的檔案語義,指的是POSIX規範。
S3指的是AWS提供的物件儲存服務以及相關介面。為方便描述,下文中以物件語義替代S3介面語義。
檔案語義和物件語義存在比較多的差異。
物件語義不支援檔案語義的部分特性,比如:
- 目錄的操作,建立、刪除、修改名稱。
- 檔案的部分操作,追加寫、隨機寫、修改名稱等。
- 檔案的後設資料,比如:
- 時間欄位,即crtime/ctime/mtime/atime。
- 使用者和組,即uid/gid。
- 許可權,即UGO和ACL。
- 檔案的擴充套件屬性。
- 硬連結。
- 軟連結。
- 鎖。
檔案語義不支援物件語義的部分特性,比如:
- Etag,檔案語義中沒有定義相關資訊。
- 生命週期管理。
- 桶策略。
- 多版本。
- 物件的後設資料,即:
- 系統後設資料,即標準HTTP頭部。
- 使用者自定義後設資料,即命名為
x-amz-meta-*
的HTTP頭部。 - 物件tagging,即命名為
x-amz-tagging
的HTTP頭部。
部分存在差異的語義,比如:
- WORM,檔案語義和物件語義的實現,由於前述差異,具體實現和保護範圍可能存在一定的差異。
- 檔案的建立。依據物件語義,儲存物件的操作是一個原子行為,包含資料、後設資料一併寫入,要麼成功、要麼失敗,只要上傳物件的介面返回了成功,即表示物件建立成功。而依據檔案語義,儲存檔案的操作,涉及開啟、寫入資料、寫入後設資料、關閉檔案等操作,並不是原子行為,寫入資料的過程中可能會被中斷,但由於檔案開啟成功,因此會出現資料不一致的現象。
- 目錄,物件語義對目錄的支援非常有限,而檔案語義則提供了豐富的API。
物件語義中,使用物件來表示客戶的資料,在儲存和管理物件時,放棄了目錄的概念,所有的物件均以展平的形式儲存,在使用檔案語義實現物件語義時,需要對目錄做特殊的處理。
在檔案語義中,/
有特殊含義,表示目錄的分隔符,因此一般不允許在目錄名或者檔名中使用。
而AWS S3定義的規範中,/
是普通字元,允許在物件名中使用。
做個實驗,登入Linux環境的控制檯,執行如下命令,輸出如下:
$ ll a.py
-rw-r--r-- 1 jackie docker 138 3月 29 21:47 a.py
$ mkdir a.py
mkdir: cannot create directory ‘a.py’: File exists
$ mkdir a.py/
mkdir: cannot create directory ‘a.py/’: File exists
依據物件語義,a.py
和a.py/
是不同的物件,但在檔案語義下,a.py
存在,則阻塞目錄a.py
的建立操作。
依據檔案語義,刪除目錄即類似rm -rf /path/to/delete
時,目錄和目錄下的所有的檔案、目錄均會被刪除。
考慮到本操作並不是一個原子操作,因此使用檔案語義實現物件語義的刪除操作時,會有比較多的注意事項。
思考點
- 刪除目錄時,目錄下的物件,需要一併刪除。假如物件數量比較多時,則刪除操作將比較耗時。
- 目錄下假如存在未合併的多段物件,是否一併刪除。
- 目錄下假如僅有一個物件,使用物件語義的刪除介面,將該物件刪除時,目錄是否需要被刪除。
- 先上傳目錄,上傳一個物件至該目錄下,使用物件語義的刪除介面,將該物件刪除時,目錄是否需要被刪除。
- 手工上傳的目錄,在列舉物件時,是否作為一個物件在列舉結果中出現。
- 如前所述,檔案主義並不支援物件主義的Etag,因此在實現上傳物件的操作時,需要計算並保留Etag值。
- 儲存物件的資料的操作,計算MD5值的操作,二者需要保持進度一致,避免MD5值計算結果不正確,或者耗時過久,影響上傳操作的效能。
- Etag儲存的位置。
- 物件後設資料的儲存位置,依據語義,需要和資料一起儲存。
- 後設資料儲存的位置。
- 操作的原子性。
- 物件語義寫入物件時,檔案的後設資料,應當如何填值。如前述,不支援的後設資料,如下:
- 時間欄位,即crtime/ctime/mtime/atime。
- 使用者和組,即uid/gid。
- 許可權,即UGO和ACL。