16

我目前正在開發Azure表存儲的應用程序。在那個應用程序中,我有一個表格,插入的數據相對較少(幾天/幾天),而這些實體的主鍵將用在另一個表格中,這些表格將有數十億行。Azure表存儲上的自動增量

因此,我正在尋找一種方法來使用自動遞增的整數,而不是GUID,作爲小表中的主鍵(因爲它將節省大量存儲空間,插入的可伸縮性並不是問題)。

關於這個話題已經有了一些討論,例如,在http://social.msdn.microsoft.com/Forums/en/windowsazure/thread/6b7d1ece-301b-44f1-85ab-eeb274349797

但是,由於併發性問題可能很難調試和發現,我自己實現這一點有點不舒服。因此,我的問題是,如果有一個經過充分測試的這樣的推測?

+0

如果你真的擔心它,SQL Azure中有一張表生成身份值? – Andrew 2009-12-08 22:36:16

+0

這是一個非常好的建議。但是這會迫使我設置我的SQL服務器,因爲Azure SQL數據服務不支持標識列:http://www.shanmcarthur.net/cloud-services/design-strategies-for-Azure-and-SDS 。 – Yrlec 2009-12-08 22:41:24

回答

4

我還沒有實現這個還沒有,但我的工作就可以了...

你可以播種您的下一個ID來使用,那麼就隨手摘下隊列中,當你需要他們的隊列。

您需要保留一個表以包含添加到隊列中的最大數字的值。如果你知道你不會使用大量的整數,你可以每隔一段時間就讓一個工人醒來,並確保隊列中仍然有整數。您也可以使用工作人員可以檢查的用過的int隊列來關注使用情況。

你也可以掛鉤這個工作,所以如果你的代碼需要一個id(偶然),那麼如果隊列是空的,它可以中斷工作人員的午睡以儘快創建更多的鍵。

如果調用失敗,你就需要一種方法來(告訴工作人員你會做的工作爲他們(鎖定),然後做得到一張ID和解鎖的工人工作)

  1. 鎖定
  2. 得到表
  3. 增量創建的最後一個鍵並保存
  4. 解鎖

然後使用新的價值。

+1

但是,隊列如何保證不會創建重複的ID?我可以從http://download.microsoft.com/download/5/2/D/52D36345-BB08-4518-A024-0AA24D47BD12/Windows%20Azure%20Queue%20-%20Dec%202008.docx瞭解到的是,如果工作進程在處理隊列消息時失敗,則消息將再次添加到隊列中。因此,你需要在工人角色上做出冪等的工作。如果兩個不同的工作角色使用相同的消息(即相同的ID),我不知道如何使這個冪等性。 – Yrlec 2009-12-09 14:20:02

+2

如果你只有1個創建id的woker,那麼dups將被放入隊列。 將ID拉出隊列時,獲取消息,然後在使用消息內容(id)之前刪除消息。這應該確保沒有id被多次使用。似乎情況更糟的情況是,你可能會失去一把鑰匙,但你的獨特性應該還是不錯的。 – 2009-12-09 17:44:09

+0

上面的第二句話應該是:「如果你只有1個創建id的話,那麼dups就不會被放入隊列中......」 – 2009-12-09 17:45:29

3

如果您確實需要避免使用guid,您是否考慮過使用基於日期/時間的東西,然後利用分區鍵來降低併發風險。

您的分區鍵可以是用戶,年,月,日,小時等,行鍵可以是足夠小的時間段內的其餘日期時間以控制併發性。

當然,你必須問自己,以Azure約會的價格問自己,如果避免一個Guid真的值得所有這些額外的努力(假設一個Guid將會工作)。

4

的解決方案,我發現,防止重複的ID,並讓您自動遞增它是

  1. lock (lease) a blob,讓充當一個邏輯門。

  2. 然後讀取值。

  3. 寫增加值

  4. 鬆開租賃

  5. 使用在您的應用程序/表

然後值,如果你的Worker角色是在這個過程崩潰,然後您的商店中只會缺少ID。恕我直言,這比重複更好。

這裏是從史蒂夫馬克思

10

這種方法對於大家誰就會發現它在尋找一個code sample and more information,有一個更好的解決方案。 Minimal time for table lock is 15 seconds - 這太糟糕了。如果您想創建真正可擴展的解決方案,請不要使用它。使用Etag

在表ID創建一個實體(你甚至可以將其命名爲ID或其他)。

1)請閱讀。

2)遞增。

3)InsertOrUpdate WITHETag指定(來自讀取查詢)。

如果最後一次操作(InsertOrUpdate)成功,那麼你有一個新的,獨特的,自增的ID。如果失敗(HttpStatusCode == 412除外),則意味着其他客戶端更改了它。所以,再重複1,2和3 通常時間Read+InsertOrUpdate小於200ms的。我的測試工具with source on github

+0

好主意。 – PilotBob 2015-11-06 20:37:13

+0

如何使用EGT來保證原子操作,讀取和增加? 這是一種可行的方法嗎? https://docs.microsoft.com/en-gb/azure/storage/storage-table-design-guide#entity-group-transactions – 2017-07-06 08:23:55