执行许多查询后执行查询超时

Executing queries being timing out after having performed many queries

我在 table 上异步执行查询,一段时间内一切正常,但突然间查询开始超时。

简而言之,我有一个包含许多 ID 的文本文件,对于这些 ID 中的每一个,我想在 table 中执行一个查询。查询本身不应花费很长时间,少于 5 秒,但是在成功执行许多查询后,应用程序突然开始每次都超时。如果我然后重新启动我的应用程序并重新 运行 超时的 ID,它们现在 运行 完全没有问题。

假设我有一个1000个ID的列表,然后它在处理并成功执行200个ID后开始超时。

我已经尝试插入一个 MaximumExecutionTime 并将其设置为比标准的 5 秒高得多,但它仍然超时。我试过不共享 CloudTableClients,只是让每个 "thread" 创建一个新实例。

该代码是一个更大项目的一部分,因此我将在此处包含相关部分并省略一些其他代码。我首先创建一个 CloudTableClient,它在不同的任务之间共享,就好像我理解正确一样,可以共享它。然后我有一个 ActionBlock,我 post ID 到。我已将 MaxDegreeOfParallelism 限制为我拥有的处理器数量,我对此有最好的体验。

CloudStorageAccount cloudStorage = CloudStorageAccount.Parse(_ParsedConnectionString);
CloudTableClient tableClient = cloudStorage.CreateCloudTableClient();

var block = new ActionBlock<int>(
  async id =>
  {
    // Do stuff
    var res = await executeQuery(id, tableClient);
    // Do more stuff
  },
  new ExecutionDataflowBlockOptions
  {
    MaxDegreeOfParallelism = Environment.ProcessorCount
  }
);

StreamReader file = new StreamReader(someFile);
string line;
while ((line = file.ReadLine()) != null)
{
  block.Post(Convert.ToInt32(line));
}
block.Complete();
block.Completion.Wait();

并且在executeQuery函数中:

CloudTable table = tableClient.GetTableReference(_someTable);

var tableQuery = new TableQuery<SomeEntity>
{
  FilterString = "some query"
};

TableContinuationToken continuationToken = null;
TableRequestOptions options = new TableRequestOptions
{
  MaximumExecutionTime = new TimeSpan(0, 2, 0)
};
OperationContext context = new OperationContext();

do
{
  var tableQueryResult = await table.ExecuteQuerySegmentedAsync(tableQuery, continuationToken, options, context);
  continuationToken = tableQueryResult.ContinuationToken;
  // Do stuff
}
while (continuationToken != null);

查询很好,就好像我重新运行 应用程序的 ID 之前超时一样,它 运行 符合预期。

The client could not finish the operation within specified timeout.
at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.EndExecuteAsync[T](IAsyncResult result) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Core\Executor\Executor.cs:line 51
   at Microsoft.WindowsAzure.Storage.Core.Util.AsyncExtensions.<>c__DisplayClass2`1.<CreateCallback>b__0(IAsyncResult ar) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Core\Util\AsyncExtensions.cs:line 69
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at App.Parser.<executeQuery>d__25.MoveNext()`

根据您获得的异常,您的查询是针对 AzureStorage 的 运行。某些存储操作受 number/minute.

中的配额限制

基本上read/write几乎是无限的,但管理是。

例如,如果在您的每个请求中,您首先尝试获取存储密钥,那么您可能会达到限制,然后 azure 会限制您(这可能会导致超时,因为限制是每分钟一次)。

CloudStorageAccount

None、CloudTableClientCloudTable 都是线程安全的。

仍然记录 CloudTableClient 的少数参考资料,例如 CloudTableClient.ListTables Method () 都有以下免责声明:

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

您的 cloudStoragetableClient 实例可能被线程破坏了,这就是重新启动进程修复它的原因。