撰写Windows Azure ISV系列博客的目的是宣传来自ISV(独立软件供应商)在Windows Azure 应用程序的开发和部署过程中的一些成就。这篇文章是微软在日本的分公司的Windows Azure宣传者Naoki Sato所写,是关于Windows Azure ISV ReedRex股份有限公司和他们如何使用Windows Azure为Facebook页面提供他们的CMS服务。
ReedRex 最近推出了一项新的SaaS服务叫做sociobridge,专门为Facebook页面内容管理系统 (CMS) 服务而设的。由顶级日本广告公司Dentsu Razorfish分发,sociobridge由Dentsu 和 Razorfish共同出资组建。
公司和广告机构的工作人员可以使用sociobridge来做以下的事情:
- 创建和维护 Facebook 页面
- 日程表
- 监视walls、 评论和爱好
Sociobridge由两个多租户以ASP.NET MVC 使用 Facebook C# SDK 所写的 web应用程序组成。一个Web Role运行订阅者门户,它是为订阅者提供的一个内容管理应用程序(客户公司和广告代理机构)。另一个运行一个应用程序运行时,为终端用户托管公共Facebook页面。
还有Worker Role实例负责Facebook的监测和其他后台处理。
Sociobridge将Windows Azure Storage (Table 和 Blob)作为一个永久的数据存储区。这是因为Windows Azure 存储提供了更高的可扩展性和更低的成本需求。
有关订阅(租户)、用户账户、日程表、投票结果、统计及其他的信息都被存储在Table 存储里。在Windows Azure Table 存储里只有两张表。
- 订阅元数据
- 订阅者数据
在Table 存储中,表被分区以便支持跨存储节点的负载平衡。表的实体是按分区进行组织的。一个分区由一系列连续拥有相同的分区键值的实体组成。
关系数据库如SQL Azure支持事务处理,提供通常被称为ACID(Atomic,Consistent,Isolated,Durable)的特性:
- 原子性:事务是作为原子执行的,整个语句要么执行,要么不执行。
- 一致性:事务不能使数据库中的数据处于不一致的状态。
- 隔离性:事务不能够相互干扰。
- 持久性:事务的结果被永久保存。
与关系数据库系统不同,Windows Azure Table 存储一般不支持事务内的多个操作(例如,插入、更新和删除实体)。但是如果所有实体作为事务的一部分受制于操作并且拥有相同的分区关键值(且属于相同的分区),你可以在一批被称作“entity group transaction”或EGT执行这些操作。这里有关于EGT的更多详细信息。
为了利用schema-less数据模型和Table 存储的EGT,不同类型的数据被存储在一个单一的数据表里。订阅ID被用作分区键值,因此每个订阅的数据被存储在不同的分区并且为了提高可扩展性表访问延伸到许多存储服务器中。行的键值是由数据类型和一种独立的行ID组成。
每个从Subscriber Portal的表查询是仔细设计用来指定分区键值(订阅ID),以便他们的查询只限于单个分区和全表扫描包括那些从未分过区的区域。
在单个订阅的数据里有两个或多个类型的数据的事务,但是没有两个或多个订阅数据的事务。因此,此表的设计使得使用EGT(entity group transaction)的原子事务称为可能,因为单个事务中的数据驻留于单一表中的单个分区。
目前,Windows Azure Storage Analytics为每个存储账户提供度量数据。对此表使用这样的设计,单个订阅者不可能估计表存储的成本。选择此表的设计是因为上面提到的优势和存储账户的数量。
客户公司的工作人员和(或者)一个广告代理机构创建和维护在订阅者门户上的Facebook页面。当定义和Facebook页面的元数据被创建或修改时,Facebook 页面的实际 web 内容被预先生成,并 存在Blob 存储中。
一个订阅者可能在同一个Facebook页面里创建多个自定义的选项卡。每个自定义的选项卡有它自己的Blob容器,每个选项卡的web内容都被存储在那里。Blob容器的权限被设置为public,因为Facebook页面本来就是public的。
在运行时:
- 终端用户浏览一个Facebook页面(使用HTML内联框架被包含在Facebook中)。
- Web浏览器在Web Role上向应用程序运行时发送一个HTTP POST请求。
- 应用程序运行时访问Table Storage来查询一个Blob Storage URL。
- 应用程序运行时返回Blob Storage URL(使用HTTP 302 Found)。
- Web浏览器被重定向到Blob存储的web内容中。
这种体系结构的目的是通过避免生成动态的web内容减少Web Role的工作负荷,实现更高的可扩展性以处理来自多个Facebook用户的大量请求。
Facebook页面需要处理HTTP POST请求。顾名思义,Blob Service REST API 的“Get Blob”操作需要是一个HTTP GET请求。因此,直接访问Blob存储是不行的,并且处理HTTP POST应用程序运行时是必须的。
Blob存储的分区键值是容器名称和Blob名称的组合,所以可以在不同的分区中访问不同的Facebook页面(Blob)。
根据“Windows Azure Storage Abstractions and their Scalability Targets”这篇文章,单一Blob的目标吞吐量是60 MB/秒。性能测试显示sociobridge应用程序运行时(在一个小示例上)的吞吐量是每秒约200 次请求。
粗略估计,如果只托管了一个Facebook页面并且该页面的大小小于300KB,应用程序运行时将成为一个瓶颈。如果它大于300KB,Blob存储将成为一个瓶颈。可以通过添加更多的Web Role实例并分别利用Windows Azure CDN删除这些瓶颈。请注意,通常会托管多个Facebook页面(Blob),Blob的访问将被横向扩展。
Sociobridge被设计用来利用Windows Azure的功能,尤其是Windows Azure存储。复杂的表设计(使用租户ID作为分区键值)并且EGT(entity group transaction)的使用将有助于设计多租户应用程序!
若想了解Windows Azure存储的可扩展性的更多信息,请参阅这些博客文章:
特别感谢ReedRex 的sociobridge 项目首席架构师Takekazu Omi为这篇文章提供的帮助。