《云计算》样章连载
2.1 Amazon S3
Amazon S3
Amazon简单存储服务(S3)是基于云的持久化存储。它独立于Amazon其他服务运行。事实上,部署、运行在你自己服务器上的程序也可以利用Amazon S3,不要求该服务器一定“身在云中”。
Amazon说S3是“简单存储”,是指特性集而言——不是指用起来简单。Amazon S3可以帮你简单地把数据放进云中,再拖回来,完全不用了解数据如何存储、实际上存在哪儿。
如果把Amazon S3想象成远程文件系统,那你就大错特错了。从许多方面来看,Amazon S3要比文件系统原始得多。实际上,存储的不是“文件”——存的是对象。进一步说,是在桶中而非目录中存放对象。虽然粗看起来只是语义上有些区别,实际上,这中间包含着若干重要的差别:
l 存在S3中的对象不能大于5GB。
l 桶存在于一个扁平的名字空间中,由所有Amazon S3用户共享。你没法创建“子桶”,且必须留意名字空间的冲突。
l 可以把自己的桶和对象公开,让所有人都能访问。
l 如果没有第三方工具,则无法“挂载”(mount)S3存储。实际上,我不喜欢用第三方工具来挂载S3,因为S3与文件系统在概念上是如此不同,所以我相信,不应该把两者按相同的方式处理。
2.1.1 访问S3
Access to S3
访问S3之前,需要开通一个Amazon Web Services账户。可以把美国设为默认的存储地,也可以设到欧洲。不是说你住哪儿数据就该存哪儿。正如我们在本书后面要讨论的,决定云数据存在什么地方时,会涉及监管和隐私方面的考虑。就本章而言,我建议,你将从什么地方访问S3,就在离那儿最近的地方存放数据。
Web Services
Amazon提供了SOAP API和REST API两种方式访问S3。虽然开发人员往往对如何通过SOAP创建Web Services比较熟悉,然而,访问S3时,使用REST机制更可取,因为在SOAP API中处理大型二进制对象比较困难。具体来说,SOAP限制了在S3中能管理的对象大小,SOAP还限制了当数据流在本地和S3之间往返时,能够在其上进行的处理(如显示一个传输状态条)。
Amazon Web Services API支持的功能有:
l 查找桶和对象。
l 探查元数据。
l 创建新桶。
l 上传新对象。
l 删除现有的桶和对象。
在对桶进行操作时,其中一个选项是指定桶的内容应存放的位置。
除非需要非常细粒度地控制与S3的交互,否则,我推荐用你的工作编程语言写一个API封装层,把S3的REST API再抽象一次。在用Java开发时,我的团队使用Jets3t。
不管如何,要在Amazon S3上起步,绝对要从Amazon S3上下载s3cmd(http://s3tools.logix. cz/s3cmd)命令行客户端。它在S3的Web Services API上提供了一层命令行封装。这个工具恰巧是用Python写的,这就意味着可以读到源代码,看到一个如何为S3写Python应用程序的绝佳范例。
BitTorrent
Amazon也提供访问S3的另一种方式:BitTorrent。BitTorrent是一个点对点(P2P)的文件共享协议。由于BitTorrent是共享大型二进制文件的标准协议,因此,市场上有很多客户端和应用程序都通过BitTorrent来获取和发布数据。如果应用程序能用上P2P,充分利用Amazon S3对BitTorrent的支持不失为一个好主意。但是,大多数情况下,事务型Web应用程序不使用BitTorrent与S3交互。
2.1.2 使用S3
S3 in Action
为了讲清楚如何使用S3,我们将使用s3cmd在本地和S3之间传递数据。该工具支持的命令集能很好地映射到底层Web Services API上。下载了该工具之后,需要用你的S3访问密钥和S3加密密钥来对其进行配置。不管是用这个还是别的工具,访问S3中的私有桶总是需要这些密钥。
用Amazon S3时,要做的第一件事就是在S3里创建一个桶,好存放对象。
s3cmd mb s3://BUCKET
该命令用你给出的名字创建一个桶。正如我在本章前面指出的,桶的名字空间在所有Amazon客户间共享。除非你是本书的第一位读者,否则,照着上面的命令原模原样敲进去执行很难成功,需要把“BUCKET”换成某种更不容易冲突的东西。许多用户都在桶前加些能增强唯一性的前缀,如他们自己的域名。无论如何,请记住:不管遵循怎样的标准,都没法阻止别的用户使用同样的命名规范。
桶命名
我在好些不同的场合已经提醒过多次,要注意:桶的命名空间是扁平的。也许你已经在琢磨了,如何在这样的命名限制下工作呢?
首先,记住如下命名原则:
· 名字中只能用小写字母、数字、句点、下划线和中连线,并且,第一个字符必须是数字或字母。
· 名字不能用IP地址格式(例如,不能是10.0.0.1)。
· 名字必须至少3个字符长,最长不得超过255个字符。
最好创建自己的虚拟桶名空间,以此来为桶命名。例如,我用com.imaginary.mybucket这样的名字就可能没有冲突,因为imaginary.com这个域是我的。然而要注意,无法保证别人不会用你的域(或者你遵循的任何命名规范)来作为其桶名的前缀。因此,应用程序在创建新桶时要智能一些,不要盯死在一个命名方案上。
Amazon给出了一些桶命名建议,遵循这些命名指导原则能减少冲突,增加给S3对象创建有效URL的机会:
· 不要在桶名中用下划线(虽然可以用)。
· 最好把桶名控制在63个字符内。
· 不要用中连线作结束字符,也不要在中连线后用句点字符。
一旦创建了桶,就可以往里塞东西:
s3cmd put LOCAL_FILE s3://BUCKET/S3FILE
例如:
s3cmd put home_movie.mp4 s3://com.imaginary.movies/home_movie.mp4
前面已经提到过,s3cmd把文件大小限制在5G内。本书后面会讨论该用怎样的策略绕开这个限制,除此之外,还会谈到如何提供更高级别的安全,以及如何管理S3对象的完整性。
然后,可以从云中取回对象:
s3cmd get s3://BUCKET/S3FILE LOCAL_FILE
例如:
s3cmd get s3://com.imaginary.movies/home_movie.mp4 home_movies3.mp4
现在,你的家庭电影应该又回到了桌面计算机上。
以下是其他一些可用的命令。
l 列出所有桶:s3cmd ls.
l 列出特定桶的内容:s3cmd ls s3://BUCKET.
l 从桶中删除一个对象:s3cmd del s3://BUCKET/S3FILE.
l 删除桶:s3cmd rb s3://BUCKET.
桶只有在空的时候才能删除。首先必须逐个删除桶的内容,然后才能删除桶。s3cmd的del命令很快会有一个-recursive选项,但是,聪明的你应该明白,它不过是列举了目标桶的内容,再逐个删除它们而已。如果使用Web Services API与S3交互,在删除一个含有对象的桶时,必须自己写循环删除的代码。