将异步等待与 Azure 存储一起使用时的性能瓶颈 API

Performance bottlenecks when using async-await with Azure Storage API

我在使用 Azure Table 存储 API 插入请求时遇到了性能瓶颈。我正在尝试达到每 30 毫秒至少 1 次插入 table(唯一分区键)的速度。

达到此请求率的推荐方法是什么?我如何修复我的程序以克服我的瓶颈?

我有一个测试程序,它以大约 1 / 30 毫秒的速度插入 azure table。使用此测试程序,延迟不断增加,每次插入请求开始花费超过 15 秒。

下面是我的测试程序的代码。它创建异步任务,记录在 CloudTable ExecuteAsync 方法上 await 所花费的时间。不幸的是,插入延迟随着程序的运行而增长。

List<Task> tasks = new List<Task>();
while (true)
{
    Thread.Sleep(30);
    tasks = tasks.Where(t => t.IsCompleted == false).ToList(); // Remove completed tasks
    DynamicTableEntity dte = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = "abcd" };
    tasks.Add(AddEntityToTableAsync(dte));
}

...

public static async Task<int> AddEntityToTableAsync<T>(T entity) where T : class, ITableEntity
{
    Stopwatch timer = Stopwatch.StartNew();
    var tableResult = await this.cloudTable.ExecuteAsync(TableOperation.InsertOrReplace(entity));
    timer.Stop();
    Console.WriteLine($"Table Insert Time: {timer.ElapsedMilliseconds}, Inserted {entity.PartitionKey}");

    return tableResult.HttpStatusCode;
}

我认为这可能是我的测试程序 运行 用于传出网络 IO 的线程不足,因此我尝试在程序执行期间监视可用线程数:

ThreadPool.GetAvailableThreads(out workerThreads, out completionIoPortThreads);

它表明几乎所有的 IO 线程在执行期间都可用(以防万一,我什至尝试增加可用线程但对问题没有影响)。

据我了解,对于异步任务,完成端口线程在有数据要处理之前不会得到 "reserved",所以我开始认为我与 Azure 的连接可能存在问题Table 存储。

但是,我通过降低请求率(1 次插入/100 毫秒)并在同一台机器上启动 30 个测试程序实例来确认情况并非如此。对于 30 个实例,我能够保持 stable ~90ms / insert 而不会增加延迟。

我怎样才能使单个测试程序达到我在同一台机器上 运行 30 个程序时获得的类似性能?

测试程序达到了 System.Net.ServicePointManager.DefaultConnectionLimit。默认值为 2

将数字增加到 100 可以解决问题。并让单个程序达到30个程序场景一样的速度