ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 功能丰富的 Perl: Perl 和 Amazon 云

功能丰富的 Perl: Perl 和 Amazon 云

原创 Linux操作系统 作者:ArtCode 时间:2009-04-30 16:31:12 0 删除 编辑

您需要学习 Amazon 的两个 Web 服务:Amazon S3 (Simple Storage Service) 和 Amazon SimpleDB。没有比动手实践更好的学习方法了。在本文中,您将构建一个简单的照片共享站点。

我们的目标并不是构建一个经过良好设计的站点;因为我们已经实现过很多次了。此外,将站点组合起来是件困难 的事情,技术仅仅是诸多因素中之一,因此不要向我抱怨 “伙计你的品味太差了”,因为 sharethewindbeneathmydonkey.com 在第一个星期内不会让您成为百万富翁(但是如果确实是这样的话,请您一定不要忘记您的启蒙者)。

需求

本系列需要您掌握 HTTP 和 HTML 的入门级知识,以及 JavaScript. 和 Perl(位于 Apache mod_perl 进程内部)的中级知识。掌握关系数据库、磁盘存储和网络知识也非常有帮助。本系列将逐渐引入更多技术内容,因此如果需要获得有关任何主题的帮助,请参见 参考资料 小节)。

我在本系列中使用 share.lifelogs.com 作为域名。现在让我们来了解一下 Amazon S3 吧。

Amazon S3 概述

我成为一名 UNIX® 管理员已经有一段时间了,因此我可以告诉您备份和文件存储并不是简单的服务。如果 SAN、NAS、LUN、LVM、RAID、JBOD、IDE 和 SCSI 之类的缩略语对您毫无用处的话,那么您就可以松一口气了。但是如果情况不是这样的话,那么在您从损坏了的使用了 4 年的 DLT 备份中进行恢复后的第三月时,您一定会在午餐时愁得抹眼泪并且希望能有一种更好的方法来管理数据。不过我以前可没有做过这种事。

IBM 和 Amazon Web 服务

云计算提供了一种在虚拟环境中开发应用程序的方法,在这种虚拟环境中,计算能力、带宽、存储、安全性和可靠性不会造成问题 — 您不需要在自己的系统上安装软件。在一个虚拟计算环境中,只需要投入时间并购买需要的存储容量,就可以开发、部署和管理应用程序,同时可以根据不断变化的要求或业务需求进行伸缩。

IBM 与 Amazon Web Services 携手为您提供了在 Amazon Elastic Compute Cloud (EC2) 虚拟环境中对 IBM 软件产品的访问。我们有关 EC2 的软件产品包括:

  • DB2® Express-C 9.5
  • Informix® Dynamic Server Developer Edition 11.5
  • WebSphere® Portal Server and Lotus® Web Content Management Standard Edition
  • WebSphere sMash

这是产品级别的代码,启用了所有特性和选项。在 IBM developerWorks 云计算资源中心 可以获得更多信息,并下载面向这些产品的 Amazon Machine Images。

有关云计算资源的更多信息,请访问 developerWorks 上的 Cloud Computing for Developers 空间。

Amazon S3 示例

现在,看看 S3 提供了什么。文件(S3 中称为对象)保存在 bucket 中。在每个 bucket 中,文件名(即)是惟一的。您可以提供 “颜色” 或 “语言” 等文件属性,但是它们不包含在文件名中。

假设我们将美国国旗的图片作为 “images/flag.png” 文件存储在 bucket “us.images.share.lifelogs.com” 中,而将德国国旗作为文件 “images/flag.png” 存储在 bucket “de.images.share.lifelogs.com” 中(它们的文件名相同,但是保存在不同的 bucket 中)。您的用户可以随后请求 http://us.images.share.lifelogs.com.s3.amazonaws.com/images/flag.png 来获得美国国旗,或者通过请求 http://de.images.share.lifelogs.com.s3.amazonaws.com/images/flag.png 获得德国国旗。此外,可以在 DNS 中将 de.images.share.lifelogs.com 作为 de.images.share.lifelogs.com.s3.amazonaws.com 的别名(对 us.images.share.lifelogs.com 做同样的操作),这样,用户只需请求 http://us.images.share.lifelogs.com/images/flag.png 或 http://de.images.share.lifelogs.com/images/flag.png 就可获得国旗。

注意,bucket 名在所有 Amazon S3 帐户中都是惟一的,因此像 “test” 或 “default” 这样的名称是不合适的。如果可以的话,使用完整的域名限定 bucket 的名称。这将使在 DNS 中识别和使用 bucket 变得更加简单。同样,bucket 名称是有限制的,因此不要使用特别长的名称。坚持使用在域名中出现的相同字符。

S3 是一项复杂的服务,因此我建议您在继续阅读之前查看一下 S3 的主页。

Amazon SimpleDB 概述

通常在介绍这一部分内容的时候,职业演讲人和大学教授会对因为前一晚上纵饮过度而在前排大打瞌睡的老兄特别问候一声:数据库非常重要!

您醒了吗?

进行分类、过滤、聚集、平均分配和分析,我们每天面对的数据流会变得难以管理。IT 专业人员需要全天托管这些数据库。他们需要存储空间、电源、备份以及其他许多资源。作为一项财务决策,使用诸如 SimpleDB 之类的托管数据库对您的业务来说可能是值得的;我在这里仅解释一下它的技术方面。

一个简单的数据库示例就是冰箱上面贴的备忘单:每一项占一行,在某些项的旁边划了一个对钩,而其他项可能被勾掉。在传统的关系数据库中,这个备忘单可能被建模成两个表,每个表包含两个列:


表 1. todo_foreign 表

事项 状态码
(status.statuscode 的外键,
默认为 0)
给妈妈打电话 0
给 IRS 打电话 2
取牛奶 1

表 2. 状态表
状态码 状态描述
0 活动
1 已完成
2 已删除

“但是,等等,” 您会说。“当这些事项被完成或删除后数据会怎么样,谁修改了数据,数据类型是什么?毕竟,这就是我们培养聪明的、有能力的数据库管理员(DBA)的原因。??们了解有关普通表单和外键以及 SQL 的所有内容。当然,您需要他们当中的其中之一来立即检查您的设计,对不对?”

是的,谢谢您的提醒,您可真聪明,不过请别干扰我的这个简单示例,好吗?稍后您可以抱着一本 “Secrets Of The SQL and RDBMS Gods For Dummies” 自我安慰一下。

Amazon SimpleDB 是一个广泛分布的关键属性数据库。它绝对不是面向所有业务的,并且在性能和可伸缩性方面也有严格的限制。每个属性被限制为 1KB,因此您的备忘事项的名称不能超过 1 KB。

安全性也是一个问题;SimpleDB 的访问控制系统类似 S3。一个简单的社会性站点(比如将在本系列中遇到的站点)可以使用 SimpleDB 作为后端数据库。但是,您应当考查业务需求、预算和数据存储需求,以确定 SimpleDB 是否能够完全满足这些要求。

前面提到的 S3 更新延迟问题也将对 SimpleDB 产生影响。您的更新并不能在所有位置立即生效。

如果使用简单的数据库示例,SimpleDB 结构将如下面所示:


表 3. SimpleDB todo 结构

事项 状态
给妈妈打电话 活动
给 IRS 打电话 已删除
取牛奶 已完成

到目前为止,一切良好。这要比第一个例子简单,不是吗?但是让我们再添加另一个事项:

取奶牛 活动

您看到状态被复制了吗?active 在数据库中被存储了两次。对于存储和性能而言,这对大型表来说开销太大。另一方面,每个 SimpleDB 行被设计为可以自己提供自己需要的东西。当您获得该行时,您将得到其中包含的所有内容。您不需要查找状态描述。对于 SimpleDB 的更新延迟,这会产生问题。

更多 SimpleDB 备忘单

假设您添加了一个新的状态码 waituntiltomorrow,并将它应用到 todo_foreign 表(包含外键的表 1)中的某一项。这样,您现在拥有了两个更新(一个针对状态表,一个针对 todo_foreign)。如果状态表(表 2)在 todo_foreign 更新之后 执行更新,那么您将得到不一致的数据。记住,SimpleDB 并不保证您的更新按照您执行的顺序立即生效,因此除了执行两个查找(一个用于查找项,另一个用于查找状态码描述)而使性能受损外,您可能还会得到不一致的数据。

SimpleDB 的关键在于:忘记了 todo_simple 中的列(表 2)。SimpleDB 并没有列!它为每个行提供了属性。这些属性不是静态的,因此可以随意添加和删除它们。您希望您的备忘事项有一个创建和删除日期?那么设置属性就可以了。在 todo_foreign 中,这将需要两个列;删除日期可能为 null,表示该事项仍然在活动中。让我们再添加一个列,表示完成该事项的日期。或者只使用状态码,并使用删除日期作为完成日期。我们该怎么做?

SimpleDB 的风格就是随心所欲地执行您需要的操作。需要一个创建日期?设置一个 created_date 属性。想要一个删除日期?只需为已被删除的项分配相关属性。属性的存在 告诉我们它应用于这个项。

不要再从列的角度思考了。SimpleDB 的行更类似于 Perl 的散列。每个键就是一个字符串。每个值就是一个字符串或字符串数组。让我们再次进行设计。


清单 1. todo_freeform

				
{ item: "call Mom" }
{ item: "call IRS", deleted_date: "2009-03-01" }
{ item: "get milk", done_date: "2009-03-02" }

注意 SimpleDB 有一个名为 ItemName 的隐含键,在本例中为字符串形式的备忘事项,如下所示?


清单 2. SimpleDB 备忘单

				
"call Mom" {  }
"call IRS" { deleted_date: "2009-03-01" }
"get milk" { done_date: "2009-03-02" }

SimpleDB 要求对象必须具有属性,因此为所有对象分配一个 created_date 属性,如下所示:


清单 3. 添加了 created_date 属性的 SimpleDB 备忘单

				
"call Mom" { created_date: "2009-02-01" }
"call IRS" { created_date: "2009-02-01", deleted_date: "2009-03-01" }
"get milk" { created_date: "2009-02-01", done_date: "2009-03-02" }

“但是等等”,您会喊道,“所有内容真的是一个字符串吗?数据没有被严格输入吧?哈!完蛋了!”

是的。所有内容都是字符串。是不是很令人惊奇?

并且您可以向该表中任何已经删除了三个月的事项添加一个 deletereason 属性。不会产生任何影响,并且只有新添加的代码才会使用它。

这里将产生一些戏剧化的效果,DBA 需要服用几片阿司匹林。同时,Perl 程序员会为他们递上一杯水,为什么?仅仅因为我们本来就是一些非常不错的人。

继续这个示例。这里的重点是创建搜索活动的、已删除的或已完成的事项的查询。这非常简单;可以查看 SimpleDB 文档找到所有查询选项。我们将使用 SELECT 语言。还有一种 QUERY 语言,但是 SELECT 更接近 SQL,因此更容易被大部分读者理解。


清单 4. todo_freeform. 查询

				
-- get active
select * from todo_freeform. where done_date is null and deleted_date is null
-- get deleted
select * from todo_freeform. where deleted_date is not null
-- get done
select * from todo_freeform. where done_date is not null

就是这样。现在让我们把 SimpleDB 和 S3 结合起来。

集成服务并共享照片

您接下来也许要问,如何将 SimpleDB 和 S3 联系起来?(除了使用访问控制模型外,它们并不存在内在联系)。很简单:您可以轻松地将一个 S3 对象的 bucket 和名称存储到 SimpleDB 中。不管怎样,至少可以实现备忘单;让我们开始设计照片共享站点吧。

站点需要在 S3 中存储照片并使用 SimpleDB 中的用户评论。那么用户帐户放在哪里?我们需要忍受 SimpleDB 的分布式特性,这意味着我们有时会得到无效的用户(例如在没有推出用户但推出了引用该用户的行的时候)。但是,对于这个应用程序,我们将用户保存在 SimpleDB 中。没有依赖任何外部数据库,因为我们的目标是能够在任何位置快速创建站点,所要做的仅仅是在 mod_perl 下运行一些 Perl glue,在 S3 和 SimpleDB 中执行一些真正的操作。

首先,您需要一个照片表。表记录如下所示:


清单 5. 照片表记录,share_photos

				
"http://developer.amazonwebservices.com/connect/images/amazon/logo_aws.gif" 
{ user: "ted", name: "Amazon Logo"}

"http://images.share.lifelogs.com/funny.jpg" 
{ user: "bob", name: "Funny Picture",  s3bucket: "images.share.lifelogs.com" }

接下来,创建一个用户表:


清单 6. 用户表,share_users

				
"ted" { given: "Ted", family: "Zlatanov" }
"bob" { given: "Bob", family: "Leech" }

然后是评论:


清单 7. 评论,share_comments

				
"random-string"
{ 
 url: "http://images.share.lifelogs.com/funny.jpg",
 comment: "Ha ha", 
 posted_when: "2009-03-01T19:00:00+05" 
}

"random-string2"
{ 
 user: "ted",
 url: "http://developer.amazonwebservices.com/connect/images/amazon/logo_aws.gif", 
 comment: "No it doesn't", 
 posted_when: "2009-03-01T20:00:01+05" 
}

"random-string3"
{ 
 url: "http://developer.amazonwebservices.com/connect/images/amazon/logo_aws.gif", 
 comment: "No it doesn't", 
 reply_to: "random-string2", 
 posted_when: "2009-03-01T20:00:01+05" 
}
            

注意
Google 至少提供了一些类似的服务;本系列并没有对 Google 的服务和 Amazon 的服务进行比较。您可以在网上找到大量的比较。本系列也没有讨论其他 Amazon 产品,比如 Elastic Compute Cloud (EC2),即使它们非常有趣和有用,并且确实可以帮助组合站点。最后,还存在其他各种可与 SimpleDB 媲美的分布式关键属性数据库,比如 CouchDB;我强烈建议您对这些数据库也进行一下研究。

我们将通过查看 reply_to 键将评论串接在一起。每一个帖子将使用一个随机字符串作为惟一键。

注意,我们在这里确立了一些约定:

  • 缺乏 user 属性意味着评论是匿名的。
  • 照片 URL 将所有评论合并在一起,因此改变照片的 URL 是不允许的。
  • S3 对象也有一个 URL,并使用一个 bucket 名来将它们标识为 S3 对象。
  • 复制照片 URL 是不允许的,因为 URL 是对象的键。

这并不是这个表设计的最终版本(记住,SimpleDB 非常灵活),但是足够作为入门的基础。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15082138/viewspace-592379/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-08-05

  • 博文量
    269
  • 访问量
    556640