Azure表存储查询的性能降低

Ken*_*ith 6 c# azure task-parallel-library azure-table-storage

我正在针对Azure表存储运行一系列结构良好的查询,据我所知,这应该是亚秒级返回.实际上,如果我手动运行它们(例如,从Visual Studio中的Azure工具),它们确实会立即返回.但是当我在生产中运行它们时,它们有时会花费20-30秒来返回.

这是我用ATS调用的C#代码:

public async Task<IList<T>> FindAsync(string filter, int maxRecords = int.MaxValue, IList<string> columns = null)
{
    var returnList = new List<T>();
    try
    {
        Interlocked.Increment(ref _outstandingRequests);
        var query = new TableQuery<T>().Where(filter);
        if (columns != null && columns.Any())
        {
            query = query.Select(columns);
        }
        TableQuerySegment<T> querySegment = null;
        var sw = new Stopwatch();
        sw.Start();
        while (returnList.Count < maxRecords && (querySegment == null || querySegment.ContinuationToken != null))
        {
            try
            {
                await 3.RetriesAsync(async x =>
                {
                    querySegment = await
                        Table.ExecuteQuerySegmentedAsync(query,
                            querySegment != null ? querySegment.ContinuationToken : null);
                });
                returnList.AddRange(querySegment);
            }
            catch (Exception ex)
            {
                _logger.Error("Error executing ATS query; table:{0}; filter:{1}; error:{2}",
                    typeof(T).GetFriendlyTypeName(), filter, ex.CompleteMessage());
                throw;
            }
        }
        sw.Stop();
        if (sw.ElapsedMilliseconds > 10000)
        {
            var stat = new RepoOperationStats(filter, sw, returnList.Count, _outstandingRequests);
            _logger.Warn("Long-running {0} query: secs:{1:0.0}, rc:{2}, or:{3}, fi:{4}",
                typeof(T).GetFriendlyTypeName(), stat.Milliseconds / 1000d, stat.ResultCount, stat.OutstandingRequests, stat.Filter);
        }
    }
    finally
    {
        Interlocked.Decrement(ref _outstandingRequests);
    }
    return returnList;
}
Run Code Online (Sandbox Code Playgroud)

这是存储在表中的实体的示例:

在此输入图像描述

一切都相当简单.但在我的日志中,我看到这样的重复错误:

长期运行的AtsOrganizationEventSummaryByCookie查询:secs:33.3,rc:0或:94,fi :( PartitionKey eq'4306.www-detail-mercury-mars-skywatching-tips.html-get')和((RowKey ge'2015.02) .05.00000000-0000-0000-0000-000000000000')和(RowKey le'2015.02.07.00000000-0000-0000-0000-000000000000'))

换句话说,返回零行需要33秒.请注意,它只是命中一个分区,它应该能够对该分区中的行索引进行简单的搜索.(实际上,相同的查询会在其他上下文中立即返回.)

我遇到了某种限制机制吗?我要指出,我正在调用这些并行查询,使在任何给定时间点,任何地方从十几元到100个向上查询可能是优秀的.但似乎(a)我的客户端和(b)ATS应该能够处理该级别的负载.

有关如何解决此问题的任何建议?

TDa*_*Dao 0

你的过滤器是什么?从您拥有的日志来看,您似乎正在执行扫描操作

(RowKey ge '2015.02.05.00000000-0000-0000-0000-000000000000') and (RowKey le '2015.02.07.00000000-0000-0000-0000-000000000000')

尽管已建立索引,但当您使用或 之RowKey类的比较按一系列行键进行筛选时,它会执行扫描,这可能会非常慢,具体取决于表的大小。gele

您可以尝试将整个分区加载4306.www-detail-mercury-mars-skywatching-tips.html-get到内存中并进行过滤,看看是否更快。

顺便说一句,从您的实体数据结构来看,您似乎正在尝试记录事件来访问网页。如果是,您可能需要查看 Application Insights。它更适合遥测记录。