我的作业需要处理大约 80K 项,并且必须将它们插入/更新到 Azure 表存储中。
我没有收到 table storage's specs每个存储 20K/秒,每个表 2k/秒。
我处理这个问题的最快速度约为约 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)
我发现在release中本地运行,最快的代码是:
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 调用(并跳过库)会给我带来更好的[很多]结果吗?
编辑 - 添加尝试的分区类型
最佳答案
批量事务可以提高每个进程的吞吐量 - 但这些不适用于您的情况,因为您有唯一的分区键。
这意味着,它归结为并行化。当然可能会更高 - 您提到每个表 2K/秒,但实际上吞吐量限制是每个分区 2K/秒。
不久前,我就这个主题写了一篇相当全面的博客文章 - 使用 Azure Function 消耗计划横向扩展并并行执行插入(唯一分区)。我设法达到了每秒 17K 次更新插入的峰值吞吐量。这里有完整的代码示例、统计信息、监控注释和一些陷阱:
https://www.adathedev.co.uk/2022/02/bulk-load-azure-table-storage-functions.html
在研究过程中,我像您一样查看了 UseNagleAlgorithm 调整等 - 但最终没有调整其中任何一个。最大的不同是我最终采用的并行批量加载的总体方法。
关于c# - 改进 Azure 表存储更新插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72249990/