Azure表存储上的自动增量

时间:2009-12-08 22:28:42

标签: concurrency primary-key azure-storage auto-increment identity-column

我目前正在开发Azure表存储应用程序。在该应用程序中,我有一个表,它将具有相对较少的插入(几千/天),并且这些实体的主键将在另一个表中使用,该表将具有数十亿行。

因此,我正在寻找一种方法来使用自动递增的整数而不是GUID作为小表中的主键(因为它将节省大量存储和插入的可伸缩性并不是真正的问题)。

有关该主题的一些讨论,例如在http://social.msdn.microsoft.com/Forums/en/windowsazure/thread/6b7d1ece-301b-44f1-85ab-eeb274349797

但是,由于并发问题可能很难调试和发现,我对自己实现这个有点不舒服。因此,我的问题是,是否有一个经过充分测试的这个问题?

5 个答案:

答案 0 :(得分:13)

对于每个都会在搜索中找到它的人来说,有一个更好的解决方案。 Minimal time for table lock is 15 seconds - 太可怕了。如果要创建真正可扩展的解决方案,请不要使用它。使用Etag

在表格中为ID创建一个实体(您甚至可以将其命名为ID或其他)。

1)阅读它。

2)增量。

3)指定了InsertOrUpdate WITH ETag(来自读取查询)。

如果上一次操作(InsertOrUpdate)成功,那么您将获得一个新的,唯一的,自动递增的ID。如果失败(HttpStatusCode == 412除外),则表示其他客户端更改了它。所以,再重复1,2和3。 Read+InsertOrUpdate的通常时间小于 200ms 。我的测试工具with source on github

答案 1 :(得分:5)

见Josh Twist的UniqueIdGenerator class

答案 2 :(得分:4)

我还没有实现这个,但正在努力......

您可以使用下一个ID来为一个队列设置种子,然后在需要时从队列中选择它们。

您需要保留一个表以包含添加到队列中的最大数字的值。如果你知道你不会使用大量的整数,那么每隔一段时间就可以让一个工人醒来,并确保队列中还有整数。您还可以使用一个使用过的int队列,工作人员可以检查以便密切关注使用情况。

你也可以挂起那个工人,所以当你的代码需要一个id(偶然)时队列是空的,它可能会中断工人的小睡以尽快创建更多的密钥。

如果该呼叫失败,您需要一种方法(告诉工作人员您将为他们做工作(锁定),然后让工作人员工作以获得下一个ID并解锁)

  1. lock
  2. 获取从表
  3. 创建的最后一个密钥
  4. 递增并保存
  5. 解锁
  6. 然后使用新值。

答案 3 :(得分:4)

我发现的解决方案可以防止重复的ID,并让你自动增加它

  1. lock (lease) a blob让它充当逻辑门。

  2. 然后阅读该值。

  3. 写出递增的值

  4. 发布租约

  5. 使用app / table中的值

  6. 然后,如果您的工作人员角色在此过程中崩溃,那么您的商店中只会丢失一个ID。恕我直言,这比重复更好。

    以下是史蒂夫马克思的这种方法的code sample and more information

答案 4 :(得分:3)

如果你真的需要避免guid,你是否考虑过根据日期/时间使用某些东西,然后利用分区键来最小化并发风险。

您的分区键可以是用户,年,月,日,小时等,行键可以是日期时间的其余部分,以足够小的时间跨度来控制并发。

当然,你必须以Azure中的约会价格问自己,如果避免Guid真的值得所有这些额外的努力(假设一个Guid会起作用)。