2015-01-12 35 views
3

對於我正在開發的項目,我們需要客戶附近數據庫中的客戶數據。基於這個原因,我們採用了微軟的新彈性秤解決方案。這消除了分片的複雜性,並且仍然使您能夠在全球範圍內擴展。在分片之間遷移數據

此刻我正面臨一個相當重要的問題。我需要將數據從1個碎片遷移到另一個碎片。有一個示例應用程序(合併/拆分)可以執行某些操作,但它適用於範圍(1..100,101..400等)。我正在處理的數據庫使用Guids,所以我們不能使用示例代碼。

我自己創建了一個移動/合併管理工具,但在這裏面臨一個問題。 起初我想插入ORM的所有對象和依賴關係。由於一些圓形按鍵,我無法輕鬆做到這一點。因此我現在正在創建一個SQL腳本。 SQL腳本大約130MB,只包含INSERT命令。

所有這些都必須在1筆交易中完成,因爲您不希望遷移完成一半。如果出現錯誤,則應回滾所有內容。

運行這個130MB腳本會給我一些錯誤。我的本地開發機器和SQL Azure耗盡內存。 SQL Azure的:

沒有可用內存不足,緩衝池

和本地:

有一個在資源池「默認」的系統內存不足,無法運行此查詢。

我試過禁用索引,所以這將不會得到重建在每個INSERT。這並沒有解決任何問題。

關於如何進行的任何建議?我無法真正分割腳本,因爲所有數據都必須立刻編號爲INSERT。無論我認爲SSIS包是不是一個選項。

創建我自己的數據庫事務系統看起來有很多矯枉過正和容易出錯的問題。

除了INSERT腳本,我還需要在'舊'分片/數據庫上執行DELETE腳本,所以我猜這個腳本也需要解決方案。我很樂意在1個事務中執行INSERTDELETE腳本,但這在SQL Azure(分佈式事務)上還不可能。

回答

2

Azure SQL DB Elastic Sc​​ale當前預覽中的拆分/合併版本具有已知的限制,即它僅適用於範圍分片地圖。我假設你目前正在爲你的指導使用一個清單碎片地圖。雖然我們目前正在爲彈性比例預覽的更新提供對列表分片地圖和分割/合併的支持,但我鼓勵您試用一下。這種解決方法可能比編寫自己的基礎結構來處理分片之間的數據移動更簡單,併爲您節省大量工作(希望)。

以下是我建議:

  • 射程碎片滿地圖類型GUID替換爲您的列表碎片的地圖。
  • 讓您的數據中每個GUID單身範圍:使用GUID值本身作爲左邊界和 使用由1的二進制表示其右邊界遞增GUID值(記住,右邊界是排他性的,而左邊是包容性的)。您可以使用ShardKey類的RawKey屬性輕鬆檢索左邊界點的二進制表示。
  • 將您的拆分/合併服務指向您的新範圍分片地圖。
  • 在範圍分片地圖上使用拆分/合併的shardlet移動操作將給定的guid從一個分片移動到另一個分片。

讓我知道這是如何工作的。如果你遇到麻煩 - 特別是增加了GUID - 給我一個在torsteng(at)microsoft(dot)com上的留言。

最佳, 託斯滕

下面是一段代碼,可以幫助您與GUID值的遞增。

static void CreateMappings() 
    { 
     ShardKey guid1 = new ShardKey(new Guid("<yourgui1d>")); 
     ShardKey guid2 = new ShardKey(new Guid("<yourguid2>")); 

     ShardKey guid1_next = NextShardKeyForGuid(guid1); 
     ShardKey guid2_next = NextShardKeyForGuid(guid2); 

     _map.CreateRangeMapping(new Range<Guid>(guid1.GetValue<Guid>(), guid1_next.GetValue<Guid>()), _shard1); 
     _map.CreateRangeMapping(new Range<Guid>(guid2.GetValue<Guid>(), guid2_next.GetValue<Guid>()), _shard2); 
    } 

    static ShardKey NextShardKeyForGuid(ShardKey shardkey) 
    { 
     int len = 16; 
     byte[] b = new byte[len]; 

     shardkey.RawValue.CopyTo(b, 0); 

     while (--len >= 0 && ++b[len] == 0) ; 

     // Treat overflow if the current key's value is the maximum in the domain 
     if (len < 0) 
     { 
      return new ShardKey(ShardKeyType.Guid, null); 
     } 
     else 
     { 
      return ShardKey.FromRawValue(ShardKeyType.Guid, b); 
     } 
    } 
} 
+0

感謝您的建議。我之前曾想到過這個,但它顯得太過分了。將嘗試一下,並讓你知道它是否有效。 –

+2

有沒有對列表分片地圖的支持何時實現的粗略時間估計?如果知道我們可以在規劃我們項目的其餘部分時將其留在我們的腦海中。 –

+0

關於此主題的快速更新:我們已將新版Split/Merge推送至NuGet。新版本包含對列表分片地圖的支持。如果您有機會,請嘗試一下:http://www.nuget.org/packages/Microsoft.Azure.SqlDatabase.ElasticScale.Service.SplitMerge/。 –

相關問題