OpenStack Swift Large Object Support

swift默认下支持上传的文件5G,当遇到大文件的时候该如何处理呢?Large Object Support帮助咱们解决这个问题,一样翻译自官方文档。python

Large Object Supportswift

概述网络

Swift在单一对象上传时有大小的限制;默认下是5GB。然而,如今一个单一对象的大小事实上市没有如今的通用分割的概念。分割上传的大对象,当下载的时候 一个特殊的manifest文件被建立,发送全部的片断连结称一个单独的对象。这一样提供了更快的上传速度在尽量的并行上传片断。并发

使用swift来分割对象curl

最快的方式试试这个特性是使用swift工具包括在python-swiftclinet库。当切分一个大文件时,你可使用-S参数来指定分割的大小,例如:swift upload test_container -S 1073741824 large_file
这将会分割large_file称1G大小的片断,而后并行的上传那些片断。一旦全部的片断上传成功,swift将建立manifest文件为了这些片断能够做为总体被下载。高并发

因此如今,下面的swift 命令将下载整个大对象:swift download test_container large_file
swift 使用严格的公约对于他的分割对象支持。在上面的例子将会上传全部的片断到第二个名为test_container_segments容器。这些片断将会命名如:
large_file/1290206778.25/21474836480/00000000, large_file/1290206778.25/21474836480/00000001, etc.工具

使用单独的容器最好的益处就是主容器的表不会被全部的片断的名字污染。使用格式为<name>/<timestamp>/<size>/<segment>的片断名字的缘由是为了上传一个新的有相同名字的文件时不会重写第一次的内容直到mainfest 文件被上传的那一刻。性能

swift将会帮你管理这些片断文件,删除旧的片断在删除和重写等。你能够重写这个行为用--leave-segments参数若是须要;这个颇有用若是你想要有多个版本的相同的大对象可用。测试


Direct API 直接APIurl

你也可使用片断和manifest目录经过HTTP请求。你能够只是上传片断,manifest文件只是一个0位的文件有一个额外的X-Object-Manifest头。

全部的对象片断须要在同一个容器,有个通用的对象前缀名字,它们的名字安装它们连结的顺序排序。它们不须要和manifest文件在同一个容器。这和上面swift中同样有助于保持容器列表的安静。

manifest文件仅是一个带有额外X-Objetc-Manifest的0字节文件: <container>/<prefix> 头部,<container>是对象片断所在的容器,<prefix>是全部片断通用的前缀。

最好的是先上传全部的片断而后建立或更新manifest。在整个方式下,整个对象是不可下载的直到上传完成。因此,你能够上传一个新的组段到第二个位置,而后更新manifest去指出整个新的位置。在上传新片断期间,起初的manifest会一直可用来下载第一组片断。

这有一个使用curl对微小的1字节片断的例子:

# First, upload the segments
curl -X PUT -H 'X-Auth-Token: <token>' \
    http://<storage_url>/container/myobject/1 --data-binary '1'
curl -X PUT -H 'X-Auth-Token: <token>' \
    http://<storage_url>/container/myobject/2 --data-binary '2'
curl -X PUT -H 'X-Auth-Token: <token>' \
    http://<storage_url>/container/myobject/3 --data-binary '3'

# Next, create the manifest file
curl -X PUT -H 'X-Auth-Token: <token>' \
    -H 'X-Object-Manifest: container/myobject/' \
    http://<storage_url>/container/myobject --data-binary ''

# And now we can download the segments as a single object
curl -H 'X-Auth-Token: <token>' \
    http://<storage_url>/container/myobject

其余的注意事项
1.带有GET或HEAD的manifest文件,X-Object-Manifest:<container>/<prefix>头,将会返回连结的对象为了你能够看到他们的片断是从哪里来的。
2.Content-Length对GET或HEAD的响应在manifest文件将动态的会合计全部的在<container>/<prefix>列表里片断,所以,上传额外的片断在manifest被穿件后将引发连结的对象变的更大;这不须要去从新建立manifest文件。
3.Content-Type对于GET或者HEAD的响应在manifest文件和Content-Tpye在PUT请求时设置的同样,建立manifest。你能够很简单的改变Content-Tpye经过从新发送PUT。
4.ETag对于GET或HEAD的响应在manifest文件 <container>/<prefix>所列的连结的每一个片断的ETags的字符串的MD5的值得动态总和。在swift中Etag经常是对象内容的MD5值得总和,适用于每个独立的片断。可是,他不能生产这样的ETag在manifest本身。因此这个方法被选择来至少提供改变的检测。

注意:若是若是你使用容器的同步特性你须要确保你的manifest文件和你的片断文件是同步是否它们在不停的容器中。

History
大对象支持在这个实现以前有过多个版本。

在swift限制对象的大小的最重要的驱使是维护环中虚节点的平衡。为了维护一个甚至磁盘的分布使用贯穿集群的明显的存储模式是简单的把大对象分红较小的片断,能够再读的时候粘合在一块儿。

在引入大对象支持以前,一些应用已经能够拆分它们的上传成片断,再组装它们在客户端这边在检索单个部分。这项设计被容许客户能够支持备份和归档庞大的数据集,可是也频繁的改善性能或者减小因为网络中断引发的错误。这个办法的主要缺陷是原始的分区方案须要正确的再组装这个对象,对于一些场景来讲是不切实际的,就像CDN源。

为了清除进入客户想要存对象大于5G币的市场的障碍,首先咱们原型化彻底透明的支持上传大对象。一个彻底原型化的实现支持一个更大的最大值经过自动的拆分对象称片断在上传到代理,没有改变客户的API。全部的片断彻底的隐藏在客户的API。

这个解决方案致使了一些具备挑战性的失败条件到集群,不提供可与任何的参数作并行上传,没有从失败中恢复的基础。这种透明化的实现被认为太复杂了对于收益。

当前的"user manifest"设计被选择是为了提供一个透明的下载大对象到客户端,一直提供上传客户一个干净的API来支持分段的上传。

另外一种“显示”user manifest方法被讨论,须要一种预约义的格式的片断列表来“完成”分段式的上传。同时这或许会提供一些潜在的优点,它决定推送一个额外的负载到客户端,这种其中奶的行为限制了应该采用更简单“API”的支持(本质上就是'X-Object-Manifest'头的格式)

在开发期间咱们注意到,这种基于路径前缀的“隐式”user manifest方法可能会被最终的容器列表一致性窗口所影响,理论上会引发一个GET在manifest对象返回一个无效的整个的对象在短时间以内。事实上你未必会遭遇这个情形除非你运行了很是高并发的上传在一个小的运行object-updaters或container-replicators的测试环境。

像全部的swift,大对象支持这个特性会继续的去提高和改变,在以后的时间。

相关文章
相关标签/搜索