更新了azure表中的4,000多万个实体,其中有许多实例如何处理并发问题

Pau*_*ade 5 azure azure-table-storage

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

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

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

有更好的想法吗?

Gau*_*tri 5

非常有趣的问题!!! 扩展@Brian Reischl的答案(其中很多都在大声思考,所以请耐心等待:))

假设:

  • 您的实体可以以某种形式或形式进行序列化.我假设您将获得XML格式的原始数据.
  • 您有一个单独的辅助角色,它正在执行所有实体读取.
  • 您知道编写修改后的实体需要多少个工作者角色.为了论证,让我们假设你提到它是20.

可能解决方案

首先,您将创建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将从container-00读取文件, WorkerRole_IN_1将读取container-01中的文件,依此类推.

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

正如我之前所说,这是一个很大的"大声思考"的解决方案,有些事情必须考虑当"读者"工作者角色垮台和其他事情时发生的事情.


Bri*_*chl 3

如果您的 PartitionKey 和/或 RowKey 落入已知范围,您可以尝试将它们划分为大小大致相等的不相交集合,供每个工作人员处理。例如,Worker1 处理以“A”到“C”开头的键,Worker2 处理以“D”到“F”开头的键,等等。

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

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

作为旁注,您的流程应该是“选择 -> 插入新项 -> 删除旧项”。如果步骤 2 和 3 之间发生故障,“选择 -> 删除旧的 -> 插入新的”可能会导致永久数据丢失。