改进 Azure Table 存储更新

Improving Azure Table Storage Upserts

我有一份处理大约 80K 项的工作,必须将它们 insert/update 到 Azure Table 存储中。

我没有得到每个存储 20K/秒的 table storage's specs 和每个 table2k/秒的 table storage's specs

我最快的处理速度约为 ~350/秒。这适用于非常小的项目(194K 项目和更大的项目)。

我正在使用:

.NET 6
Azure Function v4
Azure.Data.Table nuget package (v 12)
v1 storage account
Each item has a unique partition
ServicePointManager.UseNagleAlgorithm = false;
ServicePointManager.Expect100Continue = false;
ServicePointManager.DefaultConnectionLimit = 200; (I've adjusted this to minor differences)

我发现 运行 在本地发布,最快的代码是:

    await Parallel.ForEachAsync(array, async (item, ct) =>
    {
        await storageTable.UpsertEntityAsync(item, TableUpdateMode.Replace, ct);
    });

我试过以下方法:

non-async versions of every
for i and with an await
for i and added the task to a task array then await the task list
foreach with an await
foreach and added the task to a task array
Parallel foreach

var partition = Partitioner.Create(0, list.Count, 50);
Parallel.ForEach(partition, options, item => {});

Upserts vs Inserts (the same)

我没有从任务列表和等待中获得真正的好处,因为图书馆有一个内部等待(相对于返回任务)。 运行 在我的示例中,它产生的时间与添加任务列表和等待它的时间相似。

我是否缺少可以为插入提供更好性能的东西?编写直接 http 调用(并跳过库)会给我更好的[很多]结果吗?

编辑 - 添加尝试的分区类型

批处理事务可以提高每个进程的吞吐量 - 但这些不适用于您的情况,因为您有唯一的分区键。

这意味着,它归结为并行化。它当然有可能变得更高 - 你提到每个 table 2K/秒,但它实际上是每个分区 2K/秒 作为吞吐量限制。

不久前我就这个确切的主题写了一篇非常全面的博客 post - 使用 Azure Functions 消耗计划 scale-out 并并行执行插入(唯一分区)。我设法达到了大约 17K upserts/sec 的峰值吞吐量。里面有完整的代码示例、统计数据、监控说明和一些陷阱:

https://www.adathedev.co.uk/2022/02/bulk-load-azure-table-storage-functions.html

在那项研究中,我像您一样查看了 UseNagleAlgorithm 调整等 - 但最终没有调整任何这些。最大的不同是我最终采用并行批量加载的总体方法。