对于任何的线上资源来说资料管理是一个关键且具挑战的层面, 随着丰富媒体成指数成长的资料量跟普及,即使是小的线上资源也必须有效地管理跟分散大量资料,另外,对每一个参与的人来说跟异地资料储存有关的内心平静是无价的。
在SundayMorningRides.com,我们管理一个成长中的GPS库存以及给直接用户的一般的GIS(地理资讯系统)资料和网页内容(文字、影像、视讯等),除此之外,我们还必须有效地管理日常的网站快照、备份以及网站和支援软体的多个开发版本,对于任何小型组织,这些工作将显著地增加成本,不仅仅是最初的货币投资,还包括持续的管理和维护人力成本。
Amazon Simple Storage Service(简称S3)就针对为解决上述线上资源的资料管理问题而应运而生,其目标是提供“可靠、快速、廉价的资料存储架构”– Amazon就是用S3来支援它全球站点的运行,“Amazon S3提供的网路服务介面允许开发者存储和读取任意大小的资料,S3对于SundayMorningRides之类的公司具有相当的吸引力,因为它使我们从前期成本和购买、管理、维护以及伺服器扩充的持续性成本这两个问题获得解决。”
这篇文章涉及到 Perl、REST模组以及Amazon S3 REST模组,整个过程透过开发一组在Unix命令列环境下执行的Perl工具与Amazon S3进行互动来实做,我另外会展示如何设定存取权限,以便于你可以直接从站点引用存储在Amazon S3上的影像和其他资料服务。
网路服务简介
网络服务(Web services) 已经成为一种发布资讯的重要渠道(method of exposing information ),或者说是建立在Web上的一种服务( services via the Web)。本质上说,Web服务提供了两个连接网路之间资源的沟通。Amazon S3 可以透过Simple Object Access Protocol(简单物件存取协定,SOAP)和representational state transfer (表象化状态转变,REST)来存取。
SOAP 介面透过组合各种特性(organizes features )生成定制操作(custom-built operations),跟使用Java Remote Methond Invocation和Common Object Resource Broker Architecture (CORBA)一样,远程对物件(Objects)进行操作。不同于RMI和CORBA,SOAP使用HTTP请求中嵌入的XML作为应用程序的通讯协定。
和SOAP类似,REST同样使用HTTP协定进行传输。不同于SOAP,REST的操作遵循HTTP标准操作—GET、POST、PUT和 DELETE。我想把REST的操作用跟关联资料库相关的CRUD与一来措词:POST是新增(Create)、GET是读取(Retrieve)、PUT是更新 (Update),而DELETE是删除。※ok!※
关于Internet存贮
Amazon S3 用三个核心概念来阐述资料空间:物件(objects)、容器(buckets)、关键字(keys) 。
. 物件(objects)是在Amazon S3中最基础的实体单位,他们由物件(objects)资料和中介资料(metadata)组成,这里的中介资料就是一组已经定义在HTTP标头文件内的属性值(name-attribute pairs)。
. 容器(buckets)内包含多种物件(objects),容器(buckets)内没有物件数量的限制,但是每个开发者最多只能拥有100个容器(buckets)。
. 关键字(keys)是识别物件(objects)的唯一标志。
为了避免在以上各种概念中纠缠不清,我比较喜欢这样的类比:容器(buckets)等同于资料夹、物件(objects)对应于档案而关键字(keys)看作是档名,这个抽象概念的目的就是要为每个物件创建一个独特的HTTP命名空间。
我假定你已经在Amazon S3中注册,并且收到了Access Key ID和Secret Access Key,如果还没有,那请完成这些工作。
请注意:S3::*模组并不是唯一可以连接Amazon S3的perl模组,特别的是,Net::Amazon::S3模组隐藏了S3服务中的大部分细节,现在,我将使用一个相对简单的模组来解释S3内部是如何工作的。
连接、创建、显示容器(buckets)
连接到Amazon S3很简单,只要提供你的Access Key ID和Secret Access Key就可以建立一个连接,在这里我们叫做$conn,接下来讲解如何建立容器(buckets),显示容器(buckets)中的内容以及所有的容器列表。
#!/usr/bin/perl
use S3::AWSAuthConnection;
use S3::QueryStringAuthGenerator;
use Data::Dumper;
my $AWS_ACCESS_KEY_ID = ‘YOUR ACCESS KEY’;
my $AWS_SECRET_ACCESS_KEY = ‘YOUR SECRET KEY’;
my $conn = S3::AWSAuthConnection->new($AWS_ACCESS_KEY_ID,
$AWS_SECRET_ACCESS_KEY);
my $BUCKET = "foo";#注意不要再使用这个名字,ㄚ琪改用achifoo
print "creating bucket $BUCKET \n";
print $conn->create_bucket($BUCKET)->message, "\n";
print "listing bucket $BUCKET \n";
print Dumper @{$conn->list_bucket($BUCKET)->entries}, "\n";
print "listing all my buckets \n";
print Dumper @{$conn->list_all_my_buckets()->entries}, "\n";
因为每个S3的动作都是透过HTTP来产生,所以检查是否有200回应是很好的作法。
my $response = $conn->create_bucket($BUCKET);
if ($response->http_response->code == 200) {
# Good
} else {
# Not Good
}
正如你在输出中看到的:结果返回一个hash值。我用 Data::Dumper模组作为显示Bucket内容的工具。如果你是第一次运行这个,你在Bucket里面当然什么也看不到。
listing bucket foo
$VAR1 = {
‘Owner’ => {
‘ID’ => ‘xxxxx’,
‘DisplayName’ => ‘xxxxx’
},
‘Size’ => ‘66810’,
‘ETag’ => ‘"xxxxx"’,
‘StorageClass’ => ‘STANDARD’,
‘Key’ => ‘key’,
‘LastModified’ => ‘2007-12-18T22:08:09.000Z’
};
$VAR4 = ‘
‘;
listing all my buckets
$VAR1 = {
‘CreationDate’ => ‘2007-11-28T17:31:48.000Z’,
‘Name’ => ‘foo’
};
‘;
ㄚ琪的测试结果:
撰写物件(objects)
用HTTP PUT方法能快速地撰写一个物件(objects),不过要注意的是:没有任何提示或者预防手段可以预防覆盖一个已经存在的物件(objects),Amazon S3会自动更新那个写入最频繁的物件(objects),此外,它目前还不能追加(append)或者修改(modify)单个物件(objects),只能通过替代的方式来达到追加(append)或者修改(modify)的单个物件(objects)。
my %headers = (
‘Content-Type’ => ‘text/plain’
);
$response = $conn->put( $BUCKET, $KEY, S3Object->new("this is a test"),
\%headers);
同样,你可以从STDIN读取一个档案:
my %headers;
FILE: while(1) {
my $n = sysread(STDIN, $data, 1024 * 1024, length($data));
if ($n < 0) {
print STDERR "Error reading input: $!\n";
exit 1;
}
last FILE if $n == 0;
}
$response = $conn->put("$BUCKET", "$KEY", $data, \%headers);
要新增订制的中介资料,只要新增到S3Object:
S3Object->new("this is a test", { name => "attribute" })
预设情况下,每一
个物件在写入时需要私有权限(private access control),私有权限(private access control)只允许该物件(objects)的所有者读取,你可以改变这些权限设定,另外,要注意到每一个物件可以拥有最多5GB的资料。
你可能也想知道S3是否也可以透过标准的HTTP POST的方法上传,那些在Amazon工作的同仁们正在努力达到这个目标—见HTTP POST beta discussioneta discussion)有更多的资讯,在他们完成这个目标之前,我们还只能透过中间服务器进行网页的形式上传。
读取物件(objects)
和创建物件类似,同样有多种方法可以从Amazon S3中读取资料,一种方法是生成一个临时的URL,用你喜欢的客户端(比如,wget或者Curl)或甚至是一个浏览器拜访这个临时的URL来显示和读取物件(objects)的内容,你要做的全部事情就是生成URL,然后用它来呼叫REST。
my $generator = S3::QueryStringAuthGenerator->new($AWS_ACCESS_KEY_ID,
$AWS_SECRET_ACCESS_KEY);
…然后执行一个简单的HTTP GET方法请求,如果你想要做的只是暂时查看或验证资料,这是一个很棒的技巧。
$generator->expires_in(60);
my $url = $generator->get($BUCKET, "$KEY");
print "$url \n";
你也可以用程式从最初的连接直接读取资料,如果你必须执行额外的处理资料时,这很方便。
my $response = $conn->get("$BUCKET", "$KEY");
my $data = $response->object->data;
另一个酷功能就是可以使用BitTorrent的功能从Amazon S3下载档案,你可以透过BitTorrent存取任何匿名访问权限的物件。
删除物件(Objects)
现在,可能在创建物件(Objects)过程中出错,或者卡死,那么你可能需要在某些时候删除原来建构的物件(Objects)。
$conn->delete("$BUCKET", "$KEY");
设定访问权限和发布到网站
如果你已经注意到先前的例子,所有的Amazon S3 物件(objects)都是通过HTTP来存取,这样的情况使得Amazon S3像线上的文件仓库一样特别有用,尤其是它对于管理和服务站点的多媒体方面特别有用,你几乎可以把Amazon S3服务看做是站点上一个迷你的内容传递网路(Content Delivery Network)多媒体,以下的例子说明如何建立一个简单的从Amazon S3动态引用图片构成的网页。
首先,上传图片并且设置ACL权限为公开(public)状态,我已经修改了前面的例子只有一点不同,要使物件能够被公开读取,需要把Header中 x-amz-acl设为public-read。
my %headers = (
‘x-amz-acl’ => ‘public-read’,
);
另外ACL的权限还包括:
. 私有(预设) (private)
. 公开读取(public-read)
. 公开读写(public-read-write)
. 授权读取(authenticated-read)
现在你已经对上述的指令码娴熟于胸,通过对这些指令码的整合,可以编写一个能够自动在网页上显示所有在容器(Bucket)内的图片的指令码。(你可能对格式会有一些美化排版的处理)
…
my $BUCKET = "foobar";
my $response = $conn->list_bucket("$BUCKET");
for my $entry (@{$response->entries}) {
my $public_url = $generator->get($BUCKET, $entry->{Key});
my ($url, undef) = split (/\?/, $public_url);
$images .= "";
}
($webpage = <<"WEBPAGE");
$images
WEBPAGE
print $q->header();
print $webpage;
如果要向该页面添加图片,只需要上传的图片到对应的容器(Bucket),之后这些图片会自动在你下次重新整理页面的时候显示。
从网页引用多媒体文件同样是易如反掌,如果你观察这个例子生成的HTML,你会看见Amazon S3 URLs 拥有一个基本的格式:http://bucketname.s3.amazon.com/objectname ,另外,请注意:你的容器(Buckets) 的命名空间(namespace)是和其他Amazon S3 用户共享的。
结论
Amazon S3是一个强大的工具,它可以透过提供廉价和无限的存储空间帮助各种规模的组织进行资料管理,对于个人使用来说,它是一个非常好的备份工具(对于组织来说也是)和一般的档案存贮,它也是一个优秀的协作工具,免去到处群发邮件的麻烦,只需要上传一个档案,并且设定合理的存取控制,就能进行有效的协作了。—再也不用纠缠于10MB附件大小之类的限制!
在SundayMorningRides.com ,我们用S3作为我们网站服务架构的一部分,来减少我们提供多媒体服务时候的硬体负载。
当和其他Amazon Web Service,比如SimpleDB(用于结构化的资料查询),Elastic Compute Cloud(用于资料处理)等等结合的时候,他们的组合往往能为网站提供计算和资料管理的低成本解决方案。