学习基本的 Amazon SimpleDB (SDB) 概念,研究 boto(一个用于与 SDB 交互的开放源码 Python 库)提供的一些功能。在这个 “用 Amazon Web Services 进行云计算” 系列中,学习如何使用 Amazon Web Services 进行云计算。了解这些服务如何为设计和构建可伸缩、可靠的应用程序提供一种可选方案。在本文中,学习一些基本概念和 boto 提供的一些功能。
Amazon SimpleDB
Amazon SDB 是一个快速的可伸缩实时数据集索引和查询框架,基于 Amazon Web Services 的应用程序可以用它轻松地存储和获取结构化数据。它能够与其他 Amazon Web Services 很好地协作,比如 Elastic Compute Cloud (EC2) 和 Simple Storage Service (S3)。可以使用 SDB 在 Amazon Web Services 环境中构建完整的应用程序组合。只需根据使用量为服务付费。还提供一定的免费使用量。
IBM 和 Amazon Web Services
IBM 和 AWS 合作支持在虚拟计算环境中访问 IBM 软件。Amazon 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
它们是生产级代码,启用了所有特性和选项。
SDB 提供的特性包括:
可靠性 SDB 跨多个数据中心冗余地存储带索引的数据,保证它们随时可用。 速度 SDB 能够快速地获取数据,尤其是在 Amazon Web Services 环境中从 EC2 实例发出请求时。 简单性 访问和使用 SDB 的编程模型非常简单,而且可以从多种编程语言使用 SDB。 安全性 SDB 提供很高的安全水平。只允许授权的用户访问数据。 灵活性 SDB 支持动态地存储数据,不需要预先定义的模式。 低成本 SDB 的费用非常低廉。只需根据实际使用量付费。
下面讨论支撑 SDB 的概念。
域
域是存储结构化数据和运行查询的容器。在域中存储的数据称为条目。从概念上说,域与电子表格中的工作单标签相似;条目与电子表格中的行相似。可以对域运行查询,但是当前的 SDB 版本还不支持跨域查询。
每个域与下面的元数据相关联:
最后一次更新元数据的日期和时间 域中条目的数量 域中属性名-值对的数量 域中独特属性名的数量 域中所有条目名的总大小(字节数) 域中所有属性值的总大小(字节数) 域中所有独特属性名的总大小(字节数)
与 Simple Queue Service (SQS) 一样,SDB 也采用 “最终一致性” 模型。SDB 维护每个域的多个拷贝,从而提供容错能力。对域的每个修改都会传播到所有拷贝。
根据系统负载和网络延时不同,这个操作有时候要花费几秒时间,所以域的消费者可能无法立即看到修改。修改最终会传播到整个 SDB,但是在设计基于 SDB 的应用程序时一定要考虑到传播延时的影响。
条目
条目 代表域中的对象,它们包含属性和值。从概念上说,条目与电子表格中的行相似 — 属性是列,值是单元格。属性可以包含多个值。无论数据结构是什么样的,SDB 都会自动地为域编制索引。
SDB 还对针对域执行的查询有时间限制。如果查询花费的时间超过 5 秒,SDB 就会停止查询并返回一个错误。
SDB 中的域很灵活,没有任何固定的模式。域中的每个条目可以包含一组独特的属性(不超过 256 个)。属性甚至可以与域中其他条目的所有其他属性完全不同。
限制
当前的 SDB 版本有一些限制,在设计应用程序时应该考虑到这些限制。表 1 给出这些限制(取自 Amazon 的最新文档)。
表 1. 当前限制
参数
当前限制
域大小
每个域 10 GB
250,000,000 个属性名-值对
3-255 个字符(a-z、A-Z、0-9、'_'、'-' 和 '.')
每个 Amazon Web Services 账户的域数量
100
属性
每个条目中的名-值对数量是 256。
名称长度是 1024 字节。
值长度是 1024 字节。
只允许使用在 XML 文档中合法的 UTF-8 字符。不允许使用控制字符和在 XML 中非法的任何字符序列。
每个 PutAttributes 操作处理的属性数限制为 100。
每个 Select 或 QueryWithAttributes 操作请求的属性数限制为 256。
查询响应中的最大条目数
256
最大查询执行时间
5 秒
每个查询表达式的最大谓词数
10
每个查询表达式谓词的最大比较数
10
每个选择表达式的最大独特属性数
20
每个选择表达式的最大比较数
20
QueryWithAttributes 和 Select 的最大响应大小
1 MB
SDB 入门
要想开始使用 SDB,首先需要注册一个 Amazon Web Services 账户(见 参考资料)。本系列的第2部分详细介绍了如何注册 Amazon Web Services 账户。创建 Amazon Web Services 账户之后,必须为账户启用 Amazon SDB 服务:
登录Amazon Web Services 账户。 导航到 SDB 主页。 单击页面右边的 Sign Up For This Web Service。 提供必需的信息并完成注册过程。
与任何 Amazon Web Services 的所有通信都要通过 SOAP 接口或查询接口。在本文中,通过一个第三方库使用查询接口与 SDB 通信。
需要获得自己的访问键,可以通过在Web Services 帐户信息页面上选择 View Access Key Identifiers 获得访问键。现在设置了 Amazon Web Services 并为账户启用了 SDB 服务。
与 SDB 交互
这个示例使用第三方开放源码Python库boto,通过在 Python shell 中运行代码片段熟悉 SDB。
安装 boto 并设置环境
下载boto。撰写本文时的最新版本是 1.6b。把存档文件解压到您选择的目录中。进入此目录并运行 setup.py 把 boto 安装到本地 Python 环境中,见清单 1。
清单 1. 安装 boto
$ cd directory_where_you_unzipped_boto$ python setup.py install
设置一些环境变量,引用 Amazon Web Services 访问键。可以从Web Services账户信息从页面获得访问键。
清单 2. 设置环境变量
# Export variables with your AWS access keys$ export AWS_ACCESS_KEY_ID=Your_AWS_Access_Key_ID $ export AWS_SECRET_ACCESS_KEY=Your_AWS_Secret_Access_Key
启动 Python shell 并导入 boto 库,从而确认所有设置都是正确的,见清单 3。
清单 3. 检查设置
$ pythonPython 2.4.5 (#1, Apr 12 2008, 02:18:19) [GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> import boto>>>
用 boto 体验 SDB
使用 SDBConnection 类提供与 SDB 交互的主要接口。从 Python 控制台使用 boto。示例调用 SDBConnection 对象上的不同方法,然后查看 SDB 返回的响应,这有助于熟悉 API 和体验 SDB 概念。
第一步是使用前面导出到环境中的 Amazon Web Services 访问键,创建一个连接到 SDB 的连接对象。boto 库总是先检查是否设置了这些环境变量。如果设置了这些变量,boto 在创建连接时自动地使用它们。
清单 4. 创建到 SDB 的连接
>>> import boto>>> sdb_conn = boto.connect_sdb()>>>
然后,可以使用上面创建的 sdb_conn 对象与 SDB 交互。可以通过指定域名创建新的域。
清单 5. 创建域
>>> d1 = sdb_conn.create_domain('devworks-dom-1')>>>
获取所有域的列表,这返回一个结果集对象,它实际上是一个 Python 列表,见清单 6。可以循环遍历这个列表并访问每个域的所有相关信息。
清单 6. 列出所有域
>>> all_domains = sdb_conn.get_all_domains()>>> >>> len(all_domains)1>>> >>> for d in all_domains:... print d.name... devworks-dom-1
还可以按名称获取单一域。
清单 7. 列出单一域
>>> my_domain = sdb_conn.get_domain('devworks-dom-1')>>> >>> print my_domain.namedevworks-dom-1
当然,在添加条目之前,刚创建的域是空的。在域中创建一个新条目,然后在其中添加属性。
清单 8. 创建新条目
>>> my_domain = sdb_conn.get_domain('devworks-dom-1')>>> >>> i1 = my_domain.new_item('test_item_1')>>> >>> i1['cars'] = 'BMW'>>> >>> i1['fruits'] = ['apple', 'orange', 'mango']>>>
可以通过指定条目名从域中获取条目。条目名必须是惟一的,这与关系数据库中的主键概念相似。
清单 9. 获取条目及其属性
>>> my_item = my_domain.get_item('test_item_1')>>> >>> print my_item{u'cars': u'BMW', u'fruits': [u'apple', u'mango', u'orange']}>>><