【问题标题】:Too many Tasks causes SQL db to timeout任务过多导致 SQL db 超时
【发布时间】:2011-03-29 16:58:00
【问题描述】:

我的问题是我显然使用了太多任务(线程?)来调用查询 SQL Server 2008 数据库的方法。代码如下:

for(int i = 0; i < 100000 ; i++)
{  
  Task.Factory.StartNew(() => MethodThatQueriesDataBase()).ContinueWith(t=>OtherMethod(t));  
}

过了一会儿,我得到一个 SQL 超时异常。我希望将实际线程数保持在低于 100000 的缓冲区中,例如“一次不超过 10 个”。我知道我可以使用 ThreadPool 管理我自己的线程,但我希望能够通过 ContinueWith 来使用 TPL 的美妙之处。

我查看了Task.Factory.Scheduler.MaximumConcurrencyLevel,但它没有设置器。

我该怎么做?

提前致谢!

更新 1
我刚刚测试了 LimitedConcurrencyLevelTaskScheduler 类(由 Skeet 指出)并且仍然在做同样的事情(SQL 超时)。
顺便说一句,这个数据库每天接收超过 800000 个事件,并且从未发生过崩溃或超时。这听起来有点奇怪。

【问题讨论】:

  • 在 24 个时间段内的 800,000 个事件是同时少于 100,000 个。即使这只是超过 8 小时,它也只会出现每秒 28 个查询......

标签: c# sql multithreading task task-parallel-library


【解决方案1】:

您可以创建一个具有有限并发度的TaskScheduler as explained here,然后从中创建一个TaskFactory,并使用该工厂而不是Task.Factory 来启动任务。

【讨论】:

  • 我只是在读那篇文章:P。您是否使用过相同的实现(又名。它好吗?)。我现在真的不想通读实现。
  • 呸,又被Skeeted(正要链接到那篇文章)
  • 伙计们,我刚刚测试了 LimitedConcurrencyLevelTask​​Scheduler 类,但仍在做同样的事情(SQL 超时)。顺便说一句,这个数据库每天接收超过 800000 个事件,并且从未崩溃或超时。这听起来有点奇怪。
  • @Michel:您确定正确关闭数据库连接吗?与您正在使用的任务数量相比,您的连接池有多大?
  • @Jon:我的连接池是 20,我将并发级别设置为 10。这让我更加了解了一个有点慢(~0.5 秒)的特定存储过程。让我们看看它现在如何。一会儿我会发布进度。谢谢!
【解决方案2】:

任务与线程不是 1:1 - 任务被分配线程以从线程池中执行,并且线程池通常保持相当小(线程数 == CPU 内核数),除非任务/线程被阻塞等待长时间运行的同步结果 - 例如可能是同步网络调用或文件 I/O。

因此,启动 10,000 个任务不应导致产生 10,000 个实际线程。但是,如果这些任务中的每一个都立即陷入阻塞调用,那么您可能会得到更多线程,但它仍然不应该是 10,000。

这里可能发生的情况是您一次用太多请求压倒了 SQL 数据库。即使系统只为你的数千个任务设置了少数线程,如果调用的目的地是单线程,少数线程仍然会导致堆积。如果每个任务都调用 SQL db,而 SQL db 接口或 db 本身通过单线程锁协调多线程请求,那么所有并发调用都会堆积起来等待线程锁进入 SQL db 执行.无法保证接下来会释放哪些线程来调用 SQL 数据库,因此您很容易以一个“不幸”的线程结束,该线程开始等待早期访问 SQL 数据库但没有进入 SQL 数据库调用在阻塞等待超时之前。

SQL 后端也可能是多线程的,但由于许可级别限制了并发操作的数量。也就是说,一个 SQL 演示引擎只允许 2 个并发请求,但完全许可的引擎支持数十个并发请求。

无论哪种方式,您都需要采取措施将并发性降低到更合理的水平。 Jon Skeet 关于使用 TaskScheduler 来限制并发性的建议听起来是个不错的起点。

【讨论】:

    【解决方案3】:

    我怀疑您处理数据库连接的方式有问题。 Web 服务器可以在 SQL 活动的各个阶段运行数千个并发页面请求。我敢打赌,减少并发任务数的尝试确实掩盖了另一个问题。

    您能否分析 SQL 连接?查看 perfmon 以查看有多少活动连接。看看你能不能尽快抓住-使用-释放连接。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-22
      • 1970-01-01
      • 1970-01-01
      • 2011-04-23
      • 1970-01-01
      相关资源
      最近更新 更多