所以这就是问题所在。我需要在azure表中更新大约4000万个实体。使用单个实例执行此操作(选择 - >删除原始 - >使用新分区键插入)将持续到圣诞节。
我的想法是使用一个有很多实例运行的azure worker角色。这里的问题是查询抓取前1000条记录。这对一个实例来说很好,但是20个运行他们的选择显然会重叠..很多。这将导致大量浪费的计算尝试删除已被另一个实例删除的记录并更新已更新的记录。
我已经完成了一些想法,但我最好的选择是让角色用分区和行键填充队列然后让工作人员出队并进行实际处理?
有更好的想法吗?
答案 0 :(得分:5)
非常有趣的问题!!!扩展@Brian Reischl的答案(其中很多都在大声思考,所以请耐心等待我:))
<强>假设:强>
可能的解决方案:
首先,您将创建20个blob容器。我们将它们命名为container-00,container-01,... container-19。
然后你开始阅读实体 - 一次1000个。由于您从表存储中获取XML格式的原始数据,因此您可以创建XML文件并将这1000个实体存储在container-00中。您获取下一组实体并将其以XML格式保存在container-01中,依此类推,直到您点击容器-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文件,然后转到该容器中的下一个文件。读取并处理完所有文件后,您只需删除容器即可。
正如我之前所说,这是一种“大声思考”的解决方案,有些事情必须考虑当“读者”工作者角色垮台和其他事情时发生的事情。
答案 1 :(得分:3)
如果您的PartitionKeys和/或RowKeys属于已知范围,您可以尝试将它们分成大小相等的不相交集,以供每个工作人员处理。例如,Worker1处理以'A'到'C'开头的键,Worker2处理以'D'到'F'开头的键等。
如果这不可行,那么您的排队解决方案可能会有效。但同样,我建议每个队列消息代表一系列密钥,如果可能的话。例如,单个队列消息指定删除“A”到“C”范围内的所有内容,或类似的内容。
在任何情况下,如果同一PartitionKey中有多个实体,则使用批处理事务对插入和删除都有利。在最好的情况下,这可以减少几乎十倍的交易数量。您还应该在每个辅助角色中使用并行性。理想情况下,使用异步方法(Begin / End或* Async)进行写入,并行并行运行多个事务(12可能是一个很好的数字)。您也可以运行多个线程,但效率稍低。在任何一种情况下,单个工作人员都可以使用表存储来推送批次的事务。
作为旁注,您的流程应该是“选择 - &gt;插入新内容 - &gt;删除旧内容”。如果在步骤2和步骤2之间发生故障,则“选择 - &gt;删除旧 - &gt;插入新”可能导致永久性数据丢失。 3。
答案 2 :(得分:2)
我认为你应该将你的问题标记为答案;)我不能想到一个更好的解决方案,因为我不知道你的分区和行键是什么样的。但是为了增强您的解决方案,您可以选择将多个分区/行键分配到每个队列消息中,以节省交易成本。此外,当从队列中消耗时,以32个批次获取它们。异步处理。我能够在不到一天的时间内将1.7亿条记录从SQL服务器(Azure)传输到表存储。