23

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

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

关于该主题已经进行了一些讨论,例如在http://social.msdn.microsoft.com/Forums/en/windowsazure/thread/6b7d1ece-301b-44f1-85ab-eeb274349797上。

然而,由于并发问题很难调试和发现,我对自己实现它有点不舒服。因此,我的问题是,是否有经过充分测试的实施?

4

5 回答 5

30

对于将在搜索中找到它的每个人,都有一个更好的解决方案。表锁定的最短时间是 15 秒- 这太糟糕了。如果您想创建真正可扩展的解决方案,请不要使用它。使用Etag

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

1)阅读。

2) 增量。

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

如果最后一个操作 ( InsertOrUpdate) 成功,那么您将拥有一个新的、唯一的、自动递增的 ID。如果失败(HttpStatusCode== 412 例外),则意味着其他客户端更改了它。因此,再次重复 1,2 和 3。通常的时间Read+InsertOrUpdate小于200ms。我的测试实用程序与 github 上的源代码

于 2015-03-12T03:15:52.273 回答
7

See UniqueIdGenerator class by Josh Twist.

于 2011-05-22T23:12:17.570 回答
4

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

您可以使用下一个要使用的 ID 为队列播种,然后在需要时将它们从队列中取出。

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

您还可以连接该工作人员,因此如果当您的代码需要一个 id 时队列为空(偶然),它可能会中断工作人员的午睡以尽快创建更多密钥。

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

  1. 获取从表中创建的最后一个键
  2. 增加并保存
  3. 开锁

然后使用新值。

于 2009-12-09T13:24:35.780 回答
4

我发现防止重复 ID 并让您自动递增的解决方案是

  1. 锁定(租用)一个 blob并让它充当逻辑门。

  2. 然后读取值。

  3. 写入增量值

  4. 解除租约

  5. 使用您的应用程序/表格中的值

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

这是来自 Steve Marx的代码示例和有关此方法的更多信息

于 2011-10-08T05:52:25.007 回答
3

如果您确实需要避免使用 guid,您是否考虑过使用基于日期/时间的东西,然后利用分区键来最小化并发风险。

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

当然,您必须问问自己,以 Azure 中的日期为代价,避免使用 Guid 是否真的值得所有这些额外的努力(假设 Guid 可以正常工作)。

于 2009-12-15T03:34:06.547 回答