2012-11-09 90 views
3

我正在構建自己的分片解決方案。每個ID的結構如下:跨分片的增量ID

  • 碎片ID(小INT)
  • 表類型ID(小INT)
  • 遞增編號(大INT)

離。 00001000010000000015

我使用虛擬碎片,因此我可以將所有碎片指向單臺服務器,當我需要更多容量時,我只需添加另一臺服務器並將某些虛擬碎片指向該服務器,以便下次數據將被寫入到新的服務器而不是第一個服務器上,儘管讀取的內容會轉到兩臺服務器上,至少在移動數據並將其更改爲配置文件之前。

我的問題是增量編號。我希望那些是獨一無二的。在特定的表中使用mysql中的build int incremental id並不好,因爲我可能會將數據移動到另一個服務器,並且在那裏我可能有另一個使用其表的增量數的數據,所以我可能會得到重複的ID。

所以我的問題是如何以可伸縮的方式生成唯一的ID,而無需使用將生成該ID的外部表,因爲它不會縮放。我可以告訴你Pinterest如何解決這個here這可能會有所幫助。我想給每個表賦予一個增量值,以便爲每個分片跳過不同的值,因此它們在所有分片上的增量值永遠不會相同。

這個想法是建立我自己的亞馬遜RDS分片解決方案,所以副本已經存在,平衡很簡單,因爲我可以利用升級的從屬服務器來掌握並刪除兩臺服務器上的數據,並更改我的分區配置文件。我認爲有可能構建一個可以使用Amazon RDS輕鬆擴展的解決方案,而且這個解決方案比其他公司現在提供的便宜很多(已經完成了我的功課)。

我不想在我的網址中使用GUID。我不介意使用長號碼。 Pinterest,Tumblr,Facebook和其他許多人不使用Guid,所以我知道他們是一個解決方案,並且只是想知道您認爲哪種解決方案最好,考慮到我想使用數字ID。  

我正在開發ASP.NET中C#

+0

我們正在考慮類似的東西,很高興你先問這個問題。 – crush

回答

4

我的應用程序簡單地說,你是生成ID的方法註定:如果你想生成唯一的ID,您需要一箇中心的服務最終將成爲瓶頸。

還包括分片ID的味道不好;將數據移動到新碎片時會發生什麼?你需要更新所有的ID嗎?

如果你想要一個可擴展的解決方案,你將不得不看看UUIDs或類似的方法。

或者,您可以使用中央服務併爲每個呼叫分配一個ID塊(如10'000)。這樣,你就不需要經常敲擊中央服務,但如果服務失敗,整個系統就會死機。

+0

對於UUID建議+1 - 完全分佈的唯一ID在此獲勝。 –

+0

數據不會移動到新的分片,我可以將其移動到新的服務器,但它將始終屬於同一分片。這就是pinterest如何解決它們的縮放問題,所以我不認爲這是一個壞主意,你描述它:http://www.youtube.com/watch?v=aFJm1YlRr5Q –

+0

我沒有打算在URL中使用GUID 。所以我必須找到一個替代方案。我想添加用戶名是數字,但比我的ID更少序列,這將傷害插入性能 –

0

我使用Int16的分片ID在表創建期間通過將分片ID向左移(64-16)並添加1來爲每個表設置AUTO_INCREMENT值。

下一個示例使用ServiceStack.ORMLite庫,但它也可以在純SQL中完成。當我需要創建一個新表,我遍歷每個現有的碎片,開放數據庫連接到碎片(連接的詳細信息都存儲在一個查找表),並調用這個方法:

private static void CreateTableInShard<T>(IDbConnection db, bool overwrite = false, short shardId = 0) 
where T : IDataObject, new() 
    { 
     using (var trans = db.BeginTransaction()) 
     { 
      db.CreateTable<T>(overwrite); 

      if (overwrite) 
      { 
       var tableName = typeof(T).Name; 
       var ai = ((long)shardId << 48) + 1; 
       var sql = @"ALTER TABLE " + tableName + @" 
          AUTO_INCREMENT " + ai + @" ;"; 
       db.ExecuteSql(sql); 
      } 
      trans.Commit(); 
     } 
    } 

public interface IDataObject 
    { 
     long Id { get; set; } 
    } 

我有很多邏輯碎片是最初在一臺機器上。當我必須擴展時,我將不得不將整個分片移動到另一臺計算機,並在查找表中更改分片ID的連接字符串。但此舉之後的ID生成不會受到影響。

要通過id查詢分片表,我可以將分片ID設置爲(id >> 48),然後查詢特定的分片。