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=/
使用 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