我希望得到社区对此的看法。如果我有一个严重受DB / IO限制的进程,使用任务并行库并行化各个进程路径有多聪明?
我将使用一个例子......如果我有一堆项目,我需要做以下操作
从逻辑上讲,我可以在步骤#3,#5,#6中并行化为任务图,因为一个项目与前一个项目的结果无关。但是,这些都将在数据库(sql server)上等待,这很好,我知道我们只能处理SQL服务器让我们。
但我想在本地计算机上逻辑分发任务,以便它能够像数据库一样快地处理我们,而不必等待我们的任何事情。我已经完成了一些模拟原型,我用Thread.Sleeps替换了db调用(我还尝试了一些与.SpinWait相比的变化,速度快了一百万倍),而并行版本比当前实现更快,完全是串行的而且根本不平行。
我害怕的是在SQL服务器上施加了太大的压力......在我走得太远之前,我应该考虑哪些因素?
答案 0 :(得分:2)
如果并行版本比串行版本快得多,我不会担心SQL服务器上的压力......除非你正在执行的任务与其他一些重要或时间关键的操作相比具有低优先级也在DB服务器上执行。
我对你的任务描述并不是很了解,但几乎听起来这些任务应该直接在数据库中执行(我认为有些细节不可能实现?)
答案 1 :(得分:1)
另一种选择是创建一个管道,以便第二组的第3步与第一组的第4步同时发生。如果您可以在步骤5重叠更新,也可以这样做。这样你就可以进行并发SQL访问和处理,但不会对数据库造成过高的负担,因为你只有两个并发操作同时进行。
因此,您按顺序执行步骤1和2(我推测)以获取需要进一步处理的组的集合。然后。你的主线程开始了:
for each group
query the database
place the results of the query into the calc queue
第二个线程为结果队列提供服务:
while not end of data
Dequeue result from calc queue
Do numeric calculations
place the results of the query into the update queue
第三个线程为更新队列提供服务:
while not end of data
Dequeue result from update queue
Update database
System.Collections.Concurrent.BlockingCollection<T>
是一种非常有效的队列。
这里的好处是,如果你想通过添加多个计算线程或查询/更新线程来扩展它,如果SQL Server可以处理更多的并发事务。
我在日常的合并/更新程序中使用了与此类似的东西,效果非常好。该特定进程不使用SQL服务器,而是使用标准文件I / O,但概念转换得非常好。