2012-11-08 31 views
0

我有一個正在爲Windows Azure開發的ASP.NET應用程序。我們認爲有必要使用數據庫分片來提高寫入時間,因爲該應用程序非常重要,但數據很容易被隔離。但是,我需要跟蹤所有實例中的一些中心變量,並且我不確定存儲該信息的最佳位置。我有什麼選擇?如何在分片環境中管理集中值

要求:

  • 必須耐用,能存活的實例重啓
  • 必須同步。在這種情況下避免衝突的更新或者至少拋出異常是非常重要的,而不是默默地重寫值或失敗。
  • 必須相當快(每秒

我想過寫一個單獨的組件上,簡單地讀取存儲/寫入值,並將它們刷新到磁盤幾乎每一個工作者角色運行2000+讀/寫經常,但我認爲必須有一些已經爲此目的而寫的東西,我可以在Windows Azure中適用。

我認爲我在尋找的是像Apache ZooKeeper這樣的系統,但我不想「處理在工作角色啓動期間安裝JRE以及所有爵士樂。

Ed它:基於下面的建議,我想用下面的代碼使用Azure的表存儲:

var context = table.ServiceClient.GetTableServiceContext(); 
var item = context.CreateQuery<OfferDataItemTableEntity>(table.Name) 
    .Where(x => x.PartitionKey == Name).FirstOrDefault(); 

if (item == null) 
{ 
    item = new OfferDataItemTableEntity(Name); 
    context.AddObject(table.Name, item); 
}      

if (item.Allocated < Quantity) 
{ 
    allocated = ++item.Allocated; 
    context.UpdateObject(item); 
    context.SaveChanges(); 
    return true; 
} 

然而,context.UpdateObject(item)調用失敗The context is not currently tracking the entity.不查詢上下文項目最初將其添加到上下文跟蹤機制?

回答

0

你需要的是Table Storage,因爲它所有符合您的要求:

  • Durabl e:是的,表存儲是存儲帳戶的一部分,與特定的Cloud Service或實例無關。
  • 已同步:是的,表存儲是存儲帳戶的一部分,與特定的Cloud Service或實例無關。
    • 避免衝突更新這是非常重要的:是的,這可能與使用的的ETag
  • 相當快的?很快,up to 20,000 entities/messages/blobs per second

更新:

下面是一個使用新的存儲SDK(2.0)一些示例代碼:

var storageAccount = CloudStorageAccount.DevelopmentStorageAccount; 
var table = storageAccount.CreateCloudTableClient() 
          .GetTableReference("Records"); 
table.CreateIfNotExists(); 

// Add item. 
table.Execute(TableOperation.Insert(new MyEntity() { PartitionKey = "", RowKey ="123456", Customer = "Sandrino" })); 

var user1record = table.Execute(TableOperation.Retrieve<MyEntity>("", "123456")).Result as MyEntity; 
var user2record = table.Execute(TableOperation.Retrieve<MyEntity>("", "123456")).Result as MyEntity; 

user1record.Customer = "Steve"; 
table.Execute(TableOperation.Replace(user1record)); 

user2record.Customer = "John"; 
table.Execute(TableOperation.Replace(user2record)); 
  1. 首先,它增加了項目123456
  2. 然後,我模擬2個用戶獲取相同的記錄(想象他們都打開了一個頁面顯示記錄)。
  3. 用戶1速度很快並且更新了該項目。這工作。
  4. 用戶2仍然打開窗口。這意味着他正在處理該項目的舊版本。他更新舊的項目並嘗試保存它。這將導致以下異常(這是可能的,因爲SDK ETag相符):

The remote server returned an error: (412) Precondition Failed.

+0

我的要求是能夠更新一個實體,只有當前一個值與期望值相匹配時才更新實體(樂觀鎖定,即'更新實體,其中property = value'。這可以通過表存儲來完成嗎?我已經在網絡上看到過它的提示,但沒有具體的例子...... – Chris

+0

是的,你可以使用ETag來實現這一點,新SDK使得這很容易 –

+0

我試圖按照你的建議去做,但是出現錯誤,請參閱上面的編輯 – Chris

0

我結束了混合緩存/表的存儲解決方案。所有實例都通過Azure緩存跟蹤變量,而第一個實例則啓動一個計時器,該計時器每秒將值保存到表存儲器中。在啓動時,緩存變量將使用保存到表存儲的值進行初始化(如果可用)。