Windows Azure中的存储
===========================
Windows Azure为结构化的数据和非结构化的数据都提供了可扩展的存储服务. 基于以下的原因, 这里的存储服务被认为是可扩展的.
• 应用程序可以扩展它的存储到上百TB的数据.
• 存储服务可以扩展数据访问以便获得在访问上的更佳的性能, 扩展的方式取决于使用数据的模式.
即使经常被结合起来使用, 实际上存储服务是独立于任何hosted services的. 访问Windows Azure的存储是通过基于REST的API完成的. 这意味着许多支持HTTP栈的客户端都可以访问存储服务. 在实践中, 将你的数据与Windows Azure中的存储服务结合起来, 能够达到最佳的性能. 与hosted service一样, 存储服务也是可以容错的, 并且同样具有高可靠性. 在Windows Azure中存储的每一个bit的数据都即在数据中心中复制过, 也在不同地理位置的数据中心之间复制过. 数据损坏是被持续地监视着的, 同样的是对你的数据的保护和复制(目前, 任意你的数据都有三分拷贝.)
所有的数据都是通过遵循REST惯例的http请求来访问的. .NET framework包括了很多可以与不同抽象层次的基于REST的service进行交互的library, 举个抽象层次的例子, WCF数据服务, 或是通过WebRequest类进行的直接的HTTP请求.
Windows Azure的SDK还包括专门定制的客户端library, 可以提供对所有Windows Azure服务的域模型(domain models ). 基于REST的服务也被应用在许多其他的平台上, 比如说JAVA, PHP, 和Ruby. 几乎所有的programming stack都可以搞定与Windows Azure存储服务相交互的HTTP请求.
Windows Azure存储有四种类型: blobs, drives, tables, 和queues.
要访问Windows Azure的存储, 你必须有个在Windows Azure门户网站http://windows.azure.com界面创建的storage account.
Storage Account是与某个具体的地理位置相关联的. 目前, 每一个storage account可以存储高达100TB的数据, 这100T的数据可以由任意的blob, table, queue和drive组成. 如果你愿意, 你可以拥有任意多的storage account, 然而, 默认情况下你可以创建最多5个storage account(译者注: 表面上看这句话说的自相矛盾, 是不是说要超过这个限度就要多交钱呢?)
默认地, 所有对Windows Azure存储的访问都必须经过认证. 每个存储账户都有两个256bit的对称密钥.
Blobs
---------------------
通体上说, blob提供了对大块数据的访问, 大块数据举例, 图片, 视频, 文档, 和代码. subscription中的每个storage account都可以有任意数量的container, 其中每个container都可以拥有任意数量的blobs. 存储的限制是在账户级别的, 而不是任何具体的container或blob数据. blobs是通过遵循如下格式的URL来引用的:
http(s)://<storage account name>.blob.core.windows.net/<container>/<blob name>
Windows Azure的blob存储支持root container的概念. 这在当你需要只通过指定domain name就访问blob数据的时候是很有用的. Windows Azure保留的blob名字"$rootdenotes "是个特例. 下面的URL指定了一个出现在账户为"myaccount"的, 名为“mypicture.jpg” 的blob数据.
http://myaccount.blob.core.windows.net/$root/mypicture.jpg
这与下面的URL是等价的.
http://myaccount.blob.core.windows.net/mypicture.jpg
你可以命名你的blog, 从而使得它们看起来像是属于一个有层次的命名空间, 但事实上, 命名空间是扁平的. 比如说, 下面的是一个blob的引用, 这个引用看起来像是暗示了一个等级化了的结构.
http://myaccount.blob.core.windows.net/pictures/trips/seattle/spaceneedle.jpg
你也许会误认为由名为“pictures”, “trips”, 和“seattle”的文件夹组成了一个等级结构, 但事实上, 所有的路径的分段其实都是blob本身名字的一部分而已. 换句话说, container的名字是“pictures” , blob的名字是 “trips/seattle/spac-eneedle.jpg”.
Container和blob都可以按照name/value pair的格式存储最大8Kb的元数据,. 除了创建, 更新, 删除操作之外, 你还能够执行针对blob的更多特别定制的操作, 比如说拷贝, snapshot, 或租赁.
Container表现得就如同是一种blob存储的安全边界一样. 默认地, 所有对blob存储的访问都要求一个密钥. 然而, 你可以针对某个container设置安全规则来修改这种行为, 从而允许匿名访问. 这里的安全访问检验规则是container级别的, 只针对blob的访问规则. container级别的访问与虚拟遍历和发现container内所有的blob. Blob-only访问需要明确blob的Uniform Resource Identifier (URI). 如果访问规则被移除了, 那么默认的行为改为再次要求提供密钥.
为了高效的分发blob内容, Windows Azure提供了content delivery network (CDN) (内容传递网络). CDN将经常被访问的blog数据存储到距离使用blob的应用程序近的地方. 比如, 如果一个视频在亚洲用户中特别受欢迎, 那么CDN会移动这个blob数据到地理上距离用户更近的服务器上. CDN是一个显式可选的blob特性. 使用这个特性会对你的帐单有影响, 即不是免费的. Figure 3 说明了blob是如何存储的. 一个账户持有blob container. 可以有多个container跟一个账户关联. container中持有blob数据.
Blob数据可以被分为两种类型: block blobs (块blob)和page blobs (页blob).
Block Blobs
每一个block blog都可以存储高达200GB的数据, 这么大块的数据被分为4MB大小的数据块. Block blob是为stream(流)数据负载而优化了的. 它们对大块的数据的表现很好, 比如说流媒体视频, 图片, 文档, 和代码. block blob的操作适合用于安全地上传大量信息. 比如说, 你可以使用API来并行地上传数据块. 并且, 如果有错误发生, 你还可以恢复具体的某个数据块的上传, 而不是整个数据集的上传都要恢复.
比如说, 如果你上传了一个10G的文件到blob存储中, 你可以把它拆分成4MB大小的块. 之后你就可以使用PubBlock函数来独立地上传每一块(或者为了增大吞吐量, 可以与其他块平行上传). 最后, 你可以通过PubBlockList函数书写所有的这些块成为一个可读的blob中. Figure4描述了这个例子.
Page Blobs
Page Blob有预定义的尺寸上限, 最大1TB, 由一系列的页面组成, 每个页面大小是512字节. Page blob的最佳用途是随机访问用于读/写的IO. 距离如PutPage方法的写操作必须与一个页保持对齐. 相反的, 读操作, 比如GetPage方法, 能够发生在某范围内的任何地址上. Page Blob的收费是按照实际包含的信息量而收取的, 而不是它为你保留的空间的大小. 如果你创建了1GB的包含两个page的blob, Windows Azure会收取你1KB的数据的钱. Figure5描述了基本的page blob读写操作.
Windows Azure Drives
-------------------------------------
Windows Azure Drives (驱动器)是按照NTFS格式化的单卷虚拟硬盘驱动器. 一个单独的role实例可以排他地以读写模式映射一个驱动器, 或者许多实例可以同时以只读方式映射到一个驱动器. 这两种选项是不能合并的, 即二选一. 典型地, 一个实例(instance)以读写模式映射一个驱动器, 然后定期为该drive抓取snapshot. 这个snapshot之后能够被同时以只读方式被其他实例所映射. 由于Windows Azure的驱动器的底层存储是page blob, 驱动器在被一个计算节点映射后, 所有由这个节点所写的信息都将被序列化到这个blob中. 获得驱动器的租赁(lease)后, 就可以写数据到blob中了. Lease(租赁)是Windows Azure存储的并发控制机制之一. 本质上说, 就是一个blob上的锁(lock). Windows Azure的驱动器对遗留下来的依赖于NTFS文件系统和标准IO库的老应用程序是很有用的. Page Blob上的所有操作都对Windows Azure Drive是可用的.
Figure 6 illustrates a Windows Azure drive.
Windows Azure Drive对于在一个role中运行的代码是可访问的. 写到Windows Azure驱动器中的数据是存储到一个page blob中的, 而这个page blob是Windows Azure Blob service定义的, 并且page blob是缓存在本地文件系统中的.
Windows Azure Tables
--------------------------------------------
Windows Azure table提供了可扩展的结构化存储方式. Table与一个storage account关联. Windows Azure Tables不像典型的关系数据库中的表. 它们没有实现relationship, 也没有schema. 相反, 每个存储在table中的entity都可以有一个不同的组成不同类型的属性集, 比如说string orint. Table的更新和删除使用了Optimistic concurrency , 而Optimistic concurrency 基于时间戳的. Optimistic concurrency 假设并发违反(concurrency violations )的情形不频繁, 并简单地禁止任何引发concurrency violations 的更新或删除动作. Figure7描述了table 存储.
存储在table中的所有实体(entity)都拥有三个属性: 一个PartitionKey, 一个RowKey, 和一个系统控制的属性-LastUpdate. 实体是由PartitionKey 和RowKey两个属性唯一标识的. LastUpdate属性是用来优化并发访问的.
Windows Azure监控PartitionKey 属性, 并在活动足够多的时候自动扩展table. 潜在地, 它能够通过在table中分布entity从而扩展table到上千个存储节点. PartitionKey 还确保了某些相关联的实体们总是放在一起的. 这意味着, 为partition key选择一个好的键值是非常重要的. PartitionKey 和RowKey的组合唯一标识了任何table中给定的entity.
指定了PartitionKey 和RowKey属性的对Windows Azure Table的一个查询只会返回一条entity. 任何其他类型的查询可能返回许多entity, 因为查询的条件并不保证符合条件的结果唯一. Windows Azure table存储返回在page中的数据(目前每次查询最多返回1000条entity记录). 如果需要取回更多数据, 返回的结果集中会包含可以被用于取回下个page的数据的continuation token (继续令牌).
Continuation tokens 直到没有更多数据空间可用了才会被返回回来. Table目前并不支持任何的聚合函数(aggregation function), 比如说Sum, 或Count. 即使你可以数一下行数, 或对某些列求和, 多数的这些操作都是在客户端搞定的, 并且需要扫描整个table的内容, 这种操作代价会比较大. 你应该考虑其他的方式, 比如预先计算好, 预先存储你需要的数据. 或者提供某些逼近真实情况的估计值.
对单个table的, 单个partition中的数据, tranction是支持的. 比如说, 你在一个单独原子操作中能创建, 删除, 或更新entity. 这种原子操作也被称作 batch operation(批量操作). Batch的有效载荷的上限是4MB. 与table交互有很多种API. 最高等级的API使用WCF数据服务. 在最低的层次, 你可以使用Windows Azure暴露出来的REST endpoint.
Windows Azure Queues
-------------------------------------
与你可以用来存储数据的blob和table不同, Queue是用来完成其他的意图的. 主要的用途就是允许web role跟worker role通信, 通知和约定工作这两种用途比较典型.
Queue提供了序列化的异步消息, 其中每个message(消息)最大可以有8KB长. 从queue中获取消息的应用程序应该被设计为幂等的(idempotent), 因为消息能被不止一次地被处理. 幂等的意思是一个操作可以被执行多次而不会改变结果. 获取消息的应用程序还应该被设计为可以读取毒消息(poison messages). 一条毒消息包含不正常的数据, 不正常的数据能够引发queue processor丢出异常. 结果是该消息不被处理, 保留在queue中, 并且下一次想要处理它的尝试会再一次失败. Figure 8描述了queue存储. 图中可见,storage account可以包含queue, 从而包含消息.
SDK中包含了一个实现了更高层次的抽象的domain模型. 你还可以使用REST endpoint来与queue互动.
SQL Azure
--------------------------------
SQL Azure是一个基于云的关系数据库管理系统(RDBMS). 目前它特点集中需要执行transaction的特性上. 比如说, 他提供了index, view, trigger, 还有stored procedures. 访问本地SQL Server的应用程序不需要什么修改(如果有的话, 也是一点点)就能使用SQL Azure. 客户还可以使用on-premise的软件, 比如说SQL Server Reporting Services来与SQL Azure协同工作.
你能通过许多种方式连接到SQL Azure上, 比如ADO, .NET, PHP, 或ODBC. 这意味着你今天用于开发数据库应用程序的方法跟SQL Azure的一样. 本质地, 如果你有一个放在云端的数据库, 你只需要简单地修改一下连接字符串即可.
应用程序可以跟数据库一起在云端, 也可以在on-premise中, 连接到位于云中的数据库. 第一个选项被叫做code near, 第二种叫做code far. 不管应用程序在那里, 它都是用名为Tabular Data Stream (TDS) 的在TCP/IP协议之上的协议来访问数据. 这跟访问本地SQL Server数据库的协议是一样的. SQL Azure包括一个安全特性, 该安全特性能够限制特定IP范围的机器来访问数据库. 这样, 你就可以指定期望的访问数据库的机器的IP, 从而在网络层次拒绝掉其他的所有请求.
要访问SQL Azure, 你必须在http://sql.azure.com创建一个账户. 每个账户可以有一个或多个逻辑服务器, 这些服务器被实现为一个地理位置的多台物理服务器. 每个逻辑服务器可以有一个或多个数据库, 这些数据库被实现为分区的数据(partitioned data ), 分布在多台物理机上.
首先, 你在SQL Azure服务器管理界面创建一个数据库, 这个管理界面在web portal可以找到. 你还可以使用例如SQL Server Management Studio 的工具来创建数据库, 添加元素(user-defined objects, tables, views, 和indexes), 或者修改防火墙设定.
SQL Azure三种DB的尺寸选择, 1 GB, 10 GB, 和50 GB. 你的站但是基于数据库大小的, 而不是你实际存储的数据量.
Management Services
------------------------------------
Windows Azure的主要目的是让应用程序拥有者的生活变得简单. 达到这个目标的方法之一是提供一层自动化的服务管理. 通过这种服务, 开发人员创建应用程序, 部署它到云端. 开发者还配置服务配置和约束. 这些动作完成之后, Windows Azure负责运行服务和维护该服务的健康状态. Windows Azure还提供了执行许多操作的能力, 比如说监控应用程序和管理storage account, 管理hosted service, service deployments和affinity group. 你既可以通过web portal来执行这些操作, 或者通过基于REST的API来编程来执行动作. API使用与web portal不同的认证方式. 所有的编程调用都是用x509客户端证书来进行认证. 用户可以上传任何合法的x509证书到Windows Azure developer portal门户网站, 之后使用它作为客户端进行API调用时使用的认证证书.
注意: 这里讨论的Windows Azure management API指的是专门为Windows Azure组件(计算和存储)而开放的API. 平台的其他API(比如SQL Azure和AppFabric)有他们自己的一套管理界面.