[轉]在 Azure 雲服務上設計大規模服務的最佳實踐

本文轉自:http://technet.microsoft.com/zh-cn/magazine/jj717232.aspxcss

英文版:http://msdn.microsoft.com/library/azure/jj717232.aspxnode

 

做者:Mark Simms 和 Michael Thomassy      ios

供稿做者:Jason Roth 和 Ralph Squillace      web

審閱者: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 雲服務。sql

Important重要提示
注意:本文中的全部最佳實踐指導均源自與在 Azure 上運行生產代碼的客戶之間的深刻合做。本文僅討論基於 SDK 1.6 版本的 Azure 雲服務 (PaaS) 平臺,而不涵蓋未來的功能,如 Azure 網站Azure 虛擬機 (IaaS)。

 

          

本文檔介紹有關構建 Azure 應用程序的基礎設計概念、關鍵的 Azure 平臺功能、限制和特性,以及使用核心 Azure 服務的最佳實踐。重點介紹那些適合鬆散一致的分佈式數據存儲區的應用程序(與嚴格一致或高密度的多租戶數據模型相對)。數據庫

出於多種緣由,將應用程序和服務的一些環節轉換爲 Azure 可能頗有吸引力,例如:apache

  • 節省資本支出或將資本支出合併爲運營支出(資本支出至運營支出)。
  • 經過更密切地匹配需求和容量來下降成本(並提升效率)。
  • 經過減小或消除基礎結構障礙來提升靈活性和縮短上市時間。
  • 提升受衆對新市場(如移動設備)的接觸面。
  • 經過構建新的應用程序,使它們經過地理上分散的數據中心支持全球受衆,從而因雲計算的巨大規模而受益。

從技術方面而言,也有許多極好的理由,要求咱們開發新的應用程序或將現有應用程序的某些部分或所有內容移植到 Azure。因爲環境具備許多可選的實現方法,所以,你必須仔細地評估你具體的應用程序模式,以便選擇正確的實現方法。一些應用程序很是適合 Azure 雲服務(這是平臺即服務或 PaaS 方法),而其餘一些應用程序可能受益於部分或完整的基礎結構即服務(或 IaaS)方法,如 Azure 虛擬機。最後,結合使用這二者可能可以最好地知足某些應用程序的要求。windows

你的應用程序應具備如下三個關鍵環節的一個或多個,以便最大限度地發揮 Azure 雲服務的優點。(並不是全部這些環節都須要出如今你的應用程序中;一個應用程序可能只需如下這些環節之一就可以很是充分地利用 Azure,從而帶來巨大的投資回報。可是,若是工做負荷沒有展示任何這些特性,則它可能並非很是適合 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 服務器映像的過程),並集成到由負載平衡器管理的總體應用程序中。

而高狀態組件則藉助於集成到由組件之間緊密管理的系統,經過緊密偶合的冗餘性來提供靈活性。如下是一些示例:

  • SQL Server。要添加一個冗餘的 SQL Server 實例做爲主動/被動羣集的一部分,要求謹慎地選擇兼容(也即徹底相同!)的硬件和共享的存儲設備(如 SAN),以便在多個節點之間提供事務上一致的故障轉移。
  • 供電。提供冗餘的電力是一個很是複雜的示例,這要求多個系統協同發揮做用,以緩解本地(一臺服務器多個電源,板載硬件在主電源和輔助電源之間切換)與中心(備用發電機以防斷電)範圍的問題。

基於緊密耦合方法的靈活性解決方案自己就比鬆散耦合的「添加更多克隆項」的方法更昂貴,由於前者要求通過良好培訓的人員、專門的硬件以及仔細的配置和測試。這不只難以實現,並且實現起來也成本高昂。

這種專一於確保硬件平臺高度靈活的方法也可稱爲「鈦金蛋殼」。爲了保護蛋裏的內容,咱們用一層堅固(但昂貴)的鈦金覆上了一層殼。

大範圍運行系統的經驗(有關進一步的討論,請參閱 http://www.mvdirona.com/jrh/TalksAndPapers/JamesRH_Lisa.pdf)代表,在任何足夠大的系統(如處於 Azure 範圍內的數據系統)中,物理上處於運動狀態的部件總數致使系統的某些部分始終處於易於破壞的狀態。Azure 平臺的設計已規避了這一侷限性,這種設計不是消除這種侷限性,而是依賴於從節點級的故障事件中自動恢復。這種設計意圖貫穿全部核心的 Azure 服務,它對於設計可以使用 Azure 可用性模型的應用程序而言相當重要。

轉換到 Azure 後,靈活性會話從基礎結構冗餘性挑戰變爲服務冗餘性挑戰。對內部可用性計劃起支配做用的許多核心服務在 Azure 中「僅僅維持正常工做」:

  • SQL Database 自動爲你的數據維護多個事務上一致的副本。數據庫的節點級故障自動故障轉移到一致的輔助副本;請將這種體驗的便利性與提供內部靈活性所需的時間和費用進行對比。
  • Azure 存儲自動維護數據的多個一致的副本(要了解詳情,請參閱 http://sigops.org/sosp/sosp11/current/2011-Cascais/11-calder-online.pdf)。存儲卷的節點級故障自動故障轉移到一致的輔助副本。對於 SQL Database,請將這種徹底託管的體驗與在內部羣集或 SAN 中直接管理靈活存儲進行對比。

可是,這一部分的主旨是可用性,而不是靈活性。靈活性只是在 SLA 的範圍內持續向用戶交付價值的整體過程的一部分。若是服務的全部基礎結構組件運行情況均正常,但該服務沒法處理預期的用戶量,則此服務不可用,也沒法交付價值。

以移動設備或社交爲中心的工做負荷(如公共 Web 應用程序以及移動設備應用程序)與面向固定受衆的工做負荷相比,前者的動態程度要高得多;這種工做負荷要求採用更高級的方法來處理大量突發事件和峯值負載。本文檔通篇介紹爲 Azure 應用程序設計可用性時要記住的關鍵概念,這些概念基於如下要點:

  • Azure 中的每一個服務或組件都提供了某種服務級別協議 (SLA);這種 SLA 可能並不與運行你的應用程序所需的可用性指標直接關聯。瞭解系統中的全部組件、其可用性 SLA以及它們的交互方式對於理解可提供給用戶的整體可用性相當重要。
    • 避免出現將致使 SLA 降級的單點故障,如單實例角色。
    • 組合或回退到多個組件,以減輕因特定設備脫機或不可用而致使的影響。
  • Azure 中的每一個服務或組件均可能遇到故障:要麼是短時間臨時事件,要麼是長期事件。你的應用程序應編寫爲可以從容地應對故障。
    • 對於臨時故障,提供適當的重試機制以從新鏈接或從新提交工做。
    • 對於其餘故障事件,提供豐富的檢測機制來處理故障事件(向運營部門報告錯誤),並向用戶返回適當的錯誤消息
    • 若是可能,能夠回退到其餘服務或工做流。例如,若是將數據插入 SQL Database 的請求失敗(因爲非臨時緣由,如架構無效),則以序列化格式將數據寫入 Blob 存儲區。這樣,就能夠持久捕獲數據,並在解決架構問題以後將數據提交到數據庫。
  • 全部服務都具備一個峯值容量,要麼顯式指定(經過限制策略或峯值負載漸近線),要麼隱式指定(達到系統資源限制)。
    • 將你的應用程序設計爲在達到資源限制時從容降級,並採起適當的措施減輕對用戶的影響。
    • 實施適當的退讓/重試邏輯,以免對服務產生「護航」效應。若是沒有適當的退讓機制,則在經歷峯值事件以後,下游服務將始終沒有機會遇上正常步伐(由於應用程序將持續嘗試將更多負載推動服務中,從而觸發限制政策或資源枯竭)。
  • 可能經歷快速突發事件的服務一般須要經過捨棄功能來處理超過其峯值設計負載的狀況。
    • 就像人體在極冷狀況下會限制血液流向末端同樣,將你的服務設計爲在極端負載事件期間捨棄不過重要的服務。
    • 此時的必然結果是:你的應用程序所提供的全部服務不能都具備同等的業務重要性,它們能夠聽從不一樣的 SLA。

這些高級概念將在描述核心 Azure 服務的每一個章節中詳細說明,同時還有適用於每一個服務或組件的可用性目標以及如何針對可用性進行設計的建議。請記住,數據中心仍然是大型應用程序的單一故障點;從電源錯誤(請在此處查看示例)到系統錯誤(請在此處查看示例),基礎結構和應用程序問題都會致使數據中心崩潰。要求最高級別正常工做時間的應用程序應部署在多個冗餘的數據中心內,但這種狀況極爲罕見。

在多個數據中心部署應用程序要求若干基礎結構和應用程序功能:

  • (基於地理位置、用戶分區或其餘關聯邏輯)將服務的用戶路由到適當的數據中心的應用程序邏輯。
  • 在數據中心之間以適當的延遲和一致性級別同步和複製應用程序狀態。
  • 自主部署應用程序,以便最大限度下降數據中心之間的相互依賴(也即,避免數據中心 A 的故障致使數據中心 B 出現故障的狀況)。

            

          

關於可用性,(在數據中心丟失的狀況下)提供災難恢復解決方案須要大量的時間、精力和資金。這一部分將集中討論在面對系統故障和數據丟失(不管是系統觸發仍是用戶觸發)時提供業務連續性的方法和注意事項,由於術語「災難恢復」圍繞着數據庫連續性的實施方法具備特定的含義。

交付業務連續性的過程可分解爲:

  • 在發生災難性基礎結構故障時,維護對關鍵業務系統的訪問以及可用性(針對持久狀態運行的應用程序)。
  • 在發生災難性基礎結構故障時,維護對關鍵業務數據的訪問以及可用性(持久狀態)。
  • 在發生操做員錯誤或意外刪除、修改或損害時,維護關鍵業務數據的可用性(持久狀態)。

前兩個元素傳統上已在地理災難恢復 (geo-DR) 的上下文中得以解決,而第三個元素則屬於數據備份和數據還原的領域。

Azure 大大改變了關鍵業務系統可用性的平等分佈方式,從而可以快速將關鍵應用程序部署到地理上分散的全球各數據中心。事實上,發佈地理上分佈的應用程序與發佈單個雲服務的過程之間的差別並不明顯。

  關鍵的難題仍然是管理對持久狀態的訪問;跨數據中心訪問持久狀態服務(如 Azure 存儲和 SQL Database)一般會因延遲較高和/或不肯定而致使結果達不到最佳狀態,從而在數據中心發生故障時沒法知足業務連續性要求。

對於靈活性,許多 Azure 服務提供(或者在其路線圖中具備)自動地理複製功能。例如,除非另行專門配置,不然全部寫入 Azure 存儲(blob、隊列或表)中的內容都會自動複製到另外一個數據中心(每一個數據中心在同一個地理區域內都有一個特定的「鏡像」目標)。這大大減小了在 Azure 基礎之上提供傳統災難恢復解決方案所需的時間和努力。後面的章節概述管理持久狀態的核心 Azure 服務的地理複製功能。

爲了在面對用戶錯誤或操做員錯誤時維護業務連續性,在應用程序設計中應考慮若干其餘注意事項。儘管 Azure 存儲經過「存儲分析」功能提供了有限的審覈功能(在後面的章節中介紹),但它沒有提供任什麼時候點還原功能。在面對意外刪除或修改時要求靈活性的服務將須要考察以應用程序爲中心的方法,如按期將 blob 複製到其餘存儲賬戶。

SQL Database 提供了用於維護數據的歷史快照的基本功能,包括 DB 複製以及經過 bacpac 導入/導出。本文檔後面將詳細討論這些選項。

                                

藉助於 Azure 平臺提供的靈活擴展,供給曲線能夠與需求曲線密切匹配(而不是用大量額外容量來知足峯值負載)。

藉助靈活擴展,商品成本由如下各因素驅動:

  • 解決方案中利用了多少個擴展單元;虛擬機、存儲賬戶等(組合以進行擴展)
  • 這些擴展單元執行工做的效率如何。

咱們將針對給定容量可執行的工做量稱爲應用程序的密度。服務和框架的密度越大,針對給定的資源部署執行的工做量就越大;也就是說,提升密度後會減小所部署的容量(和成本),或者可以以相同的部署容量吸取附加負載。密度由兩種主要因素驅動:

  • 在一個擴展單元內執行工做的效率。這是傳統的性能優化方式 – 管理線程爭用和鎖、優化算法、優化 SQL 查詢。
  • 跨擴展單元協調工做的效率。若是系統由大量的較小單元組成,則將它們高效地結合起來的能力對於實現高效率而言相當重要。這涉及到跨組件進行通訊的框架和工具,如 SOAP 消息傳遞堆棧(如 WCF)、ORM(如實體框架)、TDS 調用(SQL 客戶端代碼)和對象序列化(如數據合同或 JSON)。

除了針對單一計算機(或數據庫)使用的傳統優化方法以外,優化分佈式通訊和操做對於交付可擴展、高效的 Azure 服務而言是相當重要的。後面的章節將詳細介紹這些關鍵的優化:

  • 塊區並不意味着瑣碎。對於每一個分佈式操做(也即致使網絡調用的操做),針對包組幀、序列化、處理等都有必定量的開銷。爲了最大限度地減小開銷,可嘗試批處理爲數量較少的「塊區」操做,而不是大量「瑣碎」的操做。請記住,批處理瑣碎的操做的確會增長延遲,並可能致使丟失數據。正確的批處理行爲的示例以下所示:
    • SQL。在單一批處理中執行多個操做。
    • REST 和 SOAP 服務(如 WCF)。利用以消息爲中心的操做界面而不是瑣碎的 RPC 樣式,若是可能,還可考慮基於 REST 的方法。
    • Azure 存儲(blob、表、隊列)。成批(而非單獨)發佈多個更新。
  • 序列化的影響。在計算機之間移動數據(以及移入和移出持久存儲)一般要求將數據序列化爲線路格式。此操做的效率(即所需時間和佔用的空間)在很大程度上影響了較大型系統的整體應用程序性能。
    • 利用高效率的序列化框架。
    • 使用 JSON 與設備通訊,或者用於可互操做(用戶可讀)的應用程序。
    • 當你同時控制兩個端點時,使用很是高效的二進制序列化(如 protobufAvro)來進行服務間通訊。
  • 使用高效框架。許多豐富的框架可用於進行開發,它們具備大量高級的功能集。其中許多框架的缺點是你常常會爲不使用的功能耗費性能成本。
    • 在通用界面以後隔離服務和客戶端 API,以便容許替換或並行評估(經過靜態工廠或倒置控制容器)。例如,提供一個針對通用界面發揮做用的可插拔 caching 層,而不是特定實現(如 Azure 緩存)。
        
        

在前一節中,咱們介紹了要構建利用由 Azure 提供的雲結構的應用程序,應涉及的關鍵設計概念和觀點。本節將討論核心平臺服務和特性,闡述其功能、擴展邊界和可用性模式。

由於每一個 Azure 服務或基礎結構組件都經過可用性 SLA 提供有限的容量,因此,瞭解這些限制和行爲對於爲你的可擴展性目標和最終用戶 SLA 作出適當的設計選擇而言相當重要。每一個核心 Azure 服務都體現爲如下四個中心環節:功能及其意圖、密度、可擴展性和可用性。

Azure 訂閱是最基本的管理、結算和服務配額單元。每一個 Azure 訂閱都具備一組默認配額,旨在防止意外覆蓋或佔用資源,但你能夠經過與支持部門聯繫來增長這些配額。

每一個訂閱都有一個賬戶全部者和經過 Microsoft 賬戶(之前稱爲 Live ID)受權的一組聯合管理員,他們經過管理門戶對訂閱中的資源具備徹底控制權。他們能夠建立存儲賬戶、部署雲服務、更改配置,並能夠添加或刪除聯合管理員。

Azure 管理 API(基於 REST 的 Web 服務)提供了一個自動執行界面,用於建立、配置和部署 Azure 服務(由管理門戶在後臺使用)。對這些 API 的訪問是使用管理證書來限制的。

 

服務 默認限制

雲服務

20

存儲賬戶

20

Cores

20

SQL Database 邏輯服務器

5

Tip提示
有關最新的 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 的另外一個緣由。

            

總結以下:

  • Azure 中的基本部署和擴展單位是雲服務,由一組角色組成。每一個角色都包含一組徹底相同的角色實例,每一個實例運行 Windows Server 的一個特定的雲配置版本。
  • 除了物理拓撲(角色和實例)和應用程序代碼以外,雲服務還定義一個服務範圍的配置。此配置能夠在運行時更新。
  • 每一個角色實例都是非持久的(更改、文件等都不能保證在從新引導、修補、故障事件中持久存在)。
  • 每一個雲服務都同時針對入站和出站通訊公開單個虛擬 IP。雲服務公開端點,而端點向內部角色和端口提供(循環法)負載平衡的映射。
  • Azure 使用升級域在邏輯上劃分實例組,並提供滾動更新或修改(同時保持可用性)。
  • Azure 使用故障域在物理上將實例分組,使之脫離單點故障(如在同一臺基礎物理計算機上運行全部實例)。
  • 利用多個訂閱以隔離部署、測試、臨時和生產環境。

              

          
                                

每一個角色都包含一組實例(由一個或多個實例組成)。其中每一個實例都是虛擬機,運行 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

Tip提示
有關最新的 Azure 訂閱和服務限制,請參閱 Azure 訂閱和服務限制、配額與約束

 

              

當兩個或更多實例部署在不一樣的故障域和升級域中時,Azure 爲雲服務提供如下 SLA:

  • 針對面向 Internet 的角色(具備外部端點的角色)提供 99.95% 的外部鏈接
  • 在兩分鐘內檢測到角色實例問題的概率達到 99.9% 並啓動糾正措施

角色實例大小和計數在運行的應用程序中可能動態發生變化(注意,更改角色實例大小將觸發滾動從新部署)。在給定用於構建 Azure 應用程序的向外擴展方法的狀況下,當須要選擇實例大小時,並不是實例越大就必定越好。這一點同時適用於成本(爲你不使用的功能付費)和性能(取決於你的工做負荷是 CPU 綁定、I/O 綁定等等)。本文檔的「最佳實踐」部分將更詳細地探討實例數目和實例大小。

                                

Azure 存儲是 Azure 的基線持久數據服務,提供 blob(文件)、隊列和表存儲(鍵到值)。存儲賬戶是擴展和可用性的基本單元,同時提供如下功能。與存儲設備之間的全部通訊均基於經過 HTTP 的 REST 接口。

Tip提示
有關最新的 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。每一個塊 blob 由多達 50,000 個塊組成,每一個塊最大可達 4 MB(總的最大塊 blob 大小爲 200 GB)。塊 blob 支持並行上載,以便經過網絡高效和併發移動大型文件。能夠插入、替換或刪除各個塊,但沒法進行就地編輯。
  • 頁 blob。頁 blob 旨在高效提供隨機的讀/寫操做(如訪問 VHD)。每一個頁 blob 的最大大小爲 1 TB,由 512 字節的頁面組成。能夠添加或更新單個頁面或一組頁面,並能夠就地覆蓋。

下表中列出了 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、int3二、int6四、string

各實體(你能夠將其視爲行)的最大大小爲 1 MB,各列的最大大小限制爲 64 kB。上表中列出了支持的數據類型;對於不支持的類型(如 DateTimeOffset),你的應用程序代碼中須要一個序列化代理(例如,以標準字符串格式存儲 DateTimeOffset)。

表存儲使用與分區和實體、分區掃描或實體掃描關聯的鍵來提供對所存儲數據的訪問。它支持篩選器投影,由於篩選表達式能夠做爲查詢的一部分推送到表存儲,並在表存儲中執行。表存儲不提供輔助索引,所以,任何非基於分區鍵或實體鍵的查找都要求進行表掃描和/或分區掃描。對於包含大量實體的分區,這一般對性能有重大影響。

任何超過 5 秒的查詢處理都會返回一個繼續標記,而應用程序能夠使用此繼續標記來繼續接收查詢的結果。檢索的實體數超過 1,000 的查詢必須利用分頁模型,以便將數據返回到包含 1,000 個實體的塊中(表存儲 API 自己就支持塊)。

目前對於表存儲支持的惟一查詢表達式是篩選和選擇(選擇特定屬性);表存儲不提供服務器端聚合或分組語義。爲了構建要求豐富的聚合或分析功能的應用程序,一般更好的選擇是以聚合格式存儲數據或使用關係引擎(如 Azure SQL Database)。某些應用程序採用混合方法,將表存儲中的數據聚合到一個輔助 SQL Database 中,而後用於查詢和報告目的。

選擇適當的分區函數對於高效和有效地利用表存儲而言相當重要。對於分區函數的類型,有兩種主要選擇:

  • 時間。經常使用於存儲時間序列數據,如 Azure 診斷性能計數器(本文檔的遙測部分中介紹了用法),基於時間的分區函數將當前時間轉換爲表示時間窗口的值(當前分鐘、小時等)。
    這樣,就能夠高效地查找和定位特定分區(由於表存儲的篩選子句支持 >=、<= 等等),但若是所選時間窗口太窄而且發生了峯值事件,則容易受到限制。例如,若是所選分區函數是當前分鐘值併發生了峯值事件,則過多的客戶端可能嘗試併發寫入同一個分區。這不只影響插入時的吞吐量,並且影響查詢時的吞吐量。
  • 數據。以數據爲中心的分區函數基於要存儲(或檢索)的數據的一個或多個屬性來計算分區值。選擇適當的數據驅動的分區函數取決於幾個因素:查詢模式、分區密鑰密度(分區中最終用了多少個實體)以及沒法預測的增加(這對於使很是大的表從新達到平衡多是個挑戰)。常見模式包括:
    • 單一字段。分區鍵是源數據中的單一字段(如訂單信息中的客戶 ID)。
    • 多字段。分區鍵或行鍵是源數據中多個字段的組合(一般是串聯)。當選擇分區鍵時,請注意,批處理操做要求全部實體位於同一個分區中(也即具備相同的分區鍵)。
    • 計算字段。分區鍵是基於一個肯定性函數從一個或多個字段計算得出的。一個常見的示例是將用戶配置文件分配到多個分區中。將使用爲實現相對統一的分配而設計的哈希函數來對用戶 ID 進行哈希處理,而後針對所需分區的數量進行取模。

任何重要的應用程序都要求使用多個分區。甚至對於具備總實體數中少許實體的表(如 200 個實體),若是應用程序每秒將發出幾千個請求,則須要用多個分區才能知足吞吐量要求。

  • 單一表/單一分區。最簡單的選項(恆定的分區鍵值),可知足小規模的工做負荷、有限的數據量以及請求吞吐量要求(< 500 個實體/秒)。
  • 單一表/多個分區。大多數部署的典型選項;認真選擇與目標查詢模式匹配的分區鍵。
  • 多存儲賬戶/多分區。若是負載投影超過每秒 5,000 個操做,則要求跨多個存儲賬戶使用表。

一旦選擇,則數據達到從新平衡(從新分區)可能會很是昂貴,這涉及讀取和複製具備新分區鍵的全部實體,而後刪除舊數據。請注意,分區沒有最小大小限制;分區能夠由單個實體(也即行)組成。

若是你的應用程序須要的吞吐量高於單一表所能提供的吞吐量(在仔細選擇分區以後),請在不一樣的存儲賬戶中利用多個並發表。在這一上下文中,你的應用程序須要實現適當的路由邏輯,以便選擇適當的存儲賬戶。

          
          

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)會話進行批處理,併發布到目標存儲賬戶。代理負責處理臨時鏈接問題、重試等其餘事項。可用數據源以下所示:

  • 性能計數器。捕獲到本地 ETW 會話並按期暫存至表存儲中的性能計數器值的子集(CPU、內存等)。
  • Windows 事件日誌。捕獲到本地 ETW 會話並按期暫存至表存儲中的 Windows 事件記錄(應用程序、系統等等)的子集。
  • Azure 日誌。應用程序代碼(經過 System.Diagnostics.Trace)發佈並由 DiagnosticMonitorTraceListener 跟蹤偵聽程序捕獲的應用程序日誌(跟蹤消息)。這些日誌將發佈到目標存儲賬戶的「WAD 性能計數器」表中。
  • IIS 7.0 日誌。關於 IIS 記錄的請求的標準 IIS 日誌信息(僅限 Web 角色)。日誌將收集到本地文件中,並按期暫存至 blob 存儲區。
  • IIS 失敗請求日誌。來自 IIS 的關於失敗請求的信息,這些信息將收集到本地文件中,並按期暫存至 blob 存儲區。
  • 崩潰轉儲。系統一旦崩潰,即捕獲關於操做系統狀態的日誌併發布至 blob 存儲區。
  • 數據源。WAD 能夠監視更多本地目錄(如本地存儲區中的日誌目錄),並按期將這些數據複製到 blob 存儲區的自定義容器中。

以上每種數據源都配置有要收集的數據子集(例如,性能計數器列表)以及收集/發佈時間間隔。還能夠經過一些 PowerShell 腳原本更改運行時配置,或強制從代理向目標存儲賬戶當即發佈數據。

Important重要提示
將遙測數據記錄到單獨的存儲賬戶中。將遙測數據和應用程序數據記錄到同一存儲賬戶中將致使大規模的嚴重爭用問題。

 

              

                                

Azure SQL Database 提供數據庫即服務,支持應用程序快速設置關係數據庫、向其中插入數據以及查詢該數據庫。它提供許多熟悉的 SQL Server 功能,同時減小了硬件、配置、修補和復原方面的負擔。

note備註
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 中現有的多數關鍵功能,但也有一些重要的例外狀況,包括:

  • 全部表都必須包含 CLUSTERED INDEX;在定義 CLUSTERED INDEX 以前不能將數據 INSERT(插入)SQL Database 中的表。
  • 沒有內置的公共語言運行時 (CLR) 支持、數據庫鏡像、Service Broker、數據壓縮或表分區功能。
  • 沒有 XML 索引;不支持 XML 數據類型。
  • 不支持透明數據加密 (TDE) 或數據審覈。
  • 不支持全文搜索。

每一個數據庫在建立時,都配置了大小上限。當前可用的容量上限包括 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 錯誤代碼的重試代碼,並提供相應的退讓邏輯。若是應用程序中不存在某種形式的退讓邏輯,數據庫可能因不斷地承受峯期負載而被鎖定在持續限制狀態。
  • 記錄限制錯誤,用重試代碼來區分暫時性鏈接、限制和硬故障 - 語法、缺失存儲過程等。這將有助於跟蹤和解決應用程序可用性問題。
  • 實施斷路器模式。適當選擇的重試策略一旦失效(針對應用程序的重試頻率權衡滯後時間與系統響應),需調用某一代碼路徑來處理非暫時性錯誤(即斷路器脫扣)。應用程序代碼隨後能夠:
    • 回退到另外一服務或方式。若是應用程序未能將新數據插入 SQL Database(而且這些數據不須要即時可用),那麼這些數據可改成序列化爲 DataTable 中的數據(或其餘 XML/JSON 格式),並寫入 blob 存儲區中的文件。該應用程序隨後可能向用戶(或 API 調用)返回成功代碼,稍後再將這些數據插入數據庫。
    • 經過返回 Null 值無提示失敗(若是數據或工做流是可選的,即不影響最終用戶體驗)。
    • 經過返回錯誤代碼快速失敗(若是未提供有用的/適當的回退機制)。

              

                                      

SQL Database 能夠輕鬆交付大量的相對較小的擴展單元(數據庫)。利用 SQL Database 在 Azure 上實施高度可擴展的應用程序要求採用橫向擴展方式,結合使用多個數據庫的資源來知足變化莫測的需求。以往應用程序都是面向「鈦金蛋殼」(即單個縱向擴展的高度靈活的數據庫服務器)來設計,而今須要經過周密的設計實現應用程序轉型,使其可以高效利用橫向擴展的數據庫服務。

和其餘 Azure 核心服務同樣,對於 SQL Database,橫向擴展和組合是進一步的擴展(數據庫大小、吞吐量)和資源(工做線程等)利用的關鍵所在。有兩種核心方法可實施 SQL Database 的分區/分片(進而實施橫向擴展);這兩種方法在一個應用程序內部並不互斥:

  • 水平分區。在水平分區方法中,完整的表或數據集被分隔到各個數據庫中。例如,對於爲不一樣客戶羣服務的多租戶應用程序,該應用程序能夠爲每一個客戶都建立一個數據庫。對於大型單租戶應用程序,客戶表能夠位於與訂單表不一樣的數據庫中。分區鍵一般就是租戶標識符(例如,客戶 ID)。在下圖中,數據集水平分區到三個不一樣的數據庫中,以通過哈希處理的電子郵件做爲分區值(即,分區鍵是電子郵件,分區函數使用這個通過哈希處理的鍵映射到目標數據庫)。
  • 垂直分區。在垂直分區方法中,數據集根據架構分區分佈在多個物理表或數據庫中。例如,客戶數據和訂單數據可能分佈在不一樣的物理數據庫中。在下圖中,數據集垂直分區到兩個不一樣的數據庫中。核心用戶信息(姓名、電子郵件)存儲在 DB1 中,用戶配置文件信息(如虛擬形象圖片的 URI)存儲在 DB2 中。

許多應用程序都混合使用水平分區和垂直分區(混合分區),此外還會歸入其餘存儲服務。例如,在上例中,用戶的虛擬形象圖片做爲 ID 存儲在數據庫中,而應用程序會將其展開爲完整的 URL。此 URL 隨後會映射到 blob 中存儲的圖像。

在使用橫向擴展的關係數據存儲區時,可用性的計算極爲不一樣。在分片數目較多的系統中,某個數據段脫機的機率較高,而整個應用程序不可用的機率要低得多。應用程序還需考慮到後端數據存儲區不徹底可用的狀況。利用橫向擴展數據模式,數據再也不是要麼徹底可用,要麼徹底不可用。

對數據從新分區可能有些難度,特別是在使用模式或數據分佈隨時間變化的狀況下。基於範圍的分區鍵,不管是基於固定數字(使用通過哈希處理的分區值的模數)仍是基於分區值的分佈,都要求在各個分片之間從新平衡分佈數據。基於範圍的分區方案每每利用二進制拆分或合併來簡化從新平衡操做。

例如,固定範圍的分區方法(如姓氏首字母)可能最初是平衡分佈的,但隨着新用戶的出現(用戶各有各的姓氏,而這些姓氏在字母表中不必定均勻分佈),其分佈可能迅速轉變爲高度失衡。須要謹記:隨着時間推移,可能要根據須要調整分區機制和從新平衡數據的成本。

基於查找的分區方案實施難度更大,每一個數據租戶或分區都須要高性能的查找機制,但因爲這些方案容許逐個將單個租戶從新平衡分佈到新分區,因此更適用於細化的從新平衡。這些方案還支持向系統添加更多容量(新數據庫等),而無需複製數據。

不管如何搭配使用分片方法,移至橫向擴展的分片關係數據庫都帶有特定的限制,要求採用不一樣的數據管理和查詢方法:

  • 以往,「良好」的 SQL 數據存儲和查詢設計都利用高度規範化的數據模型進行了存儲和一致性方面的優化。這種方法假定利用交叉引用和表間 JOIN(聯接)造成了全局一致的數據空間。但隨着數據分佈到物理上分散的多個節點上,JOIN 和交叉引用僅在單個分片內適用。SQL Database 不支持多個數據庫上的分佈式查詢;須要在客戶端層處理數據合併,而且在分片之間進行數據的非規範化處理和複製。
  • 引用數據和元數據一般都被集中到引用表中。在橫向擴展方法中,這些引用表以及公共分區鍵沒法分隔的全部數據都須要在分片之間複製並保持一致
  • 因爲沒有切實可行的方法在分片之間提供可擴展、高性能的分佈式事務,因此數據(乃至架構更新!)永遠不可能在分片之間保持事務上的一致性。應用程序代碼需認定分片之間存在必定程度的鬆散一致性,並將其做爲一種考慮因素。
  • 應用程序代碼須要瞭解分片機制(是水平分區仍是垂直分區)才能鏈接正確的分片。
  • 經常使用的 ORM(如實體框架)自己並不瞭解橫向擴展數據模型;普遍利用大型 ORM 的應用程序可能須要大規模從新設計才能與水平分片兼容。對於以垂直分片法將租戶(客戶集)隔離到單個數據庫的設計,一般在數據訪問層所需的從新設計較少。純垂直分片模型的缺點是:每一個單獨分片的容量受單個數據庫容量的限制。
  • 須要訪問(讀取或寫入)多個分片的查詢要使用散播-彙集模式來實施,這種模式將針對目標分片執行各個查詢,隨後在客戶端數據訪問層聚合結果集。

要橫向擴展 SQL Database,須要將數據手動分區或分片到多個 SQL Database 上。這種橫向擴展方法可隨着擴展實現幾乎線性的成本增加;但若是須要,彈性增加或按需擴容所需的成本可呈增量式增加。並非全部應用程序都須要通過大規模從新設計才支持這種橫向擴展模式。

  • 不能保證架構更新在事務上的一致性,特別是在更新大量分片時。應用程序要麼須要接受計劃的停機期間,要麼可以處理多個並行的已部署架構版本。
  • 業務連續型流程(備份/恢復等)須要可以處理多個數據分片。

用於解決這些難題的設計建議和最佳實踐在本文檔的「最佳實踐」一節中介紹。

          
        
                          

下文中側重於依據現實世界中的經驗和從這些經驗中汲取的教訓,介紹使用 Azure 和 SQL Database 交付高度可擴展應用程序的最佳實踐。每項最佳實踐都討論目標優化和組件、實施方法和固有的優缺點。和任何其餘最佳實踐同樣,這些建議高度依賴於它們的適用環境。根據上一節所述的平臺功能評估每項最佳實踐的適用性。

note備註
這些經驗是從一些未聽從典型 OLTP(聯機事務處理)模式的客戶項目中總結出來的。務必要意識到:有些最佳實踐不能直接套用在要求較強或較嚴格的數據一致性的應用程序上;只有你本身瞭解你應用程序及其環境的確切業務要求。

 

            

每項最佳實踐都將與一個或多個方面的優化有關:

  • 吞吐量。如何增長經過系統的操做(事務、服務調用等)的數量,以及如何減小資源爭用。
  • 滯後時間。如何縮短聚合和單個操做上的滯後時間。
  • 密度。在直接上下文(例如,SQL Database 的應用程序代碼)和聚合上下文(利用多個存儲賬戶以提升擴展性)環境中編寫服務時,如何減小爭用點。
  • 可管理性。診斷、遙測和洞察 - 如何理解大規模部署的服務的運行情況和性能。
  • 可用性。如何經過減少故障點和模式的影響來提升總體應用程序可用性(availability-under-load 將在吞吐量/滯後時間/密度部分中介紹)。

          

                     

託管服務是 Azure 中的基本擴展單元,因此周密地設計和部署託管服務是提供高度可擴展的可用服務的關鍵。

  • 託管服務中的實例和升級域數量可能極大影響部署、配置和升級託管服務所需的時間。須要在性能和可擴展性優點與這些優點所帶來的複雜性之間權衡利弊。提升可擴展性和靈活性每每會增長解決方案的開發和管理成本。
  • 避免單實例角色;此配置不符合 Azure SLA 要求。在節點發生故障或執行升級的過程當中,單實例角色將脫機。因此只應將單實例角色限制用於優先級較低的「維護」任務。
  • 每一個數據中心都具備有限(儘管較大)的容量,能夠在極少數狀況下用做單個故障點。要求最高級別擴展和可用性的服務必須實施支持多個託管服務的多數據中心拓撲結構。可是:
  • 若是不須要最高級別的可用性(請參閱上一個條目),應確保應用程序和依賴服務徹底包含在單個數據中心內。在解決方案必須使用多個數據中心的狀況下,請遵循如下原則:
    • 避免爲實時操做(專門的跨站點同步操做除外)執行跨數據中心網絡調用。數據中心之間的長時間延遲變數極大,可能產生意外或用戶不但願出現的應用程序性能問題。
    • 只准備好訪問其餘數據中心中的服務所需的最基本的功能。一般,這些活動與業務連續性和數據複製有關。
                         

對於大型分佈式應用程序,對有狀態應用程序數據的訪問相當重要。應用程序的總體吞吐量和滯後時間一般取決於檢索、共享和更新所需數據和上下文的時間能有多快。爲了知足此類需求,Azure Caching 和 Memcache 之類的分佈式緩存服務應運而生。應用程序應利用分佈式緩存平臺。請考慮如下原則:

  • 利用分佈式緩存平臺,將其做爲你託管服務中的輔助角色。緩存的這種鄰近客戶端特性減小了負載平衡器遍歷所形成的延遲和吞吐量障礙。Azure Cache 上的角色中緩存在雲服務內的輔助角色上承載緩存。
  • 將分佈式緩存平臺用做訪問經常使用應用程序數據和對象(例如,用戶配置文件和會話狀態)的主存儲庫,而且由 SQL Database 或其餘持久性存儲區提供通讀或緩存預留支持。
  • 緩存對象都有生存時間,該時間影響它們在分佈式緩存中的有效期。應用程序要麼對緩存對象明確設定生存時間,要麼爲緩存容器配置默認生存時間。應該在可用性(緩存命中率)與內存壓力和數據陳舊程度之間權衡生存時間的選擇。
  • 緩存具備 key->byte[] 語義;應注意可能產生重疊寫入,形成緩存中的數據不一致。分佈式緩存一般不會爲存儲數據的原子更新提供 API,由於緩存沒法識別存儲數據的結構。
    • 對於要求併發寫入嚴格一致的應用程序,請使用爲更新實體提供鎖定機制的分佈式緩存平臺。對於 Azure Caching,能夠經過 GetAndLock/PutAndUnlock 來實現。注意:這將對吞吐量產生負面影響。
  • 緩存性能在應用程序層上受限於序列化和反序列化對象所需的時間。若要優化此過程,請利用相對對稱(數據編碼/解碼所需時間相同)、高效的二進制序列化程序,如  protobuf
    • 若要成功使用自定義序列化,請設計要在緩存中序列化的數據傳輸對象 (DTO),對序列化使用正確的批註、避免循環依賴,並利用單元測試跟蹤高效序列化。
                                      

默認狀況下,各個服務層之間的鏈接(包括經過負載平衡器傳入的鏈接)要以循環方式分配,但鏈接次數有限。如下各圖演示了各層與外部服務之間造成的典型鏈接網(左側演示典型的僅限 Web 層的應用程序)。儘管該鏈接網沒有爲輕型鏈接協議(如 HTTP)顯示任何重大性能問題,但有些鏈接要麼因成本太高而沒法鏈接/初始化,要麼就是管制(受限)資源。例如,SQL Database 鏈接就屬於這一類鏈接。要優化這些外部服務和組件的使用,強烈建議你針對特定實例關聯資源調用。

在上述關係圖中,右邊的拓撲具備位於同一託管服務內的單獨 Web 層和輔助層(角色)。此拓撲還實現了 Web 層和應用程序層的關聯,以未來自特定應用程序實例的調用固定到特定數據庫。例如,要從數據庫 1 (DB1) 請求數據,Web 實例必須經過應用程序實例 1 或 2 請求數據。由於 Azure 負載平衡器當前只實現了循環技術,在你的應用程序中提供關聯並不要求進行認真設計和實現。

  • 使用單獨的 Web 層和應用程序層設計應用程序,在 Web 層和應用程序層之間實現分區或資源級關聯。
  • 實現將內部服務調用透明路由到目標應用程序實例的路由邏輯。使用外部或下游資源(如 SQL Database)使用的分區機制知識。

此多層體系結構的實際實現要求在 Web 層和應用程序層之間使用輕型協議進行高效的服務通訊。

          
          

Azure 應用程序的開發技術與 Windows Server 的開發技術沒有本質不一樣。可是,前者的彈性結構更須要利用最高效使用計算資源的代碼,也更能發揮其優點。

  • 假定全部服務、網絡調用和從屬資源可能不可靠,致使暫時性故障(例如,本主題下面將介紹如何實現 SQL Database 的重試邏輯):
    • 對全部服務調用(SQL Database、存儲等)實現合適的重試策略以處理暫時性故障和鏈接丟失問題。
    • 在重試邏輯中實現退讓策略以免「護航」效應(對延長中斷時間的服務累積的重試)。
    • 實現富客戶端遙測以便記錄包含上下文信息(目標服務、用戶/賬戶上下文、活動等)的錯誤消息和故障事件。
  • 不要直接建立線程來計劃做業;請利用現有計劃和併發框架(如 .NET 任務並行庫)。線程是相對重型的對象,一般不宜建立和釋放。針對共享線程池工做的計劃程序能夠更高效計劃和執行做業。此體系結構還提供更高級的語義來描述持續和錯誤處理。
  • 序列化網絡傳輸優化數據傳輸對象 (DTO)。若是 Azure 應用程序是高度分散的,則可擴展性受系統的各個組件在網絡上通訊的效率影響。在通訊或存儲的網絡上傳輸的任何數據應採用帶適當提示的 JSON 文本序列化或更高效的二進制格式,以儘量減少網絡上傳輸的元數據量(如線路上更短的字段名稱)。
    • 若是注重互操做,請使用高效的文本格式(如 JSON)以支持互操做性和帶內元數據。
    • 若是注重高吞吐量(如在你控制兩端的服務到服務通訊中),請考慮採用高效打包的二進制格式(如 bson 或 protobuf)。
      • 避免頻繁進行小對象的數據傳輸。服務之間的頻繁通訊會將大量系統資源浪費在管理開銷任務上,致使變量延遲響應。
      • 序列化和反序列化對象的測試應是自動測試框架的核心組成部分。功能測試確保數據類可序列化,且沒有循環的依賴關係。性能測試驗證所需的延遲時間和編碼大小。
  • 實際實施時,將輕型框架用於組件和服務之間的通訊。.NET 堆棧中的不少傳統技術提供了豐富的功能集,可是該功能集可能不知足分佈式 Azure 的要求。提供意圖和執行間高度抽象的組件可能嚴重影響性能。
    • 若是你不要求協議互操做性或高級協議支持,請考慮使用 ASP.NET Web API 替代 WCF 來實現 Web 服務。
    • 若是你不要求實體框架具備豐富功能,請考慮使用微型 ORM(如 Dapper)來實現 SQL 客戶端層。
  • 經過容許將 IIS 中的 HTTP 壓縮用於出站數據,減小從數據中心傳送的數據量。
  • 關聯層之間的鏈接以減小鏈接的頻率和上下文切換次數。
  • 要減少應用程序的負載,請使用 blob 存儲區來存儲較大的靜態內容 (> 100 kB)。
  • 要減少應用程序的負載,請使用藉助 blob 存儲區的內容傳送網絡 (CDN) 來傳送靜態內容(如圖像或 CSS)。
  • 避免將 SQL Database 用於會話數據。請改用分佈式緩存或 cookie。

            

          

Azure 存儲是 Azure 應用程序中耐用的數據支柱。儘管能夠提供高度可靠、可擴展的「開箱」體驗,可是大型應用程序須要遵循適當的設計和使用準則。

  • 利用多個存儲賬戶可得到更大的可擴展性,不管是增大大小 (> 100 TB) 仍是實現更大的吞吐量(每秒 > 5,000 個操做)。確保你的應用程序代碼能夠配置爲使用多個存儲賬戶,使用適當的分區函數將做業路由到存儲賬戶。將添加更多存儲賬戶的功能設計爲配置更改而非代碼更改。
  • 謹慎選擇表存儲的分區函數,以在確保插入和查詢性能的前提下支持所需的規模。將基於時間的分區方法用於遙測數據,使複合鍵基於非時間數據的行數據。使分區大小處在最佳性能的合理範圍內;分區太小將限制執行批處理操做的能力(包括查詢),分區過大則使查詢成本很高(可能致使大量併發插入的瓶頸)。
    • 分區函數的選擇也將從根本上影響查詢性能;表存儲方式提供按 {分區鍵, 行鍵} 的高效查找,可是處理 {分區鍵, 行匹配篩選器} 和 {分區鍵匹配篩選器, 行鍵匹配篩選器} 的效率不高。查詢要求全局表掃描 ({行鍵匹配篩選器})。
    • 分區能夠像單個實體這樣小;這爲純查找工做負荷(如購物車管理)提供了通過優化的性能。
  • 儘量在存儲區中將操做進行批處理。表寫入應進行批處理,一般經過使用 .NET 客戶端 API 中的 SaveChanges 方法來實現。將一系列行插入表,而後在一個批處理中使用 SaveChanges 方法提交更改。對 blob 存儲區的更新也應使用 PutBlockList 方法成批提交。與表存儲 API 同樣,針對一個塊範圍調用 PutBlockList 而非使用單個 blocks。
  • 表屬性選擇短列名;由於元數據(屬性名稱)在帶內存儲。列名也算在最大行大小 1 MB 內。過長的屬性名稱會浪費系統資源。

            

                                

如「瞭解 Azure」一節中所述,SQL Database 將整個關係數據庫做爲服務功能提供,支持以向外擴展的方式對數據存儲區進行訪問。在大型應用程序中成功使用 SQL Database 要求進行幾個謹慎的設計和實現選擇;本節將介紹一些重要的設計點和最佳作法。

不少應用程序須要使用元數據表存儲諸如路由、分區和租戶信息之類的詳細信息。將此元數據存儲在單個數據庫中會致使單個故障點以及沒法進行擴展。中央元數據存儲區應經過結合使用如下方式向外擴展:

  • 激進緩存:配置數據庫中的信息應激進緩存到分佈式緩存(如 memcache 或 Azure Caching)。
    • 請注意在應用程序啓動時積極嘗試從多個工做線程預加載緩存的影響,這一般致使過分加載和數據庫限制。若是你的應用程序須要預加載的緩存,請將加載數據的工做委託給具備可配置加載速度的專用輔助角色(或計劃的任務)。
    • 若是應用程序性能或可靠性依賴於緩存中是否具備某段數據,你的應用程序應拒絕傳入的請求,直到預先填充了緩存。填充數據後,應用程序應返回相應的錯誤消息或代碼。
  • 向外擴展:按垂直(按表)或水平(跨多個分片的段表)方式對數據進行分區,以將負載分配到多個數據庫。

已分區的 SQL Database 的整體可擴展性受單個數據庫(分片)的規模以及這些分片組合起來以增大規模的效率的影響:

  • 由於事務日誌限制了較大的事務(如重建索引),單個表大小不該超過約 10 GB(請注意這個實際限制取決於目標表索引的大小,所以對於你的數據庫該值可能大於也可能小於 10 GB)。對於大的單個表,請將它拆分爲較小的幾個表,並使用分區視圖來提供統一覆蓋。
    • 保持小的單個表能夠減少分階段升級過程當中架構更改或索引重建的影響。對多個較小表的更改能夠儘量減少因爲阻塞操做形成的停機時間和延遲時間。
    • 這個分區方式使管理技術複雜化。諸如重建索引等操做必須以迭代方式在全部組件表上執行。
  • 使單個數據庫(分片)足夠小。一些持續操做(如針對 50 GB 以上數據庫的數據庫複製或導出)可能須要幾小時才能完成(服務取消操做須要運行 24 小時以上)。

進行連續服務交付、管理分佈式數據庫更新或架構修改時,須要當心謹慎以確保順利升級。在生產數據存儲區中控制架構和元數據操做的全部傳統最佳作法比以往更爲重要。例如,在 100 個數據庫中的某個數據庫調試和解決意外刪除的存儲過程是個比以往復雜得多的任務。

由於架構更新和數據修改在分片上不是事務一致的,在過渡期應用程序更新必須同時兼容舊架構和新架構。這個要求一般表示應用程序的每一個版本必須至少與架構的當前版本和上一個版本兼容。

                         

轉換到數據庫的向外擴展集合會帶來一些與鏈接管理有關的問題。每一個 SQL 數據庫鏈接是相對昂貴的資源,這已由客戶端 API(ADO.NET、ODBC、PHP 等)中鏈接池的普遍使用所證明。每一個應用程序實例並不維護多個與中央 SQL Server 的鏈接,而是必須潛在維護與多個數據庫服務器的鏈接。

由於鏈接是昂貴可能希缺的資源,應用程序必須經過及時退回池中鏈接來正確管理鏈接。應用程序代碼應使用自動鏈接釋放機制;在 .NET 中,最佳作法是在 using 語句內封裝 SqlConnection 的全部使用,例如:

C#        
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 個鏈接。此網絡拓撲與默承認用鏈接數的組合致使較大的應用程序出現嚴重的網絡故障

  • 將較大的應用程序部署在多個託管服務上。
  • 在多個訂閱中部署數據庫(不只是同一訂閱中的多個邏輯服務器)能夠得到更爲惟一的 IP 地址。
  • 實現多層應用程序以將出站操做關聯到針對的應用程序實例(請參見有關託管服務的上一節)。
  • 請記住鏈接池根據每一個惟一鏈接字符串來維護並對應於每一個惟一的數據庫服務器、數據庫和登陸組合。使用 SQL 客戶端鏈接池並顯式限制 SQL 鏈接池的最大大小。SQL 客戶端庫根據須要重用鏈接;小鏈接池可能致使應用程序在等待鏈接可用時延遲時間增長。

如下列表提供有關減小所需活動鏈接數的建議:

                                      

轉換到分佈式數據模型可能須要更改數據庫架構的設計以及更改某些查詢類型。要求跨多個數據庫使用分佈式事務的應用程序可能具備不合適的數據模型或實現(例如,嘗試強制實施全局一致性)。這些設計必須重構。

因爲可用性和可擴展性的限制,使用中央序列生成工具時應避免應用程序的任何不尋常的方面。不少應用程序利用序列提供全局惟一標識符,使用中央跟蹤機制根據須要增大該序列。這個體系結構致使了一個全局爭用點和瓶頸,系統的每一個組件都須要與之交互。此瓶頸對於可能斷開鏈接的移動應用程序更爲突出。

所以,應用程序應利用可在分佈式系統中生成全局惟一標識符(如 GUID)的函數。根據設計 GUID 不是按順序的,所以在做爲大表中的彙集索引時它們可能致使碎片。在大數據模型中爲了減少 GUID 的碎片影響,請將數據庫分片,使得每一個分片相對較小。這容許 SQL Database 在副本故障轉移期間對數據庫自動整理碎片。

採用分佈式數據模型時客戶端應用程序代碼必須考慮如下幾個方面:

  • 分區鍵:分區鍵應是每一個數據類或模型的一部分,並可能使用屬性進行修飾以容許發現分區鍵。
  • 遙測:數據訪問層應自動記錄有關每一個 SQL 調用的信息,包括目標、分區、上下文、延遲和全部錯誤代碼或重試。
  • 分佈式查詢:執行跨分片查詢將引入幾個新問題,包括路由、分區選擇和部分紅功的概念(一些分片成功返回了數據而另外一些分片則沒有返回數據)。數據訪問層應提供委託來以異步(並行)散播-彙集方式執行分佈式查詢,返回組合結果。分佈式查詢還須要考慮限制基礎資源:
    • 最大並行度(以免線程過多,鏈接壓力過大)。
    • 最長查詢時間(以減少長時間運行的查詢的整體延遲時間或下降分片速度)。

還有幾個必須執行的管理任務:

  • 引用表:沒有提供全局連貫的查詢空間,查詢中 JOIN 的引用數據必須複製到每一個分片。要求維護並複製數據到每一個分片的引用表,以提供足夠一致的本地引用數據。
  • 從新平衡分區:單個分片可能成爲不平衡的,它們可能佔用過多資源併成爲阻塞點,也可能由於使用率低下而浪費資源。在這些狀況下,必須從新平衡分區以從新分配資源。從新平衡機制在很大程度上依賴於分區策略和實現。在大多數狀況下從新平衡一般涉及:
    • 將一個分片內的現有數據複製到一個或多個新分片,能夠經過拆分/合併機制(對於基於範圍的分區)或使用實體級複製和從新映射(對於基於查找的分區)。
    • 更新分片映射以指向新分片,而後補償在過渡期間寫入舊分片的全部數據。
  • 數據刪除:隨着應用程序數據的增加和收集,考慮按期刪除舊的未使用的數據,以增長主系統的可用空間和容量。刪除的數據不是以同步方式從 SQL Database 清除的,而是將它標記爲刪除,由後臺進程進行清理。將數據標記爲刪除的經常使用方法是使用一個標記列,它能夠表示行爲活動、不活動或已標記爲刪除。這能夠阻止在一段時間查詢數據,若是用戶指示仍須要數據,數據能夠輕鬆移回生產系統。
    刪除數據還能夠觸發碎片,可能須要索引重建以確保查詢操做的效率。較舊的數據能夠存檔到:
    • 一個在線存儲區(輔助 SQL Database),這增長了主系統的空間可是沒有下降成本。
    • 一個離線存儲區(如 blob 存儲區中的 bcp 或 bacpac 文件);這增長了主系統的空間而且下降了成本。
    • 位存儲桶。你能夠選擇從主系統永久刪除數據以增長空間。

              

                                      

SQL Database 中的幾個常見事件能夠觸發暫時性鏈接故障,如副本故障轉移。應用程序必須實現相應的代碼來處理暫時性故障並正確應對資源用盡和限制:

  • 使用重試機制處理暫時性鏈接故障:數據訪問代碼應利用策略驅動的重試機制來應對暫時性鏈接故障。重試機制應檢測臨時鏈接故障,從新鏈接到目標 SQL Database 並從新發出命令。
  • 使用重試和退讓邏輯處理限制:數據訪問代碼應利用策略驅動的重試和退讓機制來應對限制狀況。重試機制應檢測限制狀況並逐漸退讓嘗試以從新發出命令(以免可能延長限制狀況的「護航」效應)。
    • 數據訪問代碼還應能夠實施退讓到備用數據存儲區,如 blob 存儲區。這個備用存儲區爲捕獲活動、數據和狀態,避免在出現延長的限制或可用性事件時數據丟失提供耐用的機制。

.NET 應用程序可以使用可識別 SQL Database 的重試和退讓邏輯框架,如雲應用程序框架 (CloudFx)企業庫暫時性故障處理程序。這些框架提供經常使用數據訪問類(如 SqlConnection 和 SqlCommand)以及可直接調用的策略的包裝。

C#        
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 存儲過程或命令文本。請注意不要在日誌文件中泄露敏感信息 – 一般避免記錄命令文本。
  • 調用的端到端延遲。經過使用 Stopwatch 或另外一輕型計時器在計時委託中包裝調用。
  • 調用的返回代碼(成功或失敗)以及重試次數和失敗緣由(鏈接已刪除、被限制等)。
  • 鏈接的會話 ID,可經過 CONTEXT_INFO() 屬性(使用 ReliableSqlConnection 時爲 SessionTracingId 屬性)訪問。可是,對於每一個客戶端調用請不要從 CONTEXT_INFO() 檢索會話 ID 屬性,由於此命令觸發另外一個到服務器的往返。

              

                                      

爲了更高效使用 SQL Database,針對 SQL Database 的查詢和數據插入應儘量進行批處理和以異步方式執行。這不只提升了應用程序效率,並且減少了 SQL Database 上的整體系統負載(容許更大的吞吐量)。

  • 成批插入。對於連續數據插入操做(如註冊新用戶),數據應針對目標分片進行批處理和對齊。這些批應基於觸發器按期(異步)寫入 SQL Database,如目標批大小或時間窗口。對於小於 100 行的批大小,表值函數一般比大容量複製操做效率更高。
  • 避免聊天式界面。減少執行一個查詢或一組操做所需的到數據庫的往返次數。聊天式界面具備很高的管理開銷,它加大系統負載,下降吞吐量和效率。請嘗試合併相關操做,一般使用存儲過程來減小往返次數。

              

            

做爲保持業務連續性整體方案的一部分,在 SQL Database 中存儲的數據應按期導出 blob 存儲區。Blob 存儲區默認狀況下支持可用性和地理複製。

實現一個用於將數據庫按期導出到 blob 存儲區的計劃任務。使用專用存儲賬戶。此任務應在目標數據庫所在的數據中心中運行,而不是從內部桌面或服務器運行。

將導出任務安排在系統活動低的時間,以儘量減少對最終用戶體驗的影響。導出多個數據庫時,請限制並行導出的程度以減少系統影響。

                                      

瞭解你的 SQL Database 的運行情況、性能和容量是影響整體服務交付的關鍵因素。SQL Database 經過動態管理視圖提供所需的原始信息,可是當前沒有用於捕獲、分析和報告關鍵度量值的現成基礎結構。要爲 SQL Database 提供此功能,請考慮如下作法:

  • 實現一個按期任務來收集與系統負載、已用的資源(工做線程、存儲空間)和傳入公共存儲庫的數據有關的關鍵性能數據。例如,考慮 Azure 診斷使用的表。此任務必須從屬於你的應用程序的全部數據庫收集數據。收集一般以向外擴展的方式執行(即同時從多個數據庫收集數據)。
  • 實現按期任務以彙總此信息,得到有關你部署的數據庫的運行情況和容量的關鍵性能指標。

              

          
                                

Azure 診斷提供收集應用程序和實例級遙測數據的基線。可是,要了解在 Azure 上運行的大型應用程序的情況須要認真配置和管理數據流。與能夠利用豐富的 Windows 診斷實用工具的集中式向上擴展應用程序不一樣,向外擴展的分佈式系統中的診斷必須在系統投入運行前實現 – 它們不可能過後再考慮

錯誤處理、上下文跟蹤和遙測捕獲對於瞭解錯誤事件、根本緣由和解決方法是相當重要的。

  • 不要將活動站點數據和遙測數據發佈到同一存儲賬戶。請爲診斷使用專用存儲賬戶。
  • 爲塊式(高容量、高延遲、粒狀數據)和聊天式(低容量、低延遲、高值數據)遙測建立單獨的通道
    • 將標準 Azure 診斷源(如性能計數器和跟蹤)用於聊天式信息。
    • 使用通用的日誌記錄庫(如企業應用程序框架庫 log4net 或 NLog)來實現大容量記錄到本地文件。使用診斷監視器配置中的自定義數據源將此信息按期複製到 blob 存儲區。
  • 記錄對外部服務的全部 API 調用,記錄的信息包括上下文、目標、方法、計時信息(延遲)和結果(成功/失敗/重試)。使用塊式記錄通道以免診斷系統充斥大量遙測信息。
  • 將寫入表存儲區的數據(性能計數器、事件日誌、跟蹤事件)寫入時長 60 秒的時間分區。嘗試寫入過多數據(過多點源、太低的收集間隔)可能填滿此分區。請確保錯誤尖峯信號不觸發對錶存儲區的大量插入嘗試,由於這可能觸發限制事件。
    • 選擇要從這些源收集高值數據,包括關鍵性能計數器、嚴重/錯誤事件或跟蹤記錄。
    • 選擇合適的收集間隔(5–15 分鐘)以減小必須傳輸和分析的數據量。
  • 確保能夠在運行時修改日誌記錄配置,而沒必要強制執行實例重置。還要驗證配置的粒度足以支持記錄系統的特定方面,如數據庫、緩存或其餘服務。

Azure 診斷不提供從屬服務(如 SQL Database 或分佈式緩存)的數據收集。要提供應用程序及其性能特徵的綜合視圖,請添加基礎結構來收集從屬服務的數據:

  • 收集從屬服務的關鍵性能和使用數據,並將它們做爲性能計數器記錄發佈到 WAD 存儲庫。
    • Azure 存儲(使用 Azure 存儲分析)。
    • SQL Database(使用動態管理視圖)。
    • 專用緩存(使用性能計數器或運行情況監視 API)。
  • 按期分析原始遙測數據來建立聚合和彙總(以計劃的任務形式)。
相關文章
相關標籤/搜索