2012-10-20 60 views
1

我試圖按照以下方式構建自己的分片策略。假設我有一個BOXES和ITEMS表,每個框可以有多個項目。我把與同一個BOX相關的項目放在一臺機器上。與亞馬遜RDS合作的DIY分片策略

的box_id主密鑰包含:server_type(實施例100)+ shard_id + total_amount_of_boxes_per_user

total_amount_of_boxes_per_user被存儲在用戶的數據庫中爲每個用戶和我由一個用戶每次插入一個新的盒時增加它。

的服務器類型100將陣容與存儲盒+項目數據的服務器列表。這個server_type-> shard關係列表應該位於中心位置,我曾考慮過將它作爲文檔存儲在DynamoDB上。

上DynamoDB的配置文件:

boxitems_servers[ 
{shard_id: 1, is_locked: false, hostname: 127.0.0.1} 
{shard_id: 2, is_locked: false, hostname: 127.0.0.2} 
{shard_id: 3, is_locked: false, hostname: 127.0.0.3} 
{shard_id: 4, is_locked: false, hostname: 127.0.0.4} 
] 

我模仿我的數據庫和我的應用程序層,所以我不會需要進行連接。最多的時候,我會對數據庫進行一些查詢,但是這些查詢將被緩存在服務器和客戶端。 我正在使用MySQL並在ASP.NET 4.5中開發我的應用程序。

當用戶擊中頁面:

http://domain.com/1000014294967295 

我可以讀取數據,分割,並得到如下:

  • SERVER_TYPE = 100
  • shard_id = 001
  • total_amount_of_boxes_per_user = 4294967295(當然可以少得多,但它是一個整數值)

我從DynamoDB獲取boxitems_servers文檔,並且只獲取server_type的文檔。所以server type 100 = boxitems_servers

我使基於所述主機名(憑證在web.config)碎片的連接和查詢基於所述主鍵1000014294967295的數據。

我可以決定通過將is_locked: true配置文件中鎖定一個特定的碎片。所以當寫入數據(不更新)時,它只會寫入解鎖的碎片。

我將通過使用shard_id%number_of_active_shard上MODULU跨幾個碎片均勻分佈的數據寫入數據。

現在,如果我想補充另一個亞馬遜RDS數據庫,以橫向擴展,我只是創建通過我先前已經創建了亞馬遜的AMI相同架構的數據庫和服務器添加到列表碎片。

boxitems_servers[ 
{shard_id: 1, is_locked: false, hostname: 127.0.0.1} 
{shard_id: 2, is_locked: false, hostname: 127.0.0.2} 
{shard_id: 3, is_locked: false, hostname: 127.0.0.3} 
{shard_id: 4, is_locked: false, hostname: 127.0.0.4} 
{shard_id: 4, is_locked: false, hostname: 127.0.0.5} <- NEW ONE 
] 

Amazon RDS已經具有複製功能,所以我不需要擔心這一點。返回/恢復也很容易。

我唯一的擔心是:

  • 閱讀分頁來自不同的碎片數據,考慮到數據不是均勻分佈的
  • 檢索排序的數據

我需要什麼:我想你對這個策略的看法。我想創建一種即插即用架構,以便使用Amazon RDS並通過添加更多機器和更新配置文件輕鬆擴展。這應該在沒有任何停機時間的情況下運行。

我不想爲那些昂貴的解決方案支付數千美元。我相信我可以構建一個良好的分片解決方案,以滿足我的應用程序需求,該解決方案有幾個表和那些已經非標準化以防止連接的表。 Amazon RDS已經提供了我需要的複製。

我也可以創建邏輯分片,每個shard_id可以更改爲指向另一個數據庫機器(IP地址),但是當我查詢'葉'時,如果我無法在那裏找到數據,我需要向上移動並查詢其他碎片,直到找到數據。

我認爲這可以導致一個很好的分片策略,但有其侷限性,但對於高流量網站(我認爲)可以很好地工作。

回答

0

我不認爲MOD策略是最好的,因爲如果你添加一個節點,你必須將每個記錄移動到不同的數據庫(我知道這是一個不好的選擇)。

一個更好的選擇(比如Cassandra的一個)是對密鑰進行散列並將整個密鑰空間分成塊。

作爲一個例子,如果散列給予FFFF十六進制0之間的答案(這應該是充分的MD5或SHA1)

  • 從0到0FFF在節點1
  • 從1000到4FFF在節點2
  • 從5000到8FFF在節點3
  • 從9000到CFFF在節點4
  • 從D000到FFFF在節點5

這是因爲你在尋找一個寄存器,你只需要在那個節點上請求,如果你需要更多的寄存器,你最終可能會請求所有的節點。取決於你選擇什麼作爲找到你的數據的關鍵(它不需要與PK匹配)

如果你需要添加更多的節點,你只需分割你的節點,例如節點3,在這個例子中上面,你從5000到6FFF留在節點3中,從7000到8FFF到新節點6.