【问题标题】:Entity Framework and Parallelism实体框架和并行
【发布时间】:2012-11-01 17:41:12
【问题描述】:

背景

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

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

为了提高效率,我用组件构建了一个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

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

【问题讨论】:

  • 您确定您不等待池的连接吗?您是否尝试过增大连接池大小?
  • @Maess:对于有问题的运行,我将最大并行度设置为 12。如果我理解正确,连接池的默认最大大小为 100。不过,我会明确尝试设置得更高。
  • @Maess:Perfmon 仅显示到 SQL 实例的 11 个逻辑连接和 11 个用户连接,远远低于连接池限制。
  • 如果我们能得到一个复制品,那就太好了。关于哪个锁可能导致问题,我有一些初步的想法,但如果没有重现,很难确定。 EF 当然没有进行任何有意的限制,但它确实在某些地方使用锁来访问共享元数据,其中之一可能会导致问题。我的电子邮件是您知道在哪里的 avickers。
  • @ArthurVickers:我会看看能不能拼凑出一个简单的复制品。另外,是否有 EF 5 来源?我看到它们是为 EF 6 发布的。使用 EF 5 源,我可以在我的完整解决方案中找到导致问题的代码行。

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


【解决方案1】:

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

  • 该问题可以在 Microsoft 重现。
  • 句柄争用与网络 I/O 相关(即使使用本地主机上的 SQL Server)。具体来说,System.Data.dll 中网络 I/O 的读取缓冲区存在争用。
  • EF 团队现在正与 SQL 连接团队合作,以更好地了解该问题。
  • Microsoft 尚未就如何最大程度地减少这种争用的影响提供指导。

更新

目前正在 CodePlex 上跟踪此问题:

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

【讨论】:

  • 非常感谢埃里克。我对这个很感兴趣,因为我有一个类似的场景。我们是否在 connect.microsoft.com 上遇到了这方面的问题,以便我们可以追踪其进度?
  • @Dodd:由于 EF 现在是开源的(但仍然由 Microsoft 的团队工作),因此它正在 Codeplex 上进行跟踪。添加链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-10
  • 1970-01-01
  • 1970-01-01
  • 2013-02-10
  • 2011-10-11
相关资源
最近更新 更多