5

所以这就是问题所在。我需要更新 azure 表中的大约 4000 万个实体。使用单个实例执行此操作(选择 -> 删除原始 -> 使用新分区键插入)将持续到圣诞节左右。

我的想法是使用运行许多实例的 azure worker 角色。这里的问题是查询抓取了前 1000 条记录。这对一个实例来说很好,但是在运行 20 个实例时,他们的选择显然会重叠......很多。这将导致大量浪费的计算尝试删除已被另一个实例删除的记录并更新已更新的记录。

我已经完成了一些想法,但我最好的选择是让角色用分区键和行键填充队列,然后让工作人员出队并进行实际处理?

有更好的想法吗?

4

3 回答 3

5

很有趣的问题!!!扩展@Brian Reischl 的答案(其中很多都在大声思考,所以请多多包涵:))

假设:

  • 您的实体可以以某种形状或形式序列化。我假设您将获得 XML 格式的原始数据。
  • 您有一个单独的工作人员角色,负责读取实体的所有内容。
  • 您知道编写修改后的实体需要多少个辅助角色。为了争论,我们假设它是你提到的 20。

可能的解决方案:

首先,您将创建 20 个 blob 容器。我们将它们命名为 container-00、container-01、... container-19。

然后您开始阅读实体 - 一次 1000 个。由于您从表存储中获取 XML 格式的原始数据,因此您创建了一个 XML 文件并将这 1000 个实体存储在 container-00 中。您获取下一组实体并将它们以 XML 格式保存在 container-01 中,依此类推,直到您点击 container-19。然后下一组实体进入 container-00。这样,您就可以在所有 20 个容器中均匀分布您的实体。

编写完所有实体后,您处理这些实体的工作角色就会出现。由于我们知道 Windows Azure 中的实例是按顺序排列的,因此您会得到实例名称,例如 WorkerRole_IN_0、WorkerRole_IN_1、...等等。

您要做的是获取实例名称,获取数字“0”、“1”等。基于此,您将确定哪个工作角色实例将从哪个 blob 容器中读取...WorkerRole_IN_0 将从容器-00 中读取文件, WorkerRole_IN_1 将从 container-01 读取文件,依此类推。

现在,您的个人工作者角色实例将读取 XML 文件,从该 XML 文件创建实体,更新这些实体并将其保存回表存储中。完成此过程后,您将删除 XML 文件并继续处理该容器中的下一个文件。读取并处理完所有文件后,您可以删除容器。

正如我之前所说,这是很多“大声思考”的解决方案,必须考虑一些事情,比如当“读者”工作者角色下降时会发生什么以及其他事情。

于 2013-06-26T17:54:51.367 回答
3

如果您的 PartitionKeys 和/或 RowKeys 属于已知范围,您可以尝试将它们分成大小大致相等的不相交集,供每个工作人员处理。例如,Worker1 处理从“A”到“C”的键,Worker2 处理从“D”到“F”的键,等等。

如果这不可行,那么您的排队解决方案可能会起作用。但同样,如果可能,我建议每个队列消息代表一系列键。例如,单个队列消息指定删除“A”到“C”范围内的所有内容,或类似的内容。

在任何情况下,如果您在同一个 PartitionKey 中有多个实体,那么使用批处理事务对插入和删除都有好处。在最好的情况下,这可以将交易数量减少近十倍。您还应该在每个工作角色中使用并行性。理想情况下,使用异步方法(Begin/End 或 *Async)进行写入,并并行运行多个事务(12 可能是一个不错的数字)。您也可以运行多个线程,但效率较低。在任何一种情况下,单个工作人员都可以使用表存储推送大量事务。

附带说明一下,您的流程应该是“选择 -> 插入新的 -> 删除旧的”。如果在第 2 步和第 3 步之间发生故障,则“选择 -> 删除旧的 -> 插入新的”可能会导致永久数据丢失。

于 2013-06-26T17:31:03.363 回答
2

我认为您应该将您的问题标记为答案;)我想不出更好的解决方案,因为我不知道您的分区和行键是什么样的。但是为了增强您的解决方案,您可以选择将多个分区/行键注入每个队列消息以节省事务成本。此外,当从队列中消费时,以 32 个为一组获取它们。异步处理。我能够在不到一天的时间内将 1.7 亿条记录从 SQL Server (Azure) 传输到表存储。

于 2013-06-26T17:07:16.690 回答