实体框架与并行

时间:2012-11-01 17:41:13

标签: entity-framework parallel-processing profiling task-parallel-library tpl-dataflow

背景

我有一个应用程序接收定期数据转储(XML文件),并使用Entity Framework 5(代码优先)将它们导入现有数据库。导入通过EF5而不是BULK INSERT或BCP进行,因为必须应用已存在于实体中的业务规则。

处理似乎是应用程序本身的CPU绑定(极速,启用了写缓存的磁盘IO子系统在整个过程中显示几乎为零的磁盘等待时间,而SQL Server显示的CPU时间不超过8%-10%)

为了提高效率,我构建了一个pipeline using TPL Dataflow,其组件包含:

Read & Parse XML file
        |
        V
Create entities from XML Node
        |
        V
Batch entities (BatchBlock, currently n=200)
        |
        V
Create new DbContext / insert batched entities / ctx.SaveChanges()

通过这样做,我看到性能大幅提升,但无法使CPU高于60%。

分析

怀疑某种资源争用,我使用VS2012 Profiler的资源争用数据(并发)模式运行该过程。

对于标记为 Handle 2 的资源,分析器显示52%的争用。深入研究,我发现创建 Handle 2 争用最多的方法是

System.Data.Entity.Internal.InternalContext.SaveChanges()

第二名,与SaveChanges()的争论大约为40%

System.Data.Entity.DbSet`1.Add(!0)

问题

  • 我如何弄清楚 Handle 2 究竟是什么(例如TPL的一部分,EF的一部分)?
  • EF限制调用将DbContext实例与单独的线程分开吗?似乎他们正在竞争共享资源。
  • 在这种情况下,我有什么办法可以改善并行性吗?

更新

对于有问题的运行,调用SaveChanges的任务的最大并行度设置为12(我尝试了各种值,包括先前运行中的Unbounded)。

更新2

微软的EF团队提供了反馈。请参阅我的答案以获取摘要。

1 个答案:

答案 0 :(得分:5)

以下总结了我在此问题上与Entity Framework团队的互动。如果有更多信息,我会更新答案

  • 该问题可以在Microsoft重现。
  • 句柄争用与网络I / O有关(即使是localhost上的SQL Server)。具体来说,System.Data.dll中的网络I / O的读取缓冲区存在争议。
  • EF团队现在正在与SQL Connectivity团队合作,以更好地了解该问题。
  • 目前还没有关于如何最大限度地减少此争用影响的指导。

<强>更新

现在正在CodePlex上跟踪此问题:

http://entityframework.codeplex.com/workitem/636?PendingVoteId=636