OpenStack Swift Large Object Support

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

Large Object Support

概述

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

使用swift来分割对象

最快的方式试试这个特性是使用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 直接API

你也可以使用片段和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,大对象支持这个特性会继续的去提升和改变,在之后的时间。

转载于:https://my.oschina.net/zhouxingxing/blog/70435

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值