本文章是由機器翻譯。

預測:多雲

龐大的 Windows Azure

約瑟夫 · 富爾茨

 

Joseph Fultz
就個人而言,我愛的東西周期的方法。我總是似乎每個物件或機制的演變表示二元性目的的進展和重述了過去的立場。技術是好地方看到這一點,因為,在其中更改已進行的步伐很容易在短時間內看到很多的演變。

對我來說,NoSQL 運動是只是這種演變。起初我們的文檔,,我們讓他們在檔中並在檔櫃中,並最終在檔共用中。這是一個正常的事務狀態。自然的問題是規模我們真的能環繞我們圍繞著它的大腦。所以我們合理化內容選擇合理化和正常化的資料模型,將説明我們可以預見的是佔用空間、 存儲資料、 索引資料和能夠找到它。理性模型的問題是因為他們不自然。

請輸入 NoSQL,似乎混合的自然和關係模型。NoSQL 是一種優化的存儲和檢索大量資料的資料庫管理系統。這是讓我們保持文檔樣式的資料,仍可利用在日常生活的關係資料庫管理系統 (RDBMSes) 中找到一些功能的方法。

NoSQL 的主要工具之一是從 10gen Inc.,面向文檔的開源 NoSQL 資料庫系統中,MongoDB,這個月我要去關注對 Windows Azure 環境中使用 MongoDB 的設計和實施方面的一些。我假設你知道一些有關NoSQL 和 MongoDB。如果不是,您可能希望看一看朱莉列爾曼 2011 年 11 月的資料點的列,"什麼到底是文獻資料庫嗎?"(msdn.microsoft.com/magazine/hh547103),和.java 的可能 2010年工作程式師列中,"去 NoSQL 與 MongoDB"(msdn.microsoft.com/magazine/ee310029)。

首先要注意的事項

如果你正想嘗試新的 MongoDB,或考慮它作為 Windows Azure SQL 資料庫或 Windows Azure 表的替代方法,您需要注意的幾個問題的設計與規劃側、 一些相關的基礎設施和一些發展。

部署體系結構

一般情況下,返回的資料最終需要可用和持久。要用 MongoDB,可以做到這一點,請使用複製的一組。複製集提供故障切換和複製,使用一點點的人工智慧 (AI) 以解決任何領帶中選出主節點的集合。這意味著您的 Windows Azure 角色是您需要三個實例設置一個最小的複製集,再加上您可以為每個角色映射到一個磁碟機的存儲位置。請注意由於在虛擬機器 (Vm) 中的差異,您可能要有至少中型 Vm 供任何重大部署。否則,該記憶體或 CPU 可以迅速成為瓶頸。

圖 1 描述了典型的體系結構,向公眾部署最少的 MongoDB ReplicaSet 不公開的。您可以將其公開的資料存儲在外部,轉換,但它是更好的辦法,通過服務層。MongoDB 可以説明其內置功能,通過位址的問題之一是設計和部署一個分散式的資料的體系結構。MongoDB 有一個完整的功能設置為支援盡可能 ; 與 ReplicaSets 結合該功能,Windows Azure 計算和你有的是高度可擴展的、 分散式的、 可靠的資料存儲區。為了説明您入門,10gen,提供了一個示例解決方案,設置最小的 ReplicaSet。你會發現在資訊 bit.ly/NZROWJ ,你可以抓住檔從 GitHub 在 bit.ly/L6cqMF

Windows Azure MongoDB Deployment
圖 1 Windows 天青 MongoDB 部署

資料結構描述

正在在 DB 架構設計的專家可能實際上阻礙你設計的 NoSQL 方法時。更像是物件建模與集成設計用於消息傳遞基礎設施所需的技能。這樣做的原因有兩個:

  1. 資料被看作是一個文檔,並有時包含嵌套的物件或文檔。
  2. 有最少支援聯接,所以你要平衡的嵌套和調用用戶端有必須要走的單一視圖的數量的影響對資料的存儲格式。

從一個關係的心態轉移到 MongoDB 文檔看的第一次活動之一重新設計的資料架構。對於某些獨立關係模型中的物件,被保持分離。例如,產品和訂單仍將單獨的架構,在 MongoDB,和您仍將使用外鍵做兩者之間的查找。簡化了一點,這兩個物件與另一個重新設計大多是通俗易懂的如中所示圖 2

Direct Schema Translation
圖 2 直接架構翻譯

但是,它可能不一樣容易當您使用分隔在概念上,儘管他們可能很容易和顯然分隔關係模型中並不是那樣乾淨的架構。例如,客戶和 CustomerAddresses 都可能會合並這些客戶將包含關聯的位址的集合的實體 (請參見圖 3)。

Converting Relational Schema to Nested Object Schema
圖 3 轉換為嵌套物件架構的關係架構

你需要仔細看看你的關係模型,並考慮每個外鍵關係,如何將會得到表示作為實體關聯圖中它翻譯到 NoSQL 模型。

資料交互

同時查詢行為和緩存行為是很重要的一個關聯的系統,但它緩存在這裡仍然是最重要的行為。多同 Windows Azure 表一樣,很容易放進 MongoDB 的物件。並與 Windows Azure 表和更像是 Windows Azure SQL 資料庫,不同的任何欄位可以編制索引,允許單個物件的更好的查詢性能。然而,缺乏的聯接 (和普遍缺乏的查詢表現力) 變成一次可能是同一個查詢或多個聯接厚實的資料返回到後端資料存儲區的多個調用,以獲取相同的資料。這可能有點令人生畏,如果你想要獲取物件的集合,然後獲取相關的集合的第一個集合中的每一項。因此,使用我的關係 pubs 資料庫,我也許會寫類似于以下操作,以獲取所有作者姓氏和來自每個作者的所有書名的 SQL 查詢:

    Select authors.au_lname, authors.au_id,
      titles.title_id, titles.title
    From authors inner join titleauthor
      on authors.au_id = titleauthor.au_id
      inner join titles on
      titles.title_id = titleauthor.title_id
    Order By authors.au_lname

與此相反,若要獲取使用的 C# 驅動程式與 MongoDB 相同的資料,代碼看起來像所示圖 4

圖 4 加入到 MongoDB 集合

MongoDatabase mongoPubs = _mongoServer.GetDatabase("Pubs");
MongoCollection<BsonDocument> authorsCollection =
  mongoPubs.GetCollection("Authors");
MongoCursor<BsonDocument> authors = authorsCollection.FindAll();
string auIdQueryString = default(string);           
Dictionary<string,BsonDocument> authorTitles =
  new Dictionary<string,BsonDocument>();
// Build string for "In" comparison
// Build list of author documents, add titles next
foreach (BsonDocument bsonAuthor in authors)
{
  auIdQueryString = bsonAuthor["au_id"].ToString() + ",";
  authorTitles.Add(bsonAuthor["au_id"].ToString(), 
    new BsonDocument{{"au_id",
    bsonAuthor["au_id"].ToString()},
   {"au_lname", bsonAuthor["au_lname"]}});
   authorTitles.Add("titles",
   new BsonDocument(new Dictionary<string,object>()));
}
// Adjust last character
auIdQueryString = auIdQueryString.Remove(auIdQueryString.Length-1,1);
// Create query
QueryComplete titleByAu_idQuery = Query.In("au_id", auIdQueryString);
Dictionary<string, BsonDocument> bsonTitlesToAdd =
  new Dictionary<string,BsonDocument>();
// Execute query, coalesce authors and titles
foreach (BsonDocument bsonTitle in 
  authorsCollection.Find(titleByAu_idQuery))
{
  Debug.WriteLine(bsonTitle.ToJson());
  // Add to author BsonDocument
  BsonDocument authorTitlesDoc = 
    authorTitles[bsonTitle["au_id"].ToString()];
  ((IDictionary<string, object>) authorTitlesDoc["titles"]).Add(bsonTitle["title_id"].ToString(), 
      bsonTitle);
}

有你可能優化這通過代碼和結構,但不要錯過雖然 MongoDB 是適合甚至對嵌套物件直接查詢,更複雜的查詢,需要跨實體集是一個好一點點的點的方法 ... ... 嗯,讓我們只是說更多的手冊。 我們大多數人使用 LINQ 説明橋物件-關係的世界。 與 MongoDB 有趣的事是要將這座橋,但相反的原因 — — 你會錯過的關係的功能。

你也可能會錯過參照約束,尤其是外鍵約束。 因為確實可以添加任何 MongoDB 集合中,專案可能有也可能不正確的資料以使其與其他實體相關。 雖然這看起來像一個失敗的平臺如果你是一個頑固的 RDBMS 風扇,它不是。 事實上,它是在哲學中的離境。 一般情況下,對於 NoSQL 資料庫想法是移動系統不資料存儲區中的情報,讓上讀取和寫入資料的存儲集中的資料。 因此,如果你覺得需要顯式強制使用外鍵約束像 MongoDB 實現中的東西,你會做通過業務或服務層,坐在前面的資料存儲。

遷移

一旦你已經重新設計的資料架構和考慮查詢行為的要求是要獲取一些資料,在雲計算以便使用它的時候。

壞消息是有沒有嚮導,您可以指向您的 Windows Azure SQL 資料庫實例和您的 MongoDB 實例並按一下遷移。 您將需要編寫一些腳本,在外殼程式中或在代碼中。 幸運的是,如果 MongoDB 側方程的代碼構造很好,你會能夠重用部分好它正常運行時運行的解決方案。

第一步引用的 MongoDB.Bson 和蒙戈­DB。驅動程式庫和使用添加的語句:

using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson.Serialization.Conventions;
using MongoDB.Bson.Serialization.IdGenerators;
using MongoDB.Bson.Serialization.Options;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver.Builders;
using MongoDB.Driver.GridFS;
using MongoDB.Driver.Wrappers;

物件然後將顯示一些新的方法,對他們都非常有用,當你試圖從常規.net 物件移動到與 MongoDB 一起使用的 Bson 物件。 作為圖 5 所示,這變得很明顯,從資料庫讀取到 BsonDocument 將保存到 MongoDB 轉換的輸出行的函數中。

圖 5 資料移轉與 LINQ 和 MongoDB

pubsEntities myPubsEntities = new pubsEntities();
var pubsAuthors = from row in myPubsEntities.authors
  select row;
MongoDatabase mongoPubs = _mongoServer.GetDatabase("Pubs");
mongoPubs.CreateCollection("Authors");
MongoCollection<BsonDocument> authorsCollection =
  mongoPubs.GetCollection("Authors");
BsonDocument bsonAuthor;
foreach (author pubAuthor in pubsAuthors)
{
  bsonAuthor = pubAuthor.ToBsonDocument();
    authorsCollection.Insert(bsonAuthor);
}

中的簡單示例圖 5 將直接使用 MongoDB 擴充方法的資料轉換。 不過,你必須小心,尤其是與 LINQ,當執行此操作的類型。 例如,如果我嘗試直接為標題相同的操作,Titles 表中的實體模型中的物件圖的深度將導致 MongoDB 驅動程式產生一個堆疊溢位錯誤。 在這種情況下,轉換會稍微詳細在代碼中,如中所示圖 6

圖 6 轉換值的單獨

pubsEntities myPubsEntities = new pubsEntities();
var pubsTitles = from row in myPubsEntities.titles
  select row;
MongoDatabase mongoPubs = _mongoServer.GetDatabase("Pubs");
MongoCollection<BsonDocument> titlesCollection =
  mongoPubs.GetCollection("Titles");
BsonDocument bsonTitle;
foreach (title pubTitle in pubsTitles)
{
  bsonTitle = new BsonDocument{ {"titleId", pubTitle.title_id},
     {"pub_id", pubTitle.pub_id},
     {"publisher", pubTitle.publisher.pub_name},
     {"price", pubTitle.price.ToString()},
     {"title1", pubTitle.title1}};
  titlesCollection.Insert(bsonTitle);
}

要轉換保持盡可能簡單,最好的辦法是編寫 SQL 查詢,以返回可以更輕鬆地添加到適當的 MongoDB 集合的單個實體。有子文件組合的 BsonDocuments,它將採取多步的方法來創建父 BsonDocument,將兒童 BsonDocuments 添加到父 BsonDocument,然後添加到集合的父級。

你需要如果從 Windows Azure SQL 資料庫移動到 MongoDB 執行轉換的明顯位是代碼的所有生活在預存程序、 視圖和觸發器。在許多情況下,代碼會更簡單一些,因為您會將處理同一個 BsonDocument 你堅持下去的兒童而不必跨多個表的關係約束工作整體。此外,而不是編寫 TSQL,你可以使用您喜歡的.net 語言,Visual Studio IDE 的所有支援。可能不最初占的代碼是你要創建,以便能夠跨文檔做交易。在某種意義上,它是疼痛,不得不將所有的平臺功能的 Windows Azure SQL 資料庫移動到應用程式代碼。另一方面,一旦你完成你得非常快速和可擴展的資料的後端,因為它只重點資料穿梭。您還可以通過移動的所有以前被困在 RDMBS 到適當的中介層,邏輯的高度可擴展的中介層。

最後一點要注意一些意義的是由於資料存儲區的性質,資料大小將有可能增加。這是因為每個文檔已持有架構和資料。雖然這可能不是最大,因為低成本的空間在 Windows Azure 表中非常重要的它仍需要必須在設計中考慮的東西。

結論

一旦在 MongoDB 中可用的資料,則使用它會,在許多方面,感覺熟悉。

到 C# (當前的 1.5.0.4566) 驅動 1.4 LINQ 支援大大增加,因此,編寫的代碼不會感到完全陌生。因此,如果您的專案或解決方案可能會像 MongoDB NoSQL 資料存儲區中的受益,不要讓嚇唬你的語法,因為調整將會最小。但是請記住,有一個成熟的、 穩健的 RDBMS 平臺之間的一些重要差異 — — 例如 Windows Azure SQL 資料庫 — — 和 MongoDB。例如,健康和監測將需要更多的手動工作。而不是監測只有一些 Windows Azure SQL 資料庫實例的數目,你要監視主機工作者角色、 Windows Azure Blob 存儲主機的資料庫檔案和日誌檔的 MongoDB 本身。

NoSQL 解決方案提供卓越的性能,某些資料庫操作和一些有用的、 有趣的功能,真的可以給一個解決方案開發團隊帶來的好處。如果您有大量的資料,並且你在有限的預算,Windows Azure 選項 MongoDB 可能是您的解決方案體系結構的一大補充。

Joseph Fultz  是在惠普公司,作為 HP.com 全球 IT 組的一部分工作的軟體設計師。他以前是微軟,使用其頂級企業和 ISV 客戶定義的體系結構和設計解決方案的軟體設計師。

由於下面的技術專家,檢討這篇文章:Wen-ming Ye