3.2. Container存儲服務(Storage Container Services)
本節闡述了container上可以執行的ReST操作。所有的操作都是有效的HTTP請求,並被組織成以下格式:
例3.16. Container存儲的HTTP請求:基本結構
METHOD /v1/<account>/<container> HTTP/1.1
3.2.1. 獲取對象列表
對一個container的名稱執行GET操作將會獲取存儲在這個容器中的objects列表。此外,這里有一些可選的查詢參數用於進一步細化查詢結果。
一個不包含任何查詢參數的的請求將會返回存儲在這個容器中的所有對象的列表,列表長度最大為10,000。選擇一些特定的查詢參數可以對查詢結果進行過濾,以獲取存儲對象名稱的一個子集。
| limit | 整數n,指明返回結果只包含n個值 |
| marker | 字符串x,返回名稱比這個特定的字符串x大的對象列表 |
| end_marker | 字符串x,返回名稱比這個特定字符串小的對象列表 |
| prefix | 字符串x,返回名稱以x為開始的對象列表 |
| format | 設定響應的數據格式為json或xml |
| delimiter | 字符c,以x作為分隔符,返回所有被x分隔名稱的對象列表(而不需要用文件夾對objects進行標記分類) |
| path | 字符串x,返回所有在這個偽路徑x下的對象列表。等效於將delimiter設置為'/'並以路徑'/'作為前綴結束 (這個翻譯很晦澀啊,看例子!) |
例3.17. 獲取objects列表的請求
GET /<api version>/<account>/<container>[?parm=value] HTTP/1.1 Host: storage.swiftdrive.com X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
對象列表將包含在返回消息體中,每行一個對象名稱。如果container為空,則將返回一個狀態碼為204(無內容)的空響應消息;如果container不存在,則將返回一個狀態碼為404(不存在)的響應消息;如果指定的account不正確,則也將返回一個狀態碼為404的響應。
例3.18. 獲取objects列表的響應
HTTP/1.1 200 Ok
Date: Thu, 07 Jun 2010 18:50:19 GMT
Server: Apache
Content-Type: text/plain; charset=UTF-8
Content-Length: 171
kate_beckinsale.jpg
How To Win Friends And Influence People.pdf
moms_birthday.jpg
poodle_strut.mov
Disturbed - Down With The Sickness.mp3
army_of_darkness.avi
the_mad.avi
3.2.1.1. 序列化列表輸出
如果在存儲賬號URL后添加一個 format=xml 或 format=json 參數對,則服務端會將objects列表以及其擴展信息以指定的格式進行序列化再返回。除了 ?format-xml|json 以外的參數,都會返回相同的狀態/錯誤碼。以下的例子就是根據相應的格式進行返回的。
例3.19. object詳情請求:JSON
GET /<api version>/<account>/<container>?format=json HTTP/1.1 Host: storage.swiftdrive.com Content-Length: 0 X-Storage-Token: 182f9c0af0e828cfe3281767d29d19f4
例3.20. object詳情響應:JSON
HTTP/1.1 200 OK
Date: Tue, 25 Nov 2008 19:39:13 GMT
Server: Apache
Content-Length: 387
Content-Type: application/json; charset=utf-8
[ {"name":"test_obj_1", "hash":"4281c348eaf83e70ddce0e07221c3d28", "bytes":14, "content_type":"application\/octet-stream", "last_modified":"2009-02-03T05:26:32.612278"}, {"name":"test_obj_2", "hash":"b039efe731ad111bc1b0ef221c3849d0", "bytes":64, "content_type":"application\/octet-stream", "last_modified":"2009-02-03T05:26:32.612278"}, ]
例3.21. object詳情請求:XML
GET /<api version>/<account>/<container>?format=xml HTTP/1.1 Host: storage.swiftdrive.com X-Storage-Token: 182f9c0af0e828cfe3281767d29d19f4
例3.22. object詳情響應:XML
<?xml version="1.0" encoding="UTF-8"?> <container name="test_container_1"> <object> <name>test_object_1</name> <hash>4281c348eaf83e70ddce0e07221c3d28</hash> <bytes>14</bytes> <content_type>application/octet-stream</content_type> <last_modified>2009-02-03T05:26:32.612278</last_modified> </object> <object> <name>test_object_2</name> <hash>b039efe731ad111bc1b0ef221c3849d0</hash> <bytes>64</bytes> <content_type>application/octet-stream</content_type> <last_modified>2009-02-03T05:26:32.612278</last_modified> </object> </container>
3.2.1.2. Objects大列表的控制
OpenStack對象存儲系統每個請求最多可以返回10,000個對象的名字。為了獲取objects名稱列表的子序列,另一個請求必須使用 marker 參數。這個參數表明了列表從哪里結束,系統將會返回所有名稱大於這個marker的object名稱,同時,最多也只能有10,000個。注意,marker的值通過HTTP請求發送時應當是URL-encoded的。
如果我們不需要10,000個那么多的object,我們可以使用 limit 參數。
如果返回的object名稱列表的長度剛好等於limit的值(或當沒有使用limit時,等於10,000),則表明可能還有滿足條件的object名稱沒有返回。
例3.23. 列出很長的objects列表
例如,我們使用一個長度為5的對象名稱列表:
gala
grannysmith
honeycrisp
jonagold
reddelicious
我們將使用limit值為2來表明這是如何工作的:
GET /<api version>/<account>/<container>?limit=2 Host: storage.swiftdrive.com X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
gala
grannysmith
由於我們收到兩個對象名稱(與limit的值相同),因此我們猜測還有更多的objects名稱需要被列出。因此,我們使用marker參數創建另一個請求,marker的值為上一次請求返回的object列表中的最后一個:
GET /<api version>/<account>/<container>?limit=2&marker=grannysmith Host: storage.swiftdrive.com X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
honeycrisp
jonagold
由於又收到了長度為2的object列表,因此可能還有更多的對象名稱:
GET /<api version>/<account>/<container>?limit=2&marker=jonagold Host: storage.swiftdrive.com X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
reddelicious
現在,我們終於收到了長度小於2的object列表,表明沒有更多的object名稱需要被列出了,即已經到達了列表的結尾。
通過使用 end_marker 參數,我們可以限制返回的結果中的object名稱小於給定的值。
GET /<api version><account>/<container>?end_marker=jonagold Host: storage.swiftdrive.com X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
gala
grannysmith
honeycrisp
3.2.1.3. 偽層次的文件夾目錄(Pseudo-Hierarchical Folders/Directories)
即使在OpenStack對象存儲系統中不可以使用嵌套的目錄,但是你可以通過在對象名中添加符號'/',從而在一個容器中模擬出一個層次的結構。為了在偽目錄中導航,你可以使用查詢參數 delimiter。具體請參見以下例子中的描述。
注意:
在以下的例子中,對象所存儲的容器名稱為backups。在這個容器中,對象被阻止在一個成為photos的偽目錄中。請記住,容器的名稱不會展示在例子中,但他是請求的對象URL中的一部分。例如,圖片me.jpg的URL是https://storage.swiftdrive.com/v1/CF_xer7_343/backups/photos/me.jpg.
例3.24. 偽層次的文件夾/目錄
為了獲取container中的所有對象列表,我們需要使用一個沒有 delimiter 或 prefix 參數的GET請求。
GET /v1/AccountString/backups
OpenStack對象存儲系統撿回返回狀態碼為200(OK)的響應,並包含請求的對象列表。
photos/animals/cats/persian.jpg
photos/animals/cats/siamese.jpg
photos/animals/dogs/corgi.jpg
photos/animals/dogs/poodle.jpg
photos/animals/dogs/terrier.jpg
photos/me.jpg
photos/plants/fern.jpg
photos/plants/rose.jpg
使用 delimiter 參數來限制返回的結果。任何一個字符都可以作為一個delimiter(分隔符)。然而,當使用 delimiter 實現為目錄時,我們使用斜杠(/)來作為分隔符。
GET /v1/AccountString/backups?delimiter=/
系統將會返回一個狀態碼為200(OK)的響應消息,並包含匹配的對象。由於我們只是用了斜杠,因此只有偽目錄“photos/”返回。請記住,使用 delimiter 查詢返回的值並非真正的對象。他們擁有一個application/directory的content-type,並且作為json或xml的子節點返回。(YUKI注:實測1.7.6后發現,該部分描述並不正確,偽目錄返回的結點實際上只包含一個元素 subdir,json格式例如:
[
{"hash": "0d2fabedd383dda4ae3ac3364c02de5b", "last_modified": "2013-01-22T07:34:28.271480", "bytes": 4096, "name": "99", "content_type": "application/octet-stream"},
{"subdir": "docs/"}
]
解釋完畢。)
photos/
同時使用 prefix 參數和 delimiter 參數可以查看一個偽目錄中的對象,包含進一步嵌套的偽目錄。
GET /v1/AccountString/backups?prefix=photos/&delimiter=/
系統將會返回一個狀態碼為200(OK)的響應消息,並包含頂級偽目錄中的對象和偽目錄列表。
photos/animals/
photos/me.jpg
photos/plants/
關於創建多少個嵌套的偽目錄是沒有數量限制的(YUKI注:但是對象名稱長度是不能多於1024個字節的,因此並不是可以創建無限多個嵌套偽目錄)。為了在偽目錄中導航,我們需要同時使用一個較長的 prefix 參數和 delimiter 參數。在以下例子中,在偽目錄animals中還存在一個名為dogs的偽目錄。為了直接訪問到dogs偽目錄下的對象,我們需要輸入如下命令:
GET /v1/AccountString/backups?prefix=photos/animals/dogs/&delimiter=/
系統將會返回一個狀態碼為200(OK)的響應消息,並包含dogs偽目錄中的對象和偽目錄列表。
photos/animals/dogs/corgi.jpg
photos/animals/dogs/poodle.jpg
photos/animals/dogs/terrier.jpg
3.2.2. 創建容器
對一個容器名稱使用PUT操作可以完成容器的創建。
Containers是你所存儲的數據的車廂(compartments)。經過URL編碼的名稱不能大於256字節,並且在容器名稱中不可以包含'/'字符。
我們可以使用PUT請求和額外的HTTP頭來為容器關聯自定義的元數據信息。這些關聯容器元數據的HTTP頭的命名格式必須以 X-Container-Meta- 作為開頭。
例3.25. 創建Container的請求
PUT /<api version>/<account>/<container> HTTP/1.1 Host: storage.swiftdrive.com X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
一個沒有內容的響應消息將會被返回。狀態碼201(Created)表明容器已經按照請求被成功創建;當該容器已經存在時,響應消息的狀態碼為202(Accepted)。如果你的PUT請求中包含了以 X-Container-Meta- 為前綴的頭信息時,你將會在后續的GET/HEAD請求的響應中獲取相關的元數據前綴。
例3.26. 創建Container的響應
HTTP/1.1 201 Created
Date: Thu, 07 Jun 2007 18:50:19 GMT
Server: Apache
Content-Type: text/plain; charset=UTF-8
使用自定義的容器元數據可以幫助你高效的為容器打一個“tag”。container的元數據約束和object的元數據約束相同:總的元數據信息最多為4096個字節,每個container最多可以擁有90個不同的元數據項。每一個元數據項可以擁有最長128個字節的名稱和256個字節的值。任何有效的UTF-8編碼的HTTP header值都是允許的,但我們建議您使用URL編碼,任何使用%的非ASCII值的字符都需要跟在兩位十六進制的數值后,以表示該字符為ISO-Latin編碼的。
例3.27. 使用元數據創建Container的響應
PUT /<api version>/<account>/<container> HTTP/1.1 Host: storage.clouddrive.com X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb X-Container-Meta-InspectedBy: JackWolf
一個沒有內容的響應消息將會被返回。狀態碼201(Created)表明容器已經按照請求被成功創建;當該容器已經存在時,響應消息的狀態碼為202(Accepted)。如果你的PUT請求中包含了以 X-Container-Meta- 為前綴的頭信息時,你將會在后續的GET/HEAD請求的響應中獲取相關的元數據前綴。
例3.28. 創建Container的響應
HTTP/1.1 201 Created
Date: Thu, 07 Jun 2007 18:50:19 GMT
Server: Apache
Content-Type: text/plain; charset=UTF-8
3.2.3. 刪除容器
在一個容器上執行DELETE操作可以將其永久的刪除。需要說明的是,這個容器必須是空的才能被刪除。
一個針對容器的HEAD請求可以用來判斷該容器是否還包含對象。
例3.29. 刪除Container的請求
DELETE /<api version>/<account>/<container> HTTP/1.1 Host: storage.swiftdrive.com X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
一個沒有內容的響應消息將會被返回。狀態碼204(No Content)表明容器已經被成功刪除了;狀態碼404(Not Found)表明該容器不存在;狀態碼409(Conflict)表明請求刪除的容器不是空的,不能刪除。
例3.30. 刪除Container的響應
HTTP/1.1 204 No Content
Date: Thu, 07 Jun 2010 18:57:07 GMT
Server: Apache
Content-Length: 0
Content-Type: text/plain; charset=UTF-8
3.2.4. 獲取容器元數據
在一個container上使用HEAD操作可以獲取這個容器下的objects數量以及總存儲字節。由於swift是為存儲海量數據而設計的,因此在使用integer類型存儲賬號總使用字節時應當格外小心,如果你的平台支持的話,可以將其轉換為64位的無符號整型。
例3.31. 獲取Container元數據的請求
HEAD /<api version>/<account>/<container> HTTP/1.1 Host: storage.swiftdrive.com X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
如果容器存在,將會返回狀態碼為204(No Content)的響應。如果請求的容器不存在,將會返回狀態碼為404(Not Found)的響應。響應頭中的 X-Container-Object-Count 和 X-Container-Bytes-Used 分別表明該容器中的對象數量和使用空間。
例3.32. 獲取Container元數據的響應
HTTP/1.1 204 No Content
Date: Wed, 11 Jul 2010 19:37:41 GMT
Content-type: text/html
X-Container-Object-Count: 7
X-Container-Bytes-Used: 413
X-Container-Meta-InspectedBy: JackWolf
3.2.5. 創建/更新容器元數據
你可以為容器創建任何有用的自定義元數據信息,這些頭必須以 X-Container-Meta-* 的格式定義。
如果你想創建或更新一個容器的元數據頭信息,則需要使用POST查詢。后續請求中的相同可以的key/value對將會覆蓋之前的值。
例3.33. 更新Container元數據的請求
POST /<api version>/<account>/<container>/ HTTP/1.1 Host: storage.clouddrive.com X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb X-Container-Meta-Book: MobyDick X-Container-Meta-Subject: Whaling
一個沒有內容的響應消息將會被返回。狀態碼204(No Content)表明容器的元數據已經被成功更新了;狀態碼404(Not Found)表明該容器不存在。
例3.34. 更新Container元數據的響應
HTTP/1.1 204 No Content
Date: Thu, 07 Mar 2012 20:42:51 GMT
Server: Apache
Content-Length: 0
Content-Type: text/plain; charset=UTF-8
為了確認元數據確實已經被更新了,你可以在該container上執行一個HEAD請求。注意,不要在你的HEAD請求中包含任何元數據。
例3.35. 查看Container元數據的請求
HEAD /<api version>/<account>/<container>/<object> HTTP/1.1 Host: storage.clouddrive.com X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
例3.36. 查看Container元數據的響應
HTTP/1.1 204 No Content
X-Container-Object-Count: 0
X-Trans-Id: tx028b40d228534c759f4d5fa69f8cf7fd
X-Container-Meta-Book: MobyDick
X-Container-Meta-Subject: Whaling
Accept-Ranges: bytes
Date: Mon, 12 Mar 2012 16:40:20 GMT
Content-Length: 0
X-Container-Bytes-Used: 0
3.2.6. 刪除容器元數據
為了刪除容器的一個元數據,我們需要使用那個特定的頭信息發送一個值為空的POST請求,例如X-Container-Meta-Book: 。
如果你所使用的與swift進行交互的工具不支持發送包含headers值為空的請求(例如較老版本的curl),則你可以發送頭為“X-Remove-Container-Meta-name: 任意值”的請求,例如:X-Remove-Container-Meta-Book: x。這個值將會被忽略。
例3.37. 刪除Container元數據的請求
POST /<api version>/<account>/<container> HTTP/1.1 Host: storage.clouddrive.com X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb X-Remove-Container-Meta-Book: x
這個請求將不會有包含消息體的響應返回,一個狀態碼為204的無內容響應表明刪除成功。
3.2 關於Container的API操作就已經翻完了,依舊很爛-。-,也將前一篇最后與本節相關的內容遷移過來了。下一節想翻3.4關於Object的操作,3.3 Create Static Website就放到最后吧=D
