Amazon Simple Storage Service (S3) 是一个公开的服务,Web 应用程序开发人员可以使用它存储数字资产,包括图片、视频、音乐和文档。 S3 提供一个 RESTful API 以编程方式实现与该服务的交互。通过本文,您将了解如何使用开源的 JetS3t 库利用 Amazon 的 S3 云服务存储和检索数据。


简介

云是一个抽象的概念,表示松散连接在一起的计算机组,这些计算机共同执行某项任务或者服务,就像是使用一个单独的实体完成一样。此概念背后的架构也很抽象:每个云提供者都可以根据各自情况随意设计它的产品。软件即服务(Software as a Service,SaaS)是一个与云相关的概念,表示云向用户提供某种服务。云模型可以降低用户成本,因为他们无需购买软件和硬件也可以运行 — 服务提供者已经为用户提供了必要的组件。

云计算简介

尽管云计算这一术语并不新鲜(Amazon 在 2006 年就开始提供它的云服务),但从 2008 年起它才开始真正成为流行词,这期间,Google 和 Amazon 的云服务逐渐获得了公众的关注。 Google 的 App Engine 使用户能够在 Google 基础设施上构建和托管 Web 应用程序。连同 S3,Amazon Web Services 还包括 Elastic Cloud Compute (EC2) 计算 Web 服务,该服务可以在 Amazon 的基础设施上托管应用程序。其他公司也开始蠢蠢欲动,准备与 Amazon 和 Google 一决高下,其中就包括 Microsoft®的 Azure,甚至 Sun Microsystems(其云计算还没有正式推向市场)也想分一杯羹。 IBM® 最近宣布,它将提供 某些产品 供开发人员在 Amazon EC2 环境中使用。

以 Amazon 的 S3 产品为例。顾名思义,这是一个公开的服务,使 Web 开发人员能够存储数字资产(如图片、视频、音乐和文档等),以便在应用程序中使用。使用 S3 时,它就像一个位于 Internet 的机器,有一个包含数字资产的硬盘驱动。实际上,它涉及到许多机器(位于各个地理位置),其中包含数字资产(或者数字资产的某些部分)。 Amazon 还处理所有复杂的服务请求,可以存储数据并检索数据。您只需要付少量的费用(大约每月 15 美分 /GB)就可以在 Amazon 的服务器上存储数据,1 美元即可通过 Amazon 服务器传输数据。

Amazon 的 S3 服务没有重复开发,它公开了 RESTful API,使您能够使用任何支持 HTTP 通信的语言访问 S3 。 JetS3t 项目是一个开源 Java 库,可以抽象出使用 S3 的 RESTful API 的细节,将 API 公开为常见的 Java 方法和类。编写的代码越少越好,难道不是吗?充分利用其他人的成果也是不错的。在本文中您将看到,JetS3t 使 S3 和 Java 语言的工作变得更加简单,从根本上提高了效率。

S3 概述

理论上,S3 是一个全球存储区域网络 (SAN),它表现为一个超大的硬盘,您可以在其中存储和检索数字资产。但是,从技术上讲,Amazon 的架构有一些不同。您通过 S3 存储和检索的资产被称为对象。对象存储在存储段(bucket)中。您可以用硬盘进行类比:对象就像是文件,存储段就像是文件夹(或目录)。与硬盘一样,对象和存储段也可以通过统一资源标识符(Uniform Resource Identifier,URI)查找。

例如,在我的硬盘中,我有一个名为 whitepaper.pdf 的文件,它位于主目录中名为 documents 的文件夹中。相应的,该 pdf 文件的 URI 为 /home/aglover/documents/whitepaper.pdf 。在 S3 中,URI 有一点不同。首先,存储段只能是顶级的 — 无法像嵌套硬盘中的文件夹(或目录)一样进行嵌套。其次,存储段必须遵循 Internet 命名法则;句点旁边没有斜杠,名称不包括下划线等等。最后,由于存储段名称已经是 Amazon 域内的 (s3.amazonaws.com) 公共 URI 的一部分,存储段名称必须在所有 S3 中是惟一的。(好消息是每个帐户只能包含 100 个存储段,因此不用担心别人占用了所有的好名字)。

DNS 魔术

不用担心 S3 资产的 URL 。通过 Domain Name System (DNS) 和 CNAME(canonical name的缩写)记录,您可以将自定义程度更高的 URL 映射到 S3 的 URL 。这样一来,您就隐藏了您(或您的应用程序)依赖 S3 的事实!

存储段在 S3 中是 URI 的根。也就是说,存储段的名称将是指向 S3 中某个对象的 URI 的一部分。例如,如果我有一个名为 agdocs 的存储段以及一个名为 whitepaper.pdf 的对象,URI 将是:http://agdocs.s3.amazonaws.com/whitepaper.pdf 。

S3 还提供了指定存储段和对象的所有者和权限的能力,就像对待硬件的文件和文件夹一样。在 S3 中定义对象或存储段时,您可以指定一个访问控制策略,注明谁可以访问您的 S3 资产以及如何访问(例如,读和写权限)。相应地,您可以通过许多方式提供对您的对象的访问,使用 RESTful API 只是其中一种。

开始使用 S3 和 JetS3t

要开始使用 S3,您需要一个帐户。 S3 不是免费的,因此在创建帐户时您必须向 Amazon 提供一种支付手段(比如信用卡号码)。不用担心 — 不收初装费;您只需要为使用付费。对于本文的示例,只需要支付不到 1 美元的费用。

在创建帐户的过程中,您还需要创建凭据:访问密钥和秘密密钥(就像用户名和密码)。(您还可以获取 x.509 证书;但是,只有在使用 Amazon 的 SOAP API 时才需要使用该证书)。和任何访问信息一样,都必须保管好您的秘密密钥。因为任何人使用您的凭据访问 S3 时,您都将为此付费。因此,每当创建存储段或对象时,默认的行为是让所有内容都私有;您必须显式获取对外部世界的访问。

有了访问密钥和秘密密钥,您可以下载 JetS3t并使用它通过 RESTful API 与 S3 交互。

使用编程手段通过 JetS3t 登录 S3 可以分为两步。首先,必须创建一个 AWSCredentials 对象,然后将它传递到 S3Service 对象。AWSCredentials 对象非常简单。它将访问密钥和秘密密钥视为 String。S3Service 对象实际上是一个接口类型。因为 S3 同时提供 RESTful API 和一个 SOAP API,JetS3t 库可以提供两种实现类型:RestS3Service 和 SoapS3Service。就本文而言(包括大部分 S3 事务),RESTful API 的简洁性让它成为一个很好的选择。

创建一个连接的 RestS3Service 实例很简单,如清单 1 所示:

清单 1. 创建一个 JetS3t 的 RestS3Service 实例

def awsAccessKey = “blahblah”
def awsSecretKey = “blah-blah”
def awsCredentials = new AWSCredentials(awsAccessKey, awsSecretKey)

def s3Service = new RestS3Service(awsCredentials)

现在可以执行一些有趣的操作了:例如,创建存储段、添加一个影片,然后获取一个有时间限制的 URL 。实际上,这听起来像一个业务流程,不是吗?这是一个与发布有限资产(比如影片)有关的业务流程。

创建存储段

对于虚构的电影业务,我将创建一个称为 bc50i 的存储段。借助 JetS3t,该流程很简单。通过 S3Service 类型,您有几个选项。我更喜欢使用 getOrCreateBucket 调用,如清单 2 所示。顾名思义,调用该方法可能返回一个存储段实例(表示为 S3Bucket 类型的实例)或在 S3 中创建代码段。

清单 2. 在 S3 服务器上创建存储段

def bucket = s3Service.getOrCreateBucket(“bc50i”)

不要被我这个简单的代码示例所蒙蔽。 JetS3t 库的扩展性非常强。例如,您可以快速确定拥有多少存储段 —— 只需通过 listAllBuckets 调用请求一个 S3Service 实例即可。该方法返回一个 S3Bucket 实例数组。对于任何存储段实例,您可以询问它的名称和创建日期。更重要的是,您可以通过 JetS3t 的 AccessControlList 类型控制与之相关的权限。例如,我可以获取 bc50i 存储段实例,并允许任何人可以公开读取和编写,如清单 3 所示:

清单 3. 修改存储段的访问控制列表

def bucket.acl = AccessControlList.REST_CANNED_PUBLIC_READ_WRITE

当然,通过 API,您也可以随意删除存储段。 Amazon 甚至允许您指定创建存储段的地理位置。 Amazon 简化了存储实际数据的复杂性,但是您可以告诉 Amazon 要将存储段(及其内部所有的对象)放在美国或欧洲(当前可用选项)。

向存储段添加对象

使用 JetS3t 的 API 创建 S3 对象就像操作存储段一样简单。 JetS3t 库也很智能,可以负责处理与 S3 存储段内文件相关的内容类型。例如,我想向 S3 上传一段影片 nerfwars2.mp4,以便用户能够在有限的时间内观看。创建一个 S3 对象与创建常见的 java.io.File 类型一样简单,并能将 S3Object 类型与存储段关联,如清单 4 所示:

清单 4. 创建一个 S3 对象

def s3obj = new S3Object(bucket, new File(“/path/to/nerfwars2.mp4”))

使用文件和存储段初始化 S3Object 之后,要做的所有事情就是通过 putObject 方法上传,如清单 5 所示:

清单 5. 上传影片

s3Service.putObject(bucket, s3obj)

使用清单 5 可以完成上传。现在影片位于 Amazon 服务器了,影片的键就是它的名称。当然,您可以根据需要重写该名称以调用其他对象。实际上,JetS3t API(以及 Amazon S3 RESTful API)公开了许多信息,供您创建对象时使用。我们知道,您还可以提供访问控制列表。 S3 中的任何对象都可以保存 API 允许您创建的其他元数据。之后可以通过该元数据的 S3 API(以及派生的 JetS3t)查询任何对象。

创建对象的 URL

到现在为止,我的 S3 实例有一个包含影片的存储段。实际上,我的影片可以通过以下 URI 获取:http://bc50i.s3.amazonaws.com/nerfwars2.mp4 。但是,只有我才能获取。(在本例中,我只能通过编程方式访问它,因为与所有内容关联的默认访问控制被设置为拒绝任何未授权访问)。我的目的是为选择的用户提供一种方式查看新影片(在有限的时间内),直到我开始收取访问费用(S3 也会提供帮助)。

图 1 展示了默认的访问控制。返回的 XML 文档(相应地显示在我的浏览器中)告诉我对当前资产的访问被拒绝(http://bc50i.s3.amazonaws.com/nerfwars2.mp4)。

图 1. Amazon 的安全机制

创建一个公共 URL 是 S3 提供的一个便捷功能;实际上,使用 S3,您可以创建一个公共 URL,但只在一段时间内有效(例如,24 小时内)。对于我刚刚存储在 S3 服务器上的影片,我将创建一个 48 小时内有效的 URL 。然后我将向选定的用户提供该 URL,以便他们下载并观看(假定他们在两天内下载)。

要创建一个针对 S3 对象的时间敏感型 URL,您可以使用 JetS3t 的 createSignedGetUrl 方法,这是一个 S3Service 类型的静态方法。该方法采用一个存储段名称、一个对象键(在本例中是影片名,还记得吗?)、一些凭证(以 JetS3t 的 AWSCredentials 对象的形式)、截止日期。如果您了解所需的存储段和对象键,则可以通过清单 6 中的 Groovy 代码快速获取 URL:

清单 6. 创建一个时间敏感型 URL

def now = new Date()
def url = S3Service.createSignedGetUrl(
bucket.getName(), s3obj.key, awsCredentials, now + 2)

使用 Groovy,我可以通过 + 2 语法轻松指定一个 48 小时的限定日期。得到的 URL 如下所示(只有一行):

https://bc50i.s3.amazonaws.com/nerfwars2.mp4?AWSAccessKeyId=
1asd06A5MR2&Expires=1234738280&Signature=rZvk8Gkms%3D

现在,通过该 URL,可以在浏览器中获得图 2 所示的内容:

图 2. 用于下载的 URL

这个过程是不是很简单?通过几行代码,我在云中创建了一个安全资产,该资产只能通过特殊的 URL 下载。

利用 S3 完成时间敏感型下载

如果您的带宽和存储需求不稳定,则 S3 能提供很多帮助。例如,想想我演示的业务模型 — 影片在一年中特定的时间发布。在传统的存储模型中,您需要在某处机架上购买许多空间(或提供通向它的硬件和管道),很可能下载量很大,但随后会相对降低。但是,您不能根据需要付费。使用 S3,该模型将根据需要付费 — 公司仅在需要时为存储和带宽付费。更重要的是,S3 的安全特性可以帮助您进一步指定人们何时可以下载视频,甚至可以指定谁可以下载。

使用 S3 实现这些需求非常容易。在高水平上,创建一个受限的影片公共下载需要 4 个步骤:

登录 S3 。
创建存储段。
向存储段添加所需的视频(或对象)。
创建一个指向该视频的时间敏感型 URL 。

就是这样!

结束语

与传统存储模型相比,S3 的随需付费模型有很多明显的优势。例如,在自己的硬盘上存储音乐收藏,我必须预先花 130 美元购买一个 500GB 的存储单元。我没有 500GB 的数据可以存储,因此我为自己不需要的空间花费了 25 美分 /GB(虽然很便宜)。我还需要维护设备并支付电费。如果我使用 Amazon,我不需要预先为不重要的资产支付 130 美元。我只需要支付 10 美分 /GB,无需为管理和维护存储硬件付费。现在想想在整个企业范围内实现这些服务的好处。以 Twitter 为例,在 S3 上为 100 万个用户帐户存储图片。通过按照使用付费的方式,Twitter 不需要花费大量资金购买硬件基础设施来存储和提供图片服务,也不需要支出人力和部件成本来配置和维护图片。

云的好处还不止这些。您还可以实现低延迟和高可用性。假设存储在 Amazon 云中的资产遍布全世界,那么为各个位置提供内容的速度将会更快。更重要的是,由于您的资产分布在各种机器上,您的数据在一些机器(或部分网络)瘫痪时也能保持高可用性。

一言以蔽之,Amazon S3 的好处很简单:低成本、高可用性、安全。除非您是一个 SAN 专家,喜欢维护硬件资产来存储数据内容,但是 Amazon 可能比您做的更好。在资金紧张的时候,为什么还要将自己的资金提前预支在硬件上呢(不要忘了,硬件会随时间贬值)?

iReader iReader Logo

亚马逊云存储之S3(Simple Storage Service简单存储服

S3是Simple Storage Service的缩写,即简单存储服务。亚马逊的名词缩写也都遵循这个习惯,例如Elastic Compute Cloud缩写为EC2等等。其他组织类似的命名有W3C,如果我们也follow这个习惯则IEEE会被写为IE3,CCTV就是C2TV,好像有点罗 嗦了。

S3说的玄乎一点可以叫云存储,通俗一点就是大网盘。其概念类似于分布式文家系统,同Google的GFS应该在一个层面。

S3的定义如下

Amazon S3 is a web service that enables you to store data in the cloud. You can then download the data or use the data with other AWS services, such as Amazon Elastic Cloud Computer (EC2).

看来除了做网盘只用,S3存储的数据还可以被其他的亚马逊高层服务直接引用,这一点比国内的简单的网盘提供商高不少,亚马逊大网盘是其整体 Solution中的有机组成部分。

基本概念

1。bucket – 类比于文件系统的目录

A bucket is a container for objects stored in Amazon S3. Every object is contained in a bucket. For example, if the object named photos/puppy.jpg is stored in the johnsmith bucket, then it is addressable using the URLhttp://johnsmith.s3.amazonaws.com/photos/puppy.jpg

似乎目录不能嵌套,也就是不能有子目录,官方的说法是起到namespace的作用,是访问控制的基本单位,其实丫还是个目录。

2。Object – 类比文件系统的文件

对象中带有对象名名,对象属性,对象本身最大5G,其实也还是个文件。

目前object有Versioning的属性(即对象不同历史版本的cache概念),这个是文件系统不具备的,在早期看到的S3资料中没有这一 概念,应该是演进的结果,其面对的应该是有版本控制的需求的用户。

3。Keys – 类比文件名

key的样式也是URL,记住亚马逊的服务都是使用Web Service或REST方式访问的。

例如,http://doc.s3.amazonaws.com/2006-03-01/AmazonS3.wsdl

其中‘doc’就是目录名(桶名),”2006-03-01/AmazonS3.wsdl”是文件名(对象名)。

如果引入了version则bucket + key + version唯一标示一个版本的文件。

4。Versioning – 类比CVS中的一个版本

下面是一些实现原理的描述。

image

同名文件的写入,并不覆盖已有文件而是增加了一个最新的文件版本。

同样下面的删除也不真正删除,而是mark了删除标记。

image

当最新版本mark为deleted之后,对该对象的get操作返回404错误,除非明确指定一个历史版本。

当然也可以指定版本永久删除其中一个拷贝。

5。Regions – 文件存储的地理位置

这个也是文件系统中不存在的,就是不同的地理区域,用户可以指定将文件存在某个国家的服务器。我个人认为,这不是一个很好的概念,作为云的提供商, 应该对于应用屏蔽这些部署细节。工程实现同技术理想还是有差距。目前其可以指定的server位置有美国、爱尔兰、新加坡等地。

接口API

常用的API就是读、写、增、删、改、查等等。使用标准的SOAP和REST定义。

尤其一提的是对于对象的获取,除了用http直接按照C/S方式获取之外,亚马逊支持BT协议,也就是说提供种子。从用户角度想,亚马逊会 charge更少的钱,但同时亚马逊自身也会减负。bt下载的速度就不太稳定了,基本取决于种子“质量”也就是取决于对文件感兴趣的人的多寡。例如命名为 “XX门”估计文件下载能够快很多。

数据有什么用

当数据上传到aws云之后,可以很多服务可以使用例如。

Amazon ElasticCompute Cloud

Amazon Elastic MapReduce

Amazon Import/Export等。

一点遗憾

没有看到如何实现分布式文件系统的资料,这是了解其Scale以及可靠性等的关键,或许亚马逊没有google大方,没有提供类似GFS之类的底层 机制实现文档。

参考

http://aws.amazon.com/s3/#functionality

http://docs.amazonwebservices.com/AmazonS3/2006-03-01/

http://developer.amazonwebservices.com/connect/forum.jspa?forumID=24

iReader iReader Logo
分类:

0 条评论

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注