本文章是由機器翻譯。

預測:雲端

SQL Azure 和 Windows Azure 資料表儲存體

Joseph Fultz

下載代碼示例

在我們家,經常會有這種情形:我們決定晚上輕鬆點兒,出去吃飯。每個人都很開心,也很享受晚餐的輕鬆時光。我們家周邊有很多餐館可以選擇,事實證明,除非有人明確表示想吃什麼,否則我們很難決定到哪裡吃飯。

當我的許多客戶和同事要決定在雲中使用哪種存儲機制時,也會遇到同樣的問題:面對看起來都差不多的選擇,到底應該選擇哪一個呢?通常,解決困惑的關鍵就是理解 Windows Azure 表存儲和 SQL Azure 的差別。

我無法告訴任何人選擇哪種技術,但會提供一些指導方針,説明大家針對 Windows Azure 表存儲和 SQL Azure 的功能和限制,在評估解決方案和解決方案團隊的需要時作出決定。此外,我還會添加一些代碼,讓您能夠獲得一些使用這兩種技術的開發人員體驗。

資料處理

SQL Azure 和其他關係資料庫通常在存儲系統之上提供資料處理功能。一般來說,相比于資料庫的原始存儲和檢索方面,RDBMS 使用者更感興趣的是資料處理。

例如,如果您想瞭解公司在給定時間段內的總收入,可能要掃描數百 MB 的銷售資料,然後計算 SUM。在資料庫中,您可以向資料庫發送一條查詢命令(幾個位元組),讓資料庫將資料(可能多達數 GB)從磁片檢索到記憶體中,根據適當的時間段過濾資料(通常會減少到數百 MB),計算銷售資料的總和,然後將結果返回到用戶端應用程式(幾個位元組)。

若要在純存儲系統上進行此操作,需要運行應用程式碼的電腦通過網路從存儲系統中檢索所有原始資料,然後開發人員還要編寫代碼對資料執行 SUM 操作。為了進行資料處理而將大量資料從存儲系統傳輸到應用程式,開銷非常大,也非常慢。

SQL Azure 通過查詢、事務和存儲過程來提供資料處理功能,這些功能均在伺服器端實現,只需要向應用程式返回結果。如果您的應用程式需要處理大型資料集,那麼 SQL Azure 就是一個很好的選擇。如果您的應用程式需要存儲和檢索(掃描/篩選)大型資料集,但不需要進行資料處理,那麼 Windows Azure 表存儲就是您的首選。

— Windows Azure 首席專案經理 Tony Petrossian

檢查選項

簡單地擴展範圍以包含其他存儲機制,能夠展現整個藍圖的一小部分,而從較高的層次更容易將存儲選項劃分到各個大類中:

  • 關係資料訪問:SQL Azure
  • 檔和物件訪問:Windows Azure Storage
  • 基於磁片的本地緩存:角色本機存放區

但是,為了進一步驗證選擇,您可以開始問一些簡單的問題,例如:

  • 如何使所有角色在一般情況下都能訪問檔?
  • 如何使檔可以使用,並輕鬆更新檔?
  • 如何在提供結構化訪問語義的同時還能提供充足的存儲和性能?
  • 哪一種方案能提供最佳的性能或最好的可伸縮性?
  • 培訓方面有什麼要求?
  • 有什麼管理案例?

通往明確決定的道路開始變得泥濘,很容易迷失在功能的好處與限制的比較當中。讓我們重新回到 SQL Azure 和 Windows Azure 表存儲上,我打算描述一些理想的使用模式,並為每個模式提供一些代碼示例。

SQL Azure 基礎知識

SQL Azure 提供了關聯式資料庫的基本功能,可供應用程式使用。如果某個應用程式需要在關聯式資料庫管理系統 (RDBMS) 中託管資料,那麼可以採用 SQL Azure。它提供了所有常用語義,可以通過 SQL 語句進行資料訪問。此外,SQL Server Management Studio (SSMS) 可以直接掛接到 SQL Azure 上,它提供了無需使用代碼來處理資料庫的方法,這些方法眾所周知且易於使用。

例如,使用 SQL Azure Web 管理主控台和 SSMS,只需幾步就能設置一個新的資料庫。這些步驟包括:

  1. 通過 Web 創建資料庫
  2. 創建規則,以便從本地電腦訪問資料庫。
  3. 通過本地 SSMS 連接到 Web 資料庫
  4. 在資料庫容器上下文中運行 DDL

如果應用程式當前使用的是 SQL Server 或類似的 RDBMS 後端,那麼 SQL Azure 會是將您的資料轉移到雲中的最簡單方法。

SQL Azure 還是提供基於雲的結構化資料訪問的最佳方法。無論應用程式是否託管在 Windows Azure 中,這都是事實。如果您的應用程式是手機應用程式,甚至是桌面應用程式,SQL Azure 都可以提供方法,將資料放到雲中,然後通過這些應用程式進行訪問。

在雲中使用資料庫與使用內部託管的資料庫沒有太大區別,除了一點需要注意:身份驗證需要通過 SQL Server 身份驗證進行處理。您可能想看看代號為“Houston”的 Microsoft 專案,該專案是為 SQL Azure 開發的新管理主控台,使用 Silverlight 構建。有關此專案的詳細資訊,請參見sqlazurelabs.cloudapp.net/houston.aspx

SQL Azure 開發

快速編寫一個僅包含一個 Windows 表單的示常式序,並在該表單中承載一個資料網格,用於顯示 Pubs 資料庫中的資料,這樣的過程與採用本地資料庫時相比,並不會變得更複雜。我在 Visual Studio 中利用嚮導來添加新的資料來源,而嚮導將逐步引導我創建連接字串和資料集。在本例中,我最終在 app.config 中得到了一個類似如下的連接字串:

<add name="AzureStrucutredStorageAccessExample.Properties.Settings.pubsConnectionString"

     connectionString="Data Source=gfkdgapzs5.database.windows.
net;Initial Catalog=pubs;Persist Security Info=True;User ID=jofultz;Password=[password]"

     providerName="System.Data.SqlClient" />

通常,集成身份驗證是首選的資料庫安全措施,因此再使用 SQL Server 身份驗證就顯得有點奇怪。SQL Azure 通過實施 IP 訪問清單以盡可能降低曝光面,您需要為每個可能連接到資料庫的 IP 範圍向該清單中添加一項。

現在,在 Pubs 資料庫中選擇 Titleview 視圖,回到我特意提供的小示例,採用系統預設名稱的資料集 pubsDataSet 中會有一些生成的代碼,如圖 1 所示。

圖 1 為訪問 SQL Azure 自動生成的代碼

我做了一些拖放操作,將 DataGridView 拖到了表單中,並對連接進行了配置。建立連接之後,我運行了程式,得到一個簡單的資料網格視圖,如圖 2 所示。

圖 2 簡單網格中的 SQL Azure 資料

我不打算建議您在 Visual Studio 中通過嚮導來創建一個企業級應用程式,但是想告訴您,資料訪問或多或少類似于 SQL Server,並且會像預期一樣進行。這意味著,您可以針對它生成一個實體模型並使用 LINQ,因為如果它是本地的而不是託管的,我就會這麼做(請參見圖 3)。

圖 3 使用實體模型和 LINQ

有一個強大的新功能,超越了通常基於 SQL Server 的本地資料庫範圍,那就是可以將資料以 OData 源的形式公開提供的選項(目前通過 sqlazurelabs.com 提供)。您獲得類似如下的 REST 查詢:

https://odata.sqlazurelabs.com/  

  OData.svc/v0.1/gfkdgapzs5/pubs/  

  authors?$top=10

這會生成一個 OData 回應;如果使用 $format=JSON 參數,則會生成 JSON 回應。 這對於應用程式開發人員來說是一個非常大的喜訊,因為您不僅能獲得標準的 SQL Server 行為,而且還能通過配置獲得額外的存取方法,甚至不用編寫一行代碼。 這可以讓我們把重點放在能夠增加業務價值的服務或應用層面,而不用探索如何跨網路將資料從存儲中移進和移出。

如果應用程式需要傳統的關聯式資料訪問,SQL Azure 很可能是更好、更簡單的選擇。 但是,還有一些其他原因能證明 SQL Azure 比 Windows Azure 表儲存更具競爭力。

第一個原因是,如果您的事務率非常高,則說明對資料存儲執行查詢(所有操作)的頻率很高。 SQL Azure 不按事務收費。

SQL Azure 還為您提供了在各種 Windows Azure 資料庫之間設置 SQL Azure 資料同步 (sqlazurelabs.com/SADataSync.aspx) 的選項,以及在本地資料庫和 SQL Azure 安裝之間同步資料的能力 (microsoft.com/windowsazure/developers/sqlazure/datasync/)。 我將在以後的專欄中討論如何對本機存放區設計和使用 SQL Azure 與 DataSync,屆時將介紹如何將 SQL Azure 用於分支節點體系結構。

Windows Azure 表存儲

現在,您已經瞭解了將 SQL Azure 用於存儲的優勢。 那麼,什麼時候使用 Windows Azure 表存儲更合適呢? 在以下幾種情況中,SQL Azure 可能不是合適的選擇。

如果某個應用程式正在進行改造以便遷移到 Web,或者是資料存儲層的實現尚未完成,您可能需要考慮一下 Windows Azure 表存儲。 同樣,如果您不需要關聯式存儲,或者是訪問只限于一次一個表且不需要合併,那麼 Windows Azure 表存儲就很合適。 在這種情況下,您的資料集會很小,合併操作可以由 LINQ 在用戶端處理。

如果您的資料量超過了 SQL Azure 支援的最大資料量(目前為每個實例 50GB),也需要考慮 Windows Azure 表存儲。 請注意,資料量的限制可以通過資料分區來克服,但會增加 SQL Azure 的成本。 在 Windows Azure 表存儲中,相同大小的空間可能會更便宜,而且還通過聲明的分區鍵內置了分區功能。

此外,由於 Windows Azure 表存儲是按事務收費的,對於低訪問頻率的資料或能夠輕鬆緩存的資料會是很好的選擇。

能夠凸顯 Windows Azure 表存儲優勢的其他情景包括:應用程式需要某種結構化的訪問(例如索引查找),但存儲的主要是物件或二進位大型物件 (BLOB)/字元大型物件 (CLOB);您的應用程式可通過支援在表中存放不同類型的資料而受益;因為 SQL Server 安裝中的現有資料結構(或因缺乏某種資料結構)而難以進行遷移。

使用 Windows Azure 表存儲

首先,因為假設要將“表存儲”關聯到 SQL 資料庫,所以使用 Windows Azure 表存儲看起來可能會比較麻煩。 在名稱中使用“表”不會有什麼説明。 在考慮 Windows Azure 表存儲時,我建議您將其視為物件存儲。

作為一名開發人員,請不要將注意力集中在存儲結構或機制上,而是要關注物件以及您要通過它完成的任務。 在 Windows Azure 表存儲中設置物件,對於開發人員來說往往是最大的障礙,但通過物件訪問 Windows Azure 表存儲則很自然,特別是當您使用 LINQ 時。

在開始使用 Windows Azure 表存儲時,需要將對 System.Data.Services.Client 的引用添加到您的專案中。 此外,如果您未使用 Visual Studio 雲範本(可為您提供所需的引用),請添加對 Microsoft.WindowsAzure.StorageClient.dll 的引用。

接下來,創建一個您可以使用的物件/實體(從 Authors 表中竊取):

public class TableStorageAuthor:

  Microsoft.WindowsAzure.StorageClient.TableServiceEntity {

  public int Id {get; set;}

  public string LastName { get; set; }

  public string FirstName { get; set; }

  public string Phone { get; set; }

  public string Address { get; set; }

  public string City { get; set; }

  public string State { get; set; }

  public string Zip {get; set;}

}

您可以使用 TableServiceContext 定義一個資料服務用戶端上下文來處理與存儲的連接,並執行創建/讀取/更新/刪除 (CRUD) 操作(如 圖 4 所示)。TableStorageAuthor 類被用作範本類,以便聲明 AuthorData 元素,將會為該元素返回一個針對 Authors 表的表查詢方法。 它還被用作所實現的 Add 操作的參數類型。

圖 4 訪問 Windows Azure 表存儲

public class AuthorDataServiceContext : TableServiceContext {

  public IQueryable<TableStorageAuthor> AuthorData {

    get {

      return this.CreateQuery<TableStorageAuthor>("Authors");

    }

  }



  public AuthorDataServiceContext (

    Uri baseAddress, StorageCredentials credentials)

    : base(baseAddress.AbsoluteUri, credentials) {}



  public void Add(TableStorageAuthor author) {

    this.AddObject("Authors", author);

    DataServiceResponse dsResponse = SaveChanges();

  }

}

創建目標表:

TableClient.CreateTableIfNotExist("Authors");

使用熟悉的物件創建和屬性分配模式來創建一些資料,並將這些資料添加到在存儲中創建的表中(請參見圖 5)。

圖 5 將資料添加到 Windows Azure 表存儲中

var TableClient = StorageAccount.CreateCloudTableClient();



TableStorageAuthor author = new TableStorageAuthor();

author.FirstName = "Joseph";

author.LastName = "Fultz";

author.RowKey = System.Guid.NewGuid().ToString();

author.Id = author.RowKey;

author.State = "TX";

author.PartitionKey = "TX";



AuthorDataServiceContext ctx = 

  new AuthorDataServiceContext(

  StorageAccount.TableEndpoint, 

  StorageAccount.Credentials);

ctx.Add(author);

添加完所有資料之後,就可以使用 LINQ 進行操作了。 例如,針對實體的選擇操作為:

AuthorDataServiceContext ctx = 

  new AuthorDataServiceContext(

  StorageAccount.TableEndpoint, 

  StorageAccount.Credentials);



var authors = 

  from a in ctx.AuthorData

  select a;



foreach (TableStorageAuthor ta in authors) {

  Debug.WriteLine(ta.FirstName + " " + ta.LastName);

}

我沒有實現更新和刪除操作,但具體方式是類似的。 有一點可能與將 LINQ 用於實體框架的代碼略有不同的是用於創建 TableServiceContext 的代碼,以及用於構建和使用 TableServiceContext 的後續代碼。 如果您正在使用 REST 和 DataServiceContext,執行此操作就非常自然。

您使用 TableServiceContext、TableServiceEntity 和 LINQ 的感受與對 SQL Azure 使用實體框架和 LINQ 的感受是一樣的,雖然在 Windows Azure 表存儲方案中需要手動編寫的代碼更多。

基於解決方案的評估

正如先前所述,如果應用程式已經建立了一個關聯式存儲,最好稍稍借助 SQL Azure 遷移嚮導這樣的工具將該存儲遷移到 SQL Azure。 但是,如果不是這樣的情況,或者應用程式的雲功能部分不需要 RDBMS 的完整功能,請參見圖 6 中的表格,看看哪些列最符合解決方案要求和體系結構的需求。

圖 6 比較 SQL Azure 和 Windows Azure 表存儲

功能 SQL Azure 共同的優勢 Windows Azure 表存儲
選擇語義 跨表查詢 基於主鍵的查詢 單鍵查詢(按分區)
性能和規模 通過多索引、標準化的資料結構等實現高性能,通過跨 SQL Azure 實例手動分區實現可擴展性   通過分區實現自動大規模擴展,即使在大規模部署上也能實現一致的性能
使用者體驗 眾所周知的管理工具和傳統的資料庫設計 熟悉的高水準開發人員體驗 直接序列化;不需要 ORM;通過刪除關係模型簡化了設計模型
存儲樣式 傳統的關係設計模型 適用于所有類型資料的資料存儲 單個表中支援多種類型
成本因素 沒有事務成本,按資料庫大小付費 同一資料中心以外的網路流量成本 沒有空間開銷成本,按照使用量付費
資料載入和同步 在本機存放區和基於雲的存儲之間進行同步;通過傳統的提取、轉換和載入 (ETL) 機制輕鬆將資料移進移出;在不同資料中心的 SQL Azure 資料庫之間同步    

值得注意的是,關於圖 6 中的一些項(例如,與 Windows Azure 表存儲中的管理和資料負載相關的項),市場上已經有一些協力廠商解決方案可以提供其中缺少的功能。 因此,對於重大專案,需要考慮此類工具的成本和功能。

我預期許多應用程式將會需要混合的資料方法,以便充分利用技術。 例如,Windows Azure 表存儲可用於優化提取時間,同時仍然能為文檔、視頻、圖像和其他此類媒體等資源提供大規模擴展功能。 然而,為了便於搜索相關項的中繼資料,相關的資料和物件指標應當存儲在 SQL Azure 中。 這樣的設計還能減少針對 Windows Azure 表存儲的事務流量。 這種互補設計能夠提供以下好處:

  • 保持高輸送量,以便查詢獲得資源
  • 減小 SQL Azure 資料庫的大小,使其成本始終保持最低
  • 通過將大型檔存儲到 Windows Azure 表存儲而不是 SQL Azure 中,將存儲成本降至最低(儘管 BLOB 存儲是首選的檔存儲方式)
  • 按鍵和分區提取此類資源,並從 SQL Azure 資料庫上卸載檢索查詢,以此來維持高檢索性能
  • 允許對 Windows Azure 表存儲中保存的資料進行自動的大規模擴展

簡而言之:您的設計應該綜合利用這兩種存儲機制,各自發揮長處,而不要指望用一種機制完成所有的任務。 無論採用哪種方式,我們仍然期待著雲能給我們一個答案。

Joseph Fultz 是達拉斯 Microsoft 技術中心的架構師,協助企業客戶和 ISV 設計和製作軟體解決方案以滿足商業和市場需求。他在 Tech·Ed 及類似的內部培訓活動中做過講座。

衷心感謝以下技術專家對本文的審閱:Jai Haridas、Tony PetrossianSuraj Puri