本文转自:http://technet.microsoft.com/zh-cn/magazine/jj717232.aspx
英文版:http://msdn.microsoft.com/library/azure/jj717232.aspx
作者:Mark Simms 和 Michael Thomassy
供稿作者:Jason Roth 和 Ralph Squillace
审阅者:Brad Calder、Dennis Mulder、Mark Ozur、Nina Sarawgi、Marc Mercuri、Conor Cunningham、Peter Carlin、Stuart Ozer、Lara Rubbelke 和 Nicholas Dritsas。
云计算是一种分布式计算,而分布式计算所需要的是缜密的规划和传递,而与平台选择无关。本文档的目的是基于真实的客户案例提供一个成熟的指导方针,以方便客户在 Azure 和 SQL Database 上构建可扩展的应用程序,以及实施平台即服务 (PaaS) 方案,在这种方案中需要借助 Web 角色和辅助角色将应用程序构建成为 Azure 云服务。
重要提示 |
---|
注意:本文中的所有最佳实践指导均源自与在 Azure 上运行生产代码的客户之间的深入合作。本文仅讨论基于 SDK 1.6 版本的 Azure 云服务 (PaaS) 平台,而不涵盖将来的功能,如 Azure 网站或 Azure 虚拟机 (IaaS)。
|
本文档介绍有关构建 Azure 应用程序的基础设计概念、关键的 Azure 平台功能、限制和特性,以及使用核心 Azure 服务的最佳实践。重点介绍那些适合松散一致的分布式数据存储区的应用程序(与严格一致或高密度的多租户数据模型相对)。
出于多种原因,将应用程序和服务的一些环节转换为 Azure 可能很有吸引力,例如:
从技术方面而言,也有许多极好的理由,要求我们开发新的应用程序或将现有应用程序的某些部分或全部内容移植到 Azure。由于环境具有许多可选的实现方法,因此,你必须仔细地评估你具体的应用程序模式,以便选择正确的实现方法。一些应用程序非常适合 Azure 云服务(这是平台即服务或 PaaS 方法),而其他一些应用程序可能受益于部分或完整的基础结构即服务(或 IaaS)方法,如 Azure 虚拟机。最后,结合使用这两者可能能够最好地满足某些应用程序的要求。
你的应用程序应具有以下三个关键环节的一个或多个,以便最大限度地发挥 Azure 云服务的优势。(并非所有这些环节都需要出现在你的应用程序中;一个应用程序可能只需以下这些环节之一就能够非常充分地利用 Azure,从而带来巨大的投资回报。但是,如果工作负荷没有展现任何这些特性,则它可能并不是非常适合 Azure 云服务。)
评估应用程序时应考虑的重要环节包括:
重申一遍:当评估你的应用程序时,如果你的工作负载仅具有在平台即服务环境(如 Azure 云服务)中起重要作用的上述三个环节之一,则过渡到 Azure 云服务或在此类服务之上构造应用程序会带来较高的投资回报。如果应用程序具有所有这三个特性,则你将有望获得非常高的投资回报。
尽管为 Azure 设计应用程序的许多环节与内部开发非常相似,但在基础平台和服务的行为方面存在若干关键差异。了解这些差异进而了解如何根据(而不是针对)平台进行设计,对于交付能够在云中实现弹性扩展的应用程序而言是至关重要的。
这一部分概括了五个关键概念,这些概念对于为平台即服务 (PaaS) 环境(如 Azure 云服务)构建大规模、广泛分布的向外扩展应用程序而言是至关重要的设计点。了解这些概念将帮助你设计和构建满足以下要求的应用程序:它们不仅在 Azure 云服务上运行,还能在此类服务上发展壮大,从而使你的投资获得尽可能高的回报。本文档后面讨论的所有设计注意事项和选择都会与这五个概念之一有密切联系。
此外,值得注意的是,尽管可以从 .NET 应用程序的角度来查看其中许多注意事项和最佳实践,但基础概念和方法大体上是不区分语言或平台的。
从内部应用程序转向 Azure 云服务的主要变迁与应用程序如何扩展密切相关。构建较大型应用程序的传统方法依赖于将向外扩展(无状态的 Web 和应用程序服务器)与向上扩展(购买较大的多核心/大内存系统、数据库服务器以及构建较大型的数据中心等)相结合。在云中,向上扩展是一个不太现实的选项;实现真正可扩展的应用程序的唯一途径是明确设计向外扩展。
随着内部应用程序的许多元素已适于进行向外扩展(Web 服务器、应用程序服务器),挑战在于如何确定应用程序中依赖于向上扩展服务的环节,并将其转换(或映射)到向外扩展实现。向上扩展依赖性的主要候选元素通常是关系数据库 (SQL Server/Azure SQL Database)。
传统的关系设计主要围绕着全局连贯的数据模型(单一服务器向上扩展)以及严格的一致性和事务行为。针对此支持存储区,传统的扩展方法一直是“使所有元素都变得无状态”,并将管理状态的责任推延到向上扩展 SQL 服务器。
不过,SQL Server 的可扩展性虽然很强大,但是缺乏真正灵活的扩展。也就是说,它无法提供响应性极高的资源可用性,而是必须购买较大的服务器以及执行代价高昂的迁移阶段,使容量大大超过需求,并且每次都要扩大向上扩展的规模。此外,当扩展以前的中等规模硬件时,成本曲线呈指数上升。
而当 Azure 云服务的基础结构进行扩展时,应用程序需要设计为使用向外扩展数据存储区。这样就会引发一些设计难题,例如,显式将数据分区到较小的块区(每个块区适合一个数据分区或向外扩展单元)以及管理分布式数据元素之间的一致性。这种通过分区实现扩展的方法,避免了设计为向上扩展的许多缺点。
从众所周知的向上扩展方法转向向外扩展数据和状态管理,通常是针对云进行设计的最大障碍之一;解决这些难题并设计应用程序以充分利用 Azure 云服务和 Azure SQL Database 的可扩展、灵活的功能来管理持久数据,这是本文档中大量内容的焦点。
当你运行自己的数据中心时,你具有几乎无限的控制度,同时具有几乎无限的选择。从实际场所(空调、供电、空间)到基础结构(机架、服务器、存储设备、网络等)的任何事物,直至配置(路由拓扑、操作系统安装),一切都在你的控制之下。
这种控制度也带来了各方面的成本 – 资金、运营、人力和时间。在灵活和不断变化的环境中管理所有细节的成本是转向虚拟化的过程的核心,也是转向云的征程中的一个关键环节。作为对放弃控制度的回报,这些平台降低了部署、管理的成本并提高了灵活性。它们所产生的约束在于:可用组件和服务的规模(容量、吞吐量等)限制在一定量之内。
打个比方来说,商业散装货运主要依赖于集装箱。这些集装箱可以装在各种运输工具(轮船、火车和卡车)上,并且有各种标准尺寸(最长为 53 英尺)。如果你要装运的货物量超过了最大拖车的容量,则你需要:
从这个比方可以看出,在 Azure(通常是云计算)中,每种资源都有一个限值。无论是单独的角色实例、存储帐户、云服务或甚至是数据中心 – Azure 中的每个可用资源都具有某种确定的限制。有些可能是非常大的限制,如数据中心内可用的存储空间量(类似于最大的驳船可装运超过 10,000 个集装箱),但它们也是有限的。
有了这个概念后,扩展的方法将是:对负载进行分区,然后拆分组合到多个扩展单元(多个 VM、数据库、存储帐户、云服务或数据中心)。
在本文中,我们使用术语“扩展单元”来指示满足以下条件的一组资源:(a) 处理一定程度的负载;(b) 组合在一起来处理附加负载。例如,一个 Azure 存储帐户的最大大小为 100 TB。如果你需要存储超过 100 TB 的数据,你将需要使用多个存储帐户(也即,至少两个存储扩展单元)。
后面的章节将讨论 Azure 的每个核心服务或组件的常规容量设计指南,以及用于组合这些服务以实现附加扩展的建议方法。
在内部构建高度灵活的应用程序已投入了大量的时间、精力以及智力资本。通常,这归根结底是将应用程序拆分为低状态组件(应用程序服务器、网络)和高状态组件(数据库、SAN),并使每个组件可灵活地应对故障模式。
在这一上下文中,故障模式指的是以下两者的组合:(a) 观察到系统处于故障状态;(b) 故障原因所导致的结果。例如,由于错误地配置了密码更新而导致数据库无法访问就是故障模式;故障状态是无法连接(拒绝连接,不接受凭据),而故障原因是无法与应用程序代码正确通信的密码更新。
低状态组件借助于集成到由外部系统管理的系统,通过松散偶合的冗余性来提供灵活性。例如,在负载平衡器之后放置其他 Web 服务器;每个 Web 服务器与其他 Web 服务器完全相同(使添加新容量变成只是克隆基本 Web 服务器映像的过程),并集成到由负载平衡器管理的整体应用程序中。
而高状态组件则借助于集成到由组件之间紧密管理的系统,通过紧密偶合的冗余性来提供灵活性。以下是一些示例:
基于紧密耦合方法的灵活性解决方案本身就比松散耦合的“添加更多克隆项”的方法更昂贵,因为前者要求经过良好培训的人员、专门的硬件以及仔细的配置和测试。这不仅难以实现,而且实现起来也成本高昂。
这种专注于确保硬件平台高度灵活的方法也可称为“钛金蛋壳”。为了保护蛋里的内容,我们用一层坚固(但昂贵)的钛金覆上了一层壳。
大范围运行系统的经验(有关进一步的讨论,请参阅 http://www.mvdirona.com/jrh/TalksAndPapers/JamesRH_Lisa.pdf)表明,在任何足够大的系统(如处于 Azure 范围内的数据系统)中,物理上处于运动状态的部件总数导致系统的某些部分始终处于易于破坏的状态。Azure 平台的设计已规避了这一局限性,这种设计不是消除这种局限性,而是依赖于从节点级的故障事件中自动恢复。这种设计意图贯穿所有核心的 Azure 服务,它对于设计可使用 Azure 可用性模型的应用程序而言至关重要。
转换到 Azure 后,灵活性会话从基础结构冗余性挑战变为服务冗余性挑战。对内部可用性计划起支配作用的许多核心服务在 Azure 中“仅仅维持正常工作”:
但是,这一部分的主旨是可用性,而不是灵活性。灵活性只是在 SLA 的范围内持续向用户交付价值的总体过程的一部分。如果服务的所有基础结构组件运行状况均正常,但该服务无法处理预期的用户量,则此服务不可用,也无法交付价值。
以移动设备或社交为中心的工作负荷(如公共 Web 应用程序以及移动设备应用程序)与面向固定受众的工作负荷相比,前者的动态程度要高得多;这种工作负荷要求采用更高级的方法来处理大量突发事件和峰值负载。本文档通篇介绍为 Azure 应用程序设计可用性时要记住的关键概念,这些概念基于以下要点:
这些高级概念将在描述核心 Azure 服务的每个章节中详细说明,同时还有适用于每个服务或组件的可用性目标以及如何针对可用性进行设计的建议。请记住,数据中心仍然是大型应用程序的单一故障点;从电源错误(请在此处查看示例)到系统错误(请在此处查看示例),基础结构和应用程序问题都会导致数据中心崩溃。要求最高级别正常工作时间的应用程序应部署在多个冗余的数据中心内,但这种情况极为罕见。
在多个数据中心部署应用程序要求若干基础结构和应用程序功能:
关于可用性,(在数据中心丢失的情况下)提供灾难恢复解决方案需要大量的时间、精力和资金。这一部分将集中讨论在面对系统故障和数据丢失(无论是系统触发还是用户触发)时提供业务连续性的方法和注意事项,因为术语“灾难恢复”围绕着数据库连续性的实施方法具有特定的含义。
交付业务连续性的过程可分解为:
前两个元素传统上已在地理灾难恢复 (geo-DR) 的上下文中得以解决,而第三个元素则属于数据备份和数据还原的领域。
Azure 大大改变了关键业务系统可用性的平等分布方式,从而能够快速将关键应用程序部署到地理上分散的全球各数据中心。事实上,发布地理上分布的应用程序与发布单个云服务的过程之间的差异并不明显。
关键的难题仍然是管理对持久状态的访问;跨数据中心访问持久状态服务(如 Azure 存储和 SQL Database)通常会因延迟较高和/或不确定而导致结果达不到最佳状态,从而在数据中心发生故障时无法满足业务连续性要求。
对于灵活性,许多 Azure 服务提供(或者在其路线图中具有)自动地理复制功能。例如,除非另行专门配置,否则所有写入 Azure 存储(blob、队列或表)中的内容都会自动复制到另一个数据中心(每个数据中心在同一个地理区域内都有一个特定的“镜像”目标)。这大大减少了在 Azure 基础之上提供传统灾难恢复解决方案所需的时间和努力。后面的章节概述管理持久状态的核心 Azure 服务的地理复制功能。
为了在面对用户错误或操作员错误时维护业务连续性,在应用程序设计中应考虑若干其他注意事项。尽管 Azure 存储通过“存储分析”功能提供了有限的审核功能(在后面的章节中介绍),但它没有提供任何时点还原功能。在面对意外删除或修改时要求灵活性的服务将需要考察以应用程序为中心的方法,如定期将 blob 复制到其他存储帐户。
SQL Database 提供了用于维护数据的历史快照的基本功能,包括 DB 复制以及通过 bacpac 导入/导出。本文档后面将详细讨论这些选项。
借助于 Azure 平台提供的灵活扩展,供给曲线可以与需求曲线密切匹配(而不是用大量额外容量来满足峰值负载)。
借助灵活扩展,商品成本由以下各因素驱动:
我们将针对给定容量可执行的工作量称为应用程序的密度。服务和框架的密度越大,针对给定的资源部署执行的工作量就越大;也就是说,提高密度后会减少所部署的容量(和成本),或者能够以相同的部署容量吸收附加负载。密度由两种主要因素驱动:
除了针对单一计算机(或数据库)使用的传统优化方法之外,优化分布式通信和操作对于交付可扩展、高效的 Azure 服务而言是至关重要的。后面的章节将详细介绍这些关键的优化:
在前一节中,我们介绍了要构建利用由 Azure 提供的云结构的应用程序,应涉及的关键设计概念和观点。本节将讨论核心平台服务和特性,阐述其功能、扩展边界和可用性模式。
因为每个 Azure 服务或基础结构组件都通过可用性 SLA 提供有限的容量,所以,了解这些限制和行为对于为你的可扩展性目标和最终用户 SLA 做出适当的设计选择而言至关重要。每个核心 Azure 服务都体现为以下四个中心环节:功能及其意图、密度、可扩展性和可用性。
Azure 订阅是最基本的管理、结算和服务配额单元。每个 Azure 订阅都具有一组默认配额,旨在防止意外覆盖或占用资源,但你可以通过与支持部门联系来增加这些配额。
每个订阅都有一个帐户所有者和通过 Microsoft 帐户(以前称为 Live ID)授权的一组联合管理员,他们通过管理门户对订阅中的资源具有完全控制权。他们可以创建存储帐户、部署云服务、更改配置,并可以添加或删除联合管理员。
Azure 管理 API(基于 REST 的 Web 服务)提供了一个自动执行界面,用于创建、配置和部署 Azure 服务(由管理门户在后台使用)。对这些 API 的访问是使用管理证书来限制的。
服务 | 默认限制 |
---|---|
云服务 |
20 |
存储帐户 |
20 |
Cores |
20 |
SQL Database 逻辑服务器 |
5 |
提示 |
---|
有关最新的 Azure 订阅和服务限制,请参阅 Azure 订阅和服务限制、配额与约束
|
Azure 云服务(以前称为托管服务)是基本的部署和扩展单元。每个云服务都由两个部署(生产和临时)组成,每个部署具有一组角色。云服务对于生产部署具有公共 DNS 条目(格式为 servicename.cloudapp.net),并具有一个临时部署 DNS 条目(格式为 someguid.cloudapp.net)。
每个部署都包含一个或多个角色(要么是 Web 角色,要么是辅助角色),它们反过来又包含一个或多个实例(非持久 VM)。每个实例都包含该角色的软件包的一个完全相同、不可变、非持久的快照(也即,给定角色的所有实例都部署了完全相同的内部版本)。这些实例运行 Windows Server 针对 Azure 专门推出的版本(默认情况下为提高安全性禁用了许多服务,配置为与 Azure 网络和服务结构等很好地协作),并且默认情况下由 Azure 结构自动进行修补。实时修补是通过滚动升级方案来处理的,介绍如下。
云服务可以部署到任何 Azure 数据中心,可以直接部署(在创建服务时选择目标区域),也可以通过关联组。关联组是对部署目标的间接引用,而部署目标可用来简化将应用程序的所有组件部署到相同数据中心的过程。
Web 角色预配置了 IIS 实例,该实例承载着应用程序代码。辅助角色中承载的应用程序代码在预配置的长期运行的应用程序主机中执行。每个云服务可能最多具有 25 个角色。角色默认配置是执行 .NET 代码,但角色可配置为运行与 Windows Server 兼容的任何代码– Java、Python、Ruby、node.js 等等。本文档中提到的所有平台功能都可以从任何平台中获得,但可能要求进行额外的客户端-代理开发以指向基于 REST 的 API。
在云服务内,所有实例都分配有专用 IP 地址(在 10.x 块中);所有传出连接看起来都是通过网络地址转换来自单个虚拟 IP 地址或 VIP(这是云服务部署的 VIP)。入站连接必须经由已配置的端点;这些端点针对内部角色和端口提供负载平衡的访问。例如,默认情况下,到云服务部署的入站 HTTP/HTTPS(端口 80 和 443)连接针对主 Web 角色的所有可用实例实现了负载平衡。
请注意,跨服务延迟(也即,使 NAT 跨越一个云服务并通过负载平衡器进入另一个云服务)比内部延迟相比,前者的可变程度要高得多,它是鼓励进行批处理或大批量跨服务连接以实现可扩展性的原因之一。
Azure 结构还为云服务部署中的所有实例提供了可用的配置服务。服务定义中提供了一组预期的静态配置参数(作为开发周期的一部分),并提供了在将服务发布到 Azure 时随服务一起部署的一组初始配置值。这组配置值可用作针对服务部署中的所有实例的运行时查找,可以在运行时通过 REST 接口、Azure 门户或 PowerShell 脚本进行修改。
当更改运行时配置时,所有实例可以选择(在应用程序代码中)挂接配置更改通知并在内部处理配置更新。如果应用程序代码未配置为捕获配置更改事件,则此角色中的所有实例都将遇到滚动重新启动,以更新其配置。
每个实例的状态都是非持久的;基本 Azure 映像(专门的 Windows Server VM)之上的任何配置都要求启动时配置,以创建性能计数器、优化 IIS 设置、安装依赖软件等等。这些配置脚本通常作为由云服务配置定义的启动任务来运行。
在云服务内部,Azure 结构提供有关配置、内部 IP 地址、服务配置等的信息,而此结构是通过 RoleEnvironment 提供的。在 Azure 实例之上运行的所有进程都可以访问 RoleEnvironment 信息,以检索配置、发现网络拓扑等等。你还可以使用 Azure 管理 API 从外部访问此信息。
Azure 结构提出了两个用于管理组件故障、重新配置以及升级/修补的核心概念:升级域和故障域。
升级域是 Azure 服务内的逻辑分组;默认情况下,每个服务都具有五 (5) 个升级域(可以在云服务定义中修改此值)。任何服务更改或升级一次只影响单一升级域。这些更改的示例包括修补操作系统、更改虚拟机大小、向正在运行的服务添加角色或角色实例、或者修改端点配置。
这样,就可以在保持可用性的同时实时重新配置正在运行的云服务。对于仅包含单个实例的角色,Azure 结构在升级操作期间无法提供可用性,这就是为何运行单一实例角色无法满足 Azure SLA 的原因。
故障域是基于基础硬件的逻辑分组。尽管无法保证直接映射到任何特定的硬件配置,但应将逻辑分组视为 Azure 结构自动将实例从表示单点故障(如单一基础物理服务器、机架等)的基础资源中分离的方法。为了满足服务 SLA,Azure 需要至少将实例部署到两个故障域。这是单一实例角色部署无法满足 Azure SLA 的另一个原因。
总结如下:
每个角色都包含一组实例(由一个或多个实例组成)。其中每个实例都是虚拟机,运行 Windows Server 的一个特定版本。实例(虚拟机)当前有五种规模:特别小一直到特别大。其中,每种规模都分配了一定量的 CPU、内存、存储空间和带宽。
虚拟机规模 | CPU 内核数 | 内存 | Web 角色和辅助角色的本地存储资源磁盘空间 | 虚拟机角色的本地存储资源磁盘空间 | 分配的带宽 (Mbps) |
---|---|---|---|---|---|
特别小 |
共享 |
768 MB |
19,480 MB (6,144 MB 预留用于系统文件) |
20 GB |
5 |
小型 |
1 |
1.75 GB |
229,400 MB (6,144 MB 预留用于系统文件) |
165 GB |
100 |
中型 |
2 |
3.5 GB |
500,760 MB (6,144 MB 预留用于系统文件) |
340 GB |
200 |
大型 |
4 |
7 GB |
1,023,000 MB (6,144 MB 预留用于系统文件) |
850 GB |
400 |
特别大 |
8 |
14 GB |
2,087,960 MB (6,144 MB 预留用于系统文件) |
1890 GB |
800 |
提示 |
---|
有关最新的 Azure 订阅和服务限制,请参阅 Azure 订阅和服务限制、配额与约束
|
当两个或更多实例部署在不同的故障域和升级域中时,Azure 为云服务提供以下 SLA:
角色实例大小和计数在运行的应用程序中可能动态发生变化(注意,更改角色实例大小将触发滚动重新部署)。在给定用于构建 Azure 应用程序的向外扩展方法的情况下,当需要选择实例大小时,并非实例越大就一定越好。这一点同时适用于成本(为你不使用的功能付费)和性能(取决于你的工作负荷是 CPU 绑定、I/O 绑定等等)。本文档的“最佳实践”部分将更详细地探讨实例数目和实例大小。
Azure 存储是 Azure 的基线持久数据服务,提供 blob(文件)、队列和表存储(键到值)。存储帐户是扩展和可用性的基本单元,同时提供以下功能。与存储设备之间的所有通信均基于通过 HTTP 的 REST 接口。
提示 |
---|
有关最新的 Azure 订阅和服务限制,请参阅 Azure 订阅和服务限制、配额与约束
|
Azure 存储可用性 SLA 保证,在至少 99.9% 的时间内,经过正确格式化的用于添加、更新、读取和删除数据的请求将成功并正确地得到处理,此外,存储帐户与 Internet 网关之间保持连接。
在任何情况下使用此单独存储帐户都会遵循这些限制;也即,每秒操作数和总体带宽在表、blob 和队列之间共享。如果应用程序超过每秒总操作数,则服务可能返回 HTTP 代码(503 服务器忙)。操作特定于每个存储环节(表、队列或 blob),下面各小节将介绍这些内容。
根据前面的集装箱比方,每个存储帐户都是一个可提供一定容量的集装箱。超过单个帐户(集装箱)的限制就要求在同一个应用程序中利用多个帐户。
Azure 存储默认情况下提供了可用性和灵活性;所有写入或更新 Azure 存储的操作都在三个存储节点间透明、一致地复制(这三个节点处于不同的升级域和故障域中)。对 Azure 存储的访问是以访问密钥方式以单因素身份验证来控制的。每个存储帐户都具有主密钥和辅助密钥,这样就可以在循环主密钥时实现持续可用性。Azure 存储中的数据可自动通过地理复制而复制到“镜像”数据中心(除非使用门户专门禁用此功能)。地理复制是不透明的,在主数据中心出现故障的情况下,利用 DNS 重定向将客户端故障转移到辅助位置。
请注意,尽管 Azure 存储通过自动化副本提供了数据复原功能,但这不会防止你的应用程序代码(或开发人员/用户)因为意外或无心的删除、更新等操作而造成数据损坏。在遇到应用程序或用户错误时保持数据保真需要更为先进的技术,如将数据和审核日志复制到辅助存储位置。Blob 存储提供了快照功能,这一功能可在 blob 内容的时间快照中创建只读点,这可用作 blob 的数据保真度解决方案的基础。
Azure 存储通过其存储分析功能提供了遥测功能,同时收集和公开有关针对表、队列和 blob 的单独存储调用的使用情况数据。需要使用收集策略(收集所有内容、仅搜集表等等)和保留策略(保留数据的时间长度)针对每个存储帐户启用存储分析。
Blob 存储在 Azure 中提供了文件管理服务,同时提供可用性高、经济高效的方法来存储成批的未结构化数据。此服务提供两种类型的 blob:
下表中列出了 blob 存储的设计限制。请记住,所有这些操作都针对总体存储帐户限制进行计数。
Blob 类别 | 限制 |
---|---|
最大 blob 大小(块) |
200 GB(50k 个块) |
最大块大小 |
4 MB |
最大 blob 大小(页) |
1 TB |
页大小 |
512 字节 |
最大带宽/blob |
480 Mbps |
当超出单个 blob 的大小或带宽限制后,应用程序可以写入多个并发(或序列)blob 文件。如果你的应用程序超出单个存储帐户的限制,请利用多个存储帐户以提供更多容量。
Azure 队列在发布服务器与订阅服务器之间提供中间(中转)消息传递服务。队列支持多个并发发布服务器和订阅服务器,但自身并不公开较高顺序的消息传递基元(如发布/订阅或基于主题的路由)。它们通常用于将工作项(如消息、文档、任务等)分发到一组辅助角色实例(或在多个托管服务等之间分发这些工作项)。
如果应用程序未检索和删除队列消息,则 7 天后将自动删除这些消息。它们在信息的发布服务器与使用方之间提供解除关联功能;只要双方都具有存储帐户密钥和队列名称,它们就可以通信。
队列类别 | 限制 |
---|---|
队列中的最大消息数 |
无(最大为存储帐户限制) |
消息的最大生存期 |
1 周(自动清除) |
最大消息大小 |
64 kB |
最大吞吐量 |
每秒高达 500 条消息 |
队列旨在传递控制消息,而非原始数据。如果你的消息过大而无法放入一个队列中,则可以重构消息以便分离数据和命令。将数据存储在 blob 存储中,添加对存储在队列消息中的数据和意图的引用 (URI)(意图也即 blob 存储中的数据的用途)。
为了提高单个队列中的吞吐量,请在单一消息内批处理多条消息,然后利用“更新消息”命令来跟踪封装消息的任务的进度。另一种方法是将多条消息放入一个 blob 中,并由一个指针指向队列消息中的 blob。
如果你的应用程序需要的吞吐量高于单个队列所能提供的吞吐量,则利用多个并发队列。在这一上下文中,你的应用程序必须实现适当的分区和路由逻辑。
Azure 表存储为列(二维)数据提供了持久性高、可扩展性高且一致的存储区。它提供了 { partition key, row key } -> { data[] } 语义以存储和访问数据,如下图中所示。每个表都按分区进行分解,而分区中包括实体。每个实体都有其自己的(平面)架构或属性列表(列)。
每个分区每秒支持高达 500 个操作;反过来,每个表最高支持存储帐户中提供的最大操作数。因为每个实体不仅包含实际数据,还包含列元数据(因为每个实例可能具有不同架构),所以不建议采用长列名,尤其对于大型方法。
表类别 | 限制 |
---|---|
每个分区每秒最大操作数 |
500 |
最大实体大小(列名 + 数据) |
1 MB |
最大列大小(byte[] 或字符串) |
64 kB |
最大行数 |
无(最大为存储帐户限制) |
支持的数据类型 |
byte[]、Boolean、datetime、double、Guid、int32、int64、string |
各实体(你可以将其视为行)的最大大小为 1 MB,各列的最大大小限制为 64 kB。上表中列出了支持的数据类型;对于不支持的类型(如 DateTimeOffset),你的应用程序代码中需要一个序列化代理(例如,以标准字符串格式存储 DateTimeOffset)。
表存储使用与分区和实体、分区扫描或实体扫描关联的键来提供对所存储数据的访问。它支持筛选器投影,因为筛选表达式可以作为查询的一部分推送到表存储,并在表存储中执行。表存储不提供辅助索引,因此,任何非基于分区键或实体键的查找都要求进行表扫描和/或分区扫描。对于包含大量实体的分区,这通常对性能有重大影响。
任何超过 5 秒的查询处理都会返回一个继续标记,而应用程序可以使用此继续标记来继续接收查询的结果。检索的实体数超过 1,000 的查询必须利用分页模型,以便将数据返回到包含 1,000 个实体的块中(表存储 API 本身就支持块)。
目前对于表存储支持的唯一查询表达式是筛选和选择(选择特定属性);表存储不提供服务器端聚合或分组语义。为了构建要求丰富的聚合或分析功能的应用程序,通常更好的选择是以聚合格式存储数据或使用关系引擎(如 Azure SQL Database)。某些应用程序采用混合方法,将表存储中的数据聚合到一个辅助 SQL Database 中,然后用于查询和报告目的。
选择适当的分区函数对于高效和有效地利用表存储而言至关重要。对于分区函数的类型,有两种主要选择:
任何重要的应用程序都要求使用多个分区。甚至对于具有总实体数中少量实体的表(如 200 个实体),如果应用程序每秒将发出几千个请求,则需要用多个分区才能满足吞吐量要求。
一旦选择,则数据达到重新平衡(重新分区)可能会非常昂贵,这涉及读取和复制具有新分区键的所有实体,然后删除旧数据。请注意,分区没有最小大小限制;分区可以由单个实体(也即行)组成。
如果你的应用程序需要的吞吐量高于单一表所能提供的吞吐量(在仔细选择分区之后),请在不同的存储帐户中利用多个并发表。在这一上下文中,你的应用程序需要实现适当的路由逻辑,以便选择适当的存储帐户。
Azure 内容传送网络 (CDN) 提供了一种高效的方法,在全球分布的缓存网络中缓存静态内容(从 blob 或应用程序输出)。这会减轻应用程序传送静态内容的压力,并改进总体最终用户体验。
内容传送网络可用性 SLA 确保按月以 99.9% 的可用性传送缓存的对象。
使用 CDN 要求为你的订阅激活此功能。在此,可以缓存 blob 内容(来自公开提供/匿名访问容器)和匿名应用程序输出内容(例如 http://www.myapp.com/cdn/somepage.aspx)。
通常,对于任何大规模的应用程序,所有常访问的静态内容(图片、css 等等)都应通过 CDN 并借助适当的缓存到期策略来进行传送。
例如,考虑一个具有一百万册书的在线电子书商店。在 CDN 中包括所有图书的内容(图片等)将会非常昂贵(因为绝大多数内容都不会频繁访问并且会持续过期),而只加入前面的内容(例如,前 50 本图书)将使缓存与价格之间达到最佳组合。
成功传送大规模服务的核心元素之一是遥测,也即深入了解应用程序的操作、性能和最终用户体验。Azure 应用程序的遥测方法需要同时考虑平台的向外扩展/分布式性质,以及可用于收集、分析和使用遥测的平台服务。
Azure 中用于收集和理解遥测的基本计数组件是 Azure 诊断 (WAD)。WAD 由一个代理以及一组用于存储和访问数据的标准结构和约定组成,而代理负责从各个实例收集数据并将它们转发至一个中心收集点(存储帐户)。代理支持若干配置方法,包括代码 (.NET)、在部署的项目代码内嵌入的配置文件或部署到 blob 存储的集中化的配置文件。配置在最后的实例中一定程度上是动态的,以便允许将更新后的诊断文件推送到 blob 存储,然后向下拉取到目标代理。
WAD 配置面向若干数据源而提供;其中每个数据源都定期进行收集、通过用于 Windows 的事件跟踪(称为 ETW)会话进行批处理,并发布到目标存储帐户。代理负责处理临时连接问题、重试等其他事项。可用数据源如下所示:
以上每种数据源都配置有要收集的数据子集(例如,性能计数器列表)以及收集/发布时间间隔。还可以通过一些 PowerShell 脚本来更改运行时配置,或强制从代理向目标存储帐户立即发布数据。
重要提示 |
---|
将遥测数据记录到单独的存储帐户中。将遥测数据和应用程序数据记录到同一存储帐户中将导致大规模的严重争用问题。
|
Azure SQL Database 提供数据库即服务,支持应用程序快速设置关系数据库、向其中插入数据以及查询该数据库。它提供许多熟悉的 SQL Server 功能,同时减少了硬件、配置、修补和复原方面的负担。
备注 |
---|
SQL Database 并不提供与 SQL Server 一一对应的功能,其目的在于满足专门适用于云应用程序的一套不同的要求(通过弹性扩展、数据库即服务来降低维护成本等)。有关详细信息,请参阅 http://blogs.msdn.com/b/windowsazure/archive/2012/06/26/data-series-sql-server-in-windows-azure-virtual-machine-vs-sql-database.aspx。
|
该服务运行在多租户共享环境中,其中的数据库来自基于商用硬件构建的基础结构上运行的多个用户和订阅(横向扩展,而非纵向扩展)。
数据库设置在逻辑服务器内部;每个逻辑服务器默认包含最多 150 个数据库(包括 master 数据库)。默认情况下,每个订阅可以设置五 (5) 个逻辑服务器;但通过调用支持可以提高此限额以及每个逻辑服务器包含的最大数据库数。
每个逻辑服务器都分配有一个公共的唯一生成的 DNS 名称(格式为 [服务器名称].database.windows.net),订阅中的每个逻辑服务器都共享同一个公共 IP 地址。通过标准的 SQL 端口 (TCP/1433) 访问逻辑服务器(和数据库),同时通过基于 REST 的管理 API 访问端口 TCP/833。
默认情况下,限定只能根据针对 Azure 管理门户的基于 IP 的防火墙规则来访问逻辑服务器及其中的所有数据库(可以针对逻辑服务器或单个数据库设置规则)。若要支持访问 Azure 应用程序以及从 Azure 外部直接连接应用程序(例如,连接 SQL Server Management Studio),需要配置防火墙规则。可以通过 Azure Web 管理门户使用管理服务 API 调用来配置这些规则。
SQL Database 提供 SQL Server 中现有的多数关键功能,但也有一些重要的例外情况,包括:
每个数据库在创建时,都配置了大小上限。当前可用的容量上限包括 1 GB、5 GB、10 GB、20 GB、30 GB、40 GB、50 GB、100 GB 和 150 GB(当前可用的最大容量)。当数据库达到大小限制时,它会拒绝其他 INSERT 或 UPDATE 命令(仍然可以查询和删除数据)。还可以通过发出 ALTER DATABASE 命令来创建数据库大小(增大或缩小)。
由于要依据每天使用的平均大小对数据库计费,预计快速增长或增长不可预测的应用程序可以选择将数据库最大容量最初设置为 150 GB。将数据库扩展至 150 GB 以上需要利用横向扩展方法,下一节将对此进行详细介绍。
SQL Database 为节点级别的故障提供内置的故障恢复功能。所有写入数据库的内容会使用仲裁提交技术自动复制到两个或多个背景节点(主要副本和至少一个辅助副本必须先确认活动写入事务日志,然后才将事务视为成功并返回)。在节点失败时,数据库会自动故障转移到其中一个辅助副本。这将导致客户端应用程序出现暂时性连接中断,这就是为何所有 SQL Database 客户端都必须执行某种形式的暂时性连接处理的主要原因之一(请参阅下文,了解有关执行暂时性连接处理的详细信息)。
月度可用性 SLA 要求 99.9% 的正常运行时间,即要求能够在 5 分钟的时间间隔内于 30 秒内连接到 SQL Database。上一段中所述的故障转移事件通常出现的时间不超过 30 秒,这更加迫切地需要你的应用程序能够处理暂时性连接故障。
SQL Database 通过动态管理视图 (DMV) 提供关于数据库运行状况和性能的深入分析信息;这些 DMV 包含有关系统主要方面的信息,如查询性能、数据库和表大小等。应用程序负责定期自主要 DMV 收集和分析信息,并将其整合到范围更大的遥测和洞察框架中。
有若干业务连续性(备份、恢复)选项可用于 SQL Database。数据库可以通过数据库复制功能或 DAC 导入/导出服务进行复制。数据库复制提供业务一致的结果,而 bacpac(通过导入/导出服务)则不会提供业务一致的结果。这两个选项都作为数据中心内基于队列的服务来运行,并且当前都未提供完成时间 SLA。
请注意,数据库复制和导入/导出服务都会给源数据库带来相当大的负载,并且可能触发资源争用或限制事件(在下文中的“共享资源和限制”一节中介绍)。由于以上两种方式都不能提供 SQL Server 支持的同等程度的增量备份,所以当前正在预审一项用来启用时间点恢复功能的新功能。时间点恢复功能允许用户将其数据库恢复到近两周以内的任意一个时点。
当前唯一支持的身份验证方法就是 SQL 身份验证,这是一种基于数据库中已注册用户的单因素用户名/密码登录方式。Active Directory 或双因素身份验证功能尚不提供。极力推荐使用 ADO.NET、ODBC 等接口中现有的内置加密支持对 SQL Database 连接加密。数据库级权限与 SQL Server 的权限一致。有关设置 Azure SQL Database 安全性的详细介绍,请参阅在 Azure SQL Database 中管理数据库和登录名。
SQL Database 提供一套功能齐全的动态管理视图,可用于观测查询性能和数据库运行状况;但并未提供用来收集和分析这些数据的自动化基础结构(同时也未提供直连式事件探查器和操作系统级别的性能计数器等用户熟悉的工具)。用于收集和分析的方法在本文档的“遥测”一节中介绍。
如上所述,SQL Database 是一种运行在共享基础结构之上的多租户服务。来自不同租户的数据库共享基于商用硬件构建的底层物理节点。其他系统用户可以使用同一底层基础结构之上的关键资源(工作线程、事务日志、I/O 等)。资源的使用要接受监管,这样便可将数据库限定在既定的资源限定范围之内。一旦超出这些限制,在租户或物理节点级别,SQL Database 就会中止使用或断开连接。这些限制列在下表中。
资源 | 每个事务/会话的最大值 | 每个物理节点的最大值 | 软中止限制 | 硬中止限制 |
---|---|---|---|---|
工作线程 |
N/A |
512 |
305 |
410 |
数据库大小 |
每个数据库配置的最大容量为 150 GB |
N/A |
无 |
100%;达到限值后不接受插入或更新 |
事务日志增长 |
每个事务 2 GB |
500 GB |
N/A |
N/A |
事务日志长度 |
总日志空间 (100 GB) 的 20% |
500 GB |
N/A |
N/A |
锁计数 |
每个事务一百万 |
N/A |
N/A |
N/A |
阻止系统任务 |
20 秒 |
N/A |
N/A |
N/A |
临时数据库空间 |
5 GB |
N/A |
N/A |
5 GB |
内存 |
N/A |
N/A |
N/A |
16 MB/20 秒 |
最大并行请求数 |
每个数据库 400 个请求 |
N/A |
N/A |
N/A |
一旦达到事务限值,系统就会取消该事务。一旦数据库达到软中止限制,事务处理和连接的速度就会减慢或中止。一旦达到硬中止限制,底层物理节点上的所有数据库(和用户)都会受到影响,导致终止现有操作并且阻止新操作或连接,直到资源使用量下降到中止阈值之下。
以上有些中止限制导致应用程序的设计和性能限值可能不直观。例如,限制事务日志增长到每个事务最大 2 GB 将阻止针对大型表构建索引(因为构建索引将生成超过 2 GB 的事务日志)。本文档的“最佳实践”一节会介绍关于执行此类操作的方法。
处理这些类型的限制条件和暂时性错误要求慎重设计和实施客户端代码;解决这些问题需要横向扩展数据库层,以便同时利用多个数据库(下一节将介绍横向扩展)。
SQL 客户端应用程序代码应该:
SQL Database 可以轻松交付大量的相对较小的扩展单元(数据库)。利用 SQL Database 在 Azure 上实施高度可扩展的应用程序要求采用横向扩展方式,结合使用多个数据库的资源来满足变化莫测的需求。以往应用程序都是面向“钛金蛋壳”(即单个纵向扩展的高度灵活的数据库服务器)来设计,而今需要通过周密的设计实现应用程序转型,使其能够高效利用横向扩展的数据库服务。
和其他 Azure 核心服务一样,对于 SQL Database,横向扩展和组合是进一步的扩展(数据库大小、吞吐量)和资源(工作线程等)利用的关键所在。有两种核心方法可实施 SQL Database 的分区/分片(进而实施横向扩展);这两种方法在一个应用程序内部并不互斥:
许多应用程序都混合使用水平分区和垂直分区(混合分区),此外还会纳入其他存储服务。例如,在上例中,用户的虚拟形象图片作为 ID 存储在数据库中,而应用程序会将其展开为完整的 URL。此 URL 随后会映射到 blob 中存储的图像。
在使用横向扩展的关系数据存储区时,可用性的计算极为不同。在分片数目较多的系统中,某个数据段脱机的概率较高,而整个应用程序不可用的概率要低得多。应用程序还需考虑到后端数据存储区不完全可用的情况。利用横向扩展数据模式,数据不再是要么完全可用,要么完全不可用。
对数据重新分区可能有些难度,特别是在使用模式或数据分布随时间变化的情况下。基于范围的分区键,不论是基于固定数字(使用经过哈希处理的分区值的模数)还是基于分区值的分布,都要求在各个分片之间重新平衡分布数据。基于范围的分区方案往往利用二进制拆分或合并来简化重新平衡操作。
例如,固定范围的分区方法(如姓氏首字母)可能最初是平衡分布的,但随着新用户的出现(用户各有各的姓氏,而这些姓氏在字母表中不一定均匀分布),其分布可能迅速转变为高度失衡。需要谨记:随着时间推移,可能要根据需要调整分区机制和重新平衡数据的成本。
基于查找的分区方案实施难度更大,每个数据租户或分区都需要高性能的查找机制,但由于这些方案允许逐个将单个租户重新平衡分布到新分区,所以更适用于细化的重新平衡。这些方案还支持向系统添加更多容量(新数据库等),而无需复制数据。
无论如何搭配使用分片方法,移至横向扩展的分片关系数据库都带有特定的限制,要求采用不同的数据管理和查询方法:
要横向扩展 SQL Database,需要将数据手动分区或分片到多个 SQL Database 上。这种横向扩展方法可随着扩展实现几乎线性的成本增长;但如果需要,弹性增长或按需扩容所需的成本可呈增量式增长。并不是所有应用程序都需要经过大规模重新设计才支持这种横向扩展模式。
用于解决这些难题的设计建议和最佳实践在本文档的“最佳实践”一节中介绍。
下文中侧重于依据现实世界中的经验和从这些经验中汲取的教训,介绍使用 Azure 和 SQL Database 交付高度可扩展应用程序的最佳实践。每项最佳实践都讨论目标优化和组件、实施方法和固有的优缺点。和任何其他最佳实践一样,这些建议高度依赖于它们的适用环境。根据上一节所述的平台功能评估每项最佳实践的适用性。
备注 |
---|
这些经验是从一些未遵从典型 OLTP(联机事务处理)模式的客户项目中总结出来的。务必要意识到:有些最佳实践不能直接套用在要求较强或较严格的数据一致性的应用程序上;只有你自己了解你应用程序及其环境的确切业务要求。
|
每项最佳实践都将与一个或多个方面的优化有关:
托管服务是 Azure 中的基本扩展单元,所以周密地设计和部署托管服务是提供高度可扩展的可用服务的关键。
对于大型分布式应用程序,对有状态应用程序数据的访问至关重要。应用程序的整体吞吐量和滞后时间通常取决于检索、共享和更新所需数据和上下文的时间能有多快。为了满足此类需求,Azure Caching 和 Memcache 之类的分布式缓存服务应运而生。应用程序应利用分布式缓存平台。请考虑以下原则:
默认情况下,各个服务层之间的连接(包括通过负载平衡器传入的连接)要以循环方式分配,但连接次数有限。以下各图演示了各层与外部服务之间形成的典型连接网(左侧演示典型的仅限 Web 层的应用程序)。尽管该连接网没有为轻型连接协议(如 HTTP)显示任何重大性能问题,但有些连接要么因成本过高而无法连接/初始化,要么就是管制(受限)资源。例如,SQL Database 连接就属于这一类连接。要优化这些外部服务和组件的使用,强烈建议你针对特定实例关联资源调用。
在上述关系图中,右边的拓扑具有位于同一托管服务内的单独 Web 层和辅助层(角色)。此拓扑还实现了 Web 层和应用程序层的关联,以将来自特定应用程序实例的调用固定到特定数据库。例如,要从数据库 1 (DB1) 请求数据,Web 实例必须通过应用程序实例 1 或 2 请求数据。因为 Azure 负载平衡器当前只实现了循环技术,在你的应用程序中提供关联并不要求进行认真设计和实现。
此多层体系结构的实际实现要求在 Web 层和应用程序层之间使用轻型协议进行高效的服务通信。
Azure 应用程序的开发技术与 Windows Server 的开发技术没有本质不同。但是,前者的弹性结构更需要利用最高效使用计算资源的代码,也更能发挥其优势。
Azure 存储是 Azure 应用程序中耐用的数据支柱。尽管可以提供高度可靠、可扩展的“开箱”体验,但是大型应用程序需要遵循适当的设计和使用准则。
如“了解 Azure”一节中所述,SQL Database 将整个关系数据库作为服务功能提供,支持以向外扩展的方式对数据存储区进行访问。在大型应用程序中成功使用 SQL Database 要求进行几个谨慎的设计和实现选择;本节将介绍一些重要的设计点和最佳做法。
很多应用程序需要使用元数据表存储诸如路由、分区和租户信息之类的详细信息。将此元数据存储在单个数据库中会导致单个故障点以及无法进行扩展。中央元数据存储区应通过结合使用以下方式向外扩展:
已分区的 SQL Database 的总体可扩展性受单个数据库(分片)的规模以及这些分片组合起来以增大规模的效率的影响:
进行连续服务交付、管理分布式数据库更新或架构修改时,需要小心谨慎以确保顺利升级。在生产数据存储区中控制架构和元数据操作的所有传统最佳做法比以往更为重要。例如,在 100 个数据库中的某个数据库调试和解决意外删除的存储过程是个比以往复杂得多的任务。
因为架构更新和数据修改在分片上不是事务一致的,在过渡期应用程序更新必须同时兼容旧架构和新架构。这个要求通常表示应用程序的每个版本必须至少与架构的当前版本和上一个版本兼容。
转换到数据库的向外扩展集合会带来一些与连接管理有关的问题。每个 SQL 数据库连接是相对昂贵的资源,这已由客户端 API(ADO.NET、ODBC、PHP 等)中连接池的广泛使用所证实。每个应用程序实例并不维护多个与中央 SQL Server 的连接,而是必须潜在维护与多个数据库服务器的连接。
因为连接是昂贵可能希缺的资源,应用程序必须通过及时退回池中连接来正确管理连接。应用程序代码应使用自动连接释放机制;在 .NET 中,最佳做法是在 using 语句内封装 SqlConnection 的所有使用,例如:
using (var conn = new SqlConnection(connStr)) { // SQL client calls here }
如前文所述,针对 SQL Database 的连接受暂时性连接故障的影响。必须对所有连接和命令使用重试逻辑,以免受这些暂时性故障的影响(有关其他详细信息,请参见下文)。
SQL Database 只支持 TCP 连接(而非命名管道),强烈建议你加密应用程序代码和 SQL Database 之间的连接。要阻止无意识的连接尝试(如尝试使用命名管道),应用程序应按以下方式设置其 SQL 连接字符串格式:
Server=tcp:{servername}.database.windows.net,1433;Database={database};User ID={userid}@{database};Password={password};Trusted_Connection=False;Encrypt=True;Connection Timeout=30;
对于大型应用程序部署,托管的服务部署和 SQL Database 群集内 SQL Database 逻辑服务器(每个服务器具有单独的外部 IP 地址)之间的潜在默认连接数可能以指数级增长。例如,对于包含 100 个实例、50 个数据库的托管服务,在 ADO.NET 中默认连接数为 100 个连接。
MaxConnections=DatabaseCount*Instance Count*MaxConnectionPoolSize
请参考托管服务的网络拓扑;连接的每个端(托管服务和 SQL Database 逻辑服务器)依赖 Azure 负载平衡器存活。. 每个 Azure 负载平衡器在任意两个 IPv4 地址之间最多具有 64k 个连接。此网络拓扑与默认可用连接数的组合导致较大的应用程序出现严重的网络故障。
以下列表提供有关减少所需活动连接数的建议:
转换到分布式数据模型可能需要更改数据库架构的设计以及更改某些查询类型。要求跨多个数据库使用分布式事务的应用程序可能具有不合适的数据模型或实现(例如,尝试强制实施全局一致性)。这些设计必须重构。
由于可用性和可扩展性的限制,使用中央序列生成工具时应避免应用程序的任何不寻常的方面。很多应用程序利用序列提供全局唯一标识符,使用中央跟踪机制根据需要增大该序列。这个体系结构导致了一个全局争用点和瓶颈,系统的每个组件都需要与之交互。此瓶颈对于可能断开连接的移动应用程序更为突出。
因此,应用程序应利用可在分布式系统中生成全局唯一标识符(如 GUID)的函数。根据设计 GUID 不是按顺序的,因此在作为大表中的聚集索引时它们可能导致碎片。在大数据模型中为了减小 GUID 的碎片影响,请将数据库分片,使得每个分片相对较小。这允许 SQL Database 在副本故障转移期间对数据库自动整理碎片。
采用分布式数据模型时客户端应用程序代码必须考虑以下几个方面:
还有几个必须执行的管理任务:
SQL Database 中的几个常见事件可以触发暂时性连接故障,如副本故障转移。应用程序必须实现相应的代码来处理暂时性故障并正确应对资源用尽和限制:
.NET 应用程序可使用可识别 SQL Database 的重试和退让逻辑框架,如云应用程序框架 (CloudFx) 或企业库暂时性故障处理程序。这些框架提供常用数据访问类(如 SqlConnection 和 SqlCommand)以及可直接调用的策略的包装。
var retryPolicy = RetryPolicy.Create<SqlAzureTransientErrorDetectionStrategy>(
retryCount: 3,
initialInterval: TimeSpan.FromSeconds(5),
increment: TimeSpan.FromSeconds(2));
using (var conn = new ReliableSqlConnection(connStr)) { conn.Open(); using (var cmd = conn.CreateCommand()) { } conn.Close(); }
上一个代码段演示在 SQL Database 上工作时如何使用 CloudFx ReliableSqlConnection 类来处理暂时性连接错误。
请注意记录对服务的 API 调用(如 SQL Database),因为可能出现复杂的故障情况。尝试捕获一些重要的上下文和性能信息。例如,所有 SQL Database 会话携带会话标识符,它可用于支持电话中,帮助直接隔离基本问题。强烈建议对于所有写入 SQL Database 日志的调用、命令和查询,记录:
为了更高效使用 SQL Database,针对 SQL Database 的查询和数据插入应尽可能进行批处理和以异步方式执行。这不仅提高了应用程序效率,而且减小了 SQL Database 上的总体系统负载(允许更大的吞吐量)。
作为保持业务连续性总体方案的一部分,在 SQL Database 中存储的数据应定期导出 blob 存储区。Blob 存储区默认情况下支持可用性和地理复制。
实现一个用于将数据库定期导出到 blob 存储区的计划任务。使用专用存储帐户。此任务应在目标数据库所在的数据中心中运行,而不是从内部桌面或服务器运行。
将导出任务安排在系统活动低的时间,以尽可能减小对最终用户体验的影响。导出多个数据库时,请限制并行导出的程度以减小系统影响。
了解你的 SQL Database 的运行状况、性能和容量是影响总体服务交付的关键因素。SQL Database 通过动态管理视图提供所需的原始信息,但是当前没有用于捕获、分析和报告关键度量值的现成基础结构。要为 SQL Database 提供此功能,请考虑以下做法:
Azure 诊断提供收集应用程序和实例级遥测数据的基线。但是,要了解在 Azure 上运行的大型应用程序的状况需要认真配置和管理数据流。与可以利用丰富的 Windows 诊断实用工具的集中式向上扩展应用程序不同,向外扩展的分布式系统中的诊断必须在系统投入运行前实现 – 它们不可能事后再考虑。
错误处理、上下文跟踪和遥测捕获对于了解错误事件、根本原因和解决方法是至关重要的。
Azure 诊断不提供从属服务(如 SQL Database 或分布式缓存)的数据收集。要提供应用程序及其性能特征的综合视图,请添加基础结构来收集从属服务的数据: