如何"热身"实体框架?它何时变得"冷"?

Pet*_*ter 118 asp.net asp.net-mvc entity-framework asp.net-mvc-4 entity-framework-5

不,我的第二个问题的答案不是冬天.

前言:

我最近一直在对Entity Framework进行大量的研究,而且一直困扰着我的是它在查询没有预热时的性能,所谓的冷查询.

我浏览了Entity Framework 5.0 的性能注意事项.作者介绍的概念,温暖寒冷的查询,以及他们如何不同,这我也注意到自己不知道它们的存在.在这里值得一提的是,我背后只有六个月的经验.

现在我知道如果我想在性能方面更好地理解框架,我还可以研究哪些主题.不幸的是,互联网上的大多数信息都是过时的或者是主观性的,因此我无法找到关于Warm vs Cold查询主题的任何其他信息.

基本上我到目前为止注意到的是,每当我必须重新编译或回收点击时,我的初始查询变得非常慢.正如预期的那样,任何后续数据读取都是快速的(主观的).

我们将迁移到Windows Server 2012,IIS8和SQL Server 2012,作为一名少年,我实际上赢得了在其他人之前测试它们的机会.我很高兴他们推出了一个预热模块,可以让我的应用程序为第一个请求做好准备.但是,我不确定如何继续升温我的实体框架.

我所知道的是值得做的:

  • 按照建议提前生成我的观点.
  • 最终将我的模型移动到单独的程序集中.

通过常识,我认为做的可能是错误的做法:

  • 在Application Start中执行虚拟数据读取,以便加热,生成和验证模型.

问题:

  • 什么是在我的实体框架上随时获得高可用性的最佳方法?
  • 在什么情况下实体框架再次"冷"?(重新编译,回收,IIS重启等)

And*_*eas 55

  • 什么是在我的实体框架上随时获得高可用性的最佳方法?

您可以混合使用预生成视图和静态编译查询.

Static CompiledQuerys很好,因为它们编写起来快速简便,有助于提高性能.但是对于EF5,没有必要编译所有查询,因为EF将自动编译查询本身.唯一的问题是,当扫描缓存时,这些查询可能会丢失.因此,您仍然希望保留对自己编译的查询的引用,这些查询仅发生在非常罕见的情况下,但这些查询很昂贵.如果将这些查询放入静态类中,它们将在首次需要时进行编译.对于某些查询,这可能为时已晚,因此您可能希望在应用程序启动期间强制编译这些查询.

正如您所提到的,预生成视图是另一种可能性.特别是,那些需要很长时间才能编译并且不会更改的查询.这样就可以将性能开销从运行时转移到编译时.这也不会引入任何滞后.但当然这种变化会传递到数据库,因此处理起来并不容易.代码更灵活.

不要使用大量的TPT继承(这是EF中的一般性能问题).既不构建你的继承层次结构太深也不太宽.某些类特定的2-3个属性可能不足以要求自己的类型,但可以作为现有类型的可选(可空)属性处理.

不要长时间坚持单一的背景.每个上下文实例都有自己的第一级缓存,随着它越来越大,性能会降低.上下文创建很便宜,但是上下文的缓存实体内的状态管理可能变得昂贵.其他缓存(查询计划和元数据)在上下文之间共享,并将与AppDomain一起死亡.

总而言之,您应确保经常分配上下文并仅在短时间内使用它们,您可以快速启动应用程序,编译很少使用的查询,并为性能关键且经常使用的查询提供预生成的视图.

  • 在什么情况下实体框架再次"冷"?(重新编译,回收,IIS重启等)

基本上,每次丢失AppDomain.IIS每29小时执行一次重新启动,因此您永远无法保证您的实例可以使用.此外,在没有活动的一段时间后,AppDomain也会关闭.你应该尝试再次快速上来.也许你可以异步进行一些初始化(但要注意多线程问题).您可以使用在没有请求阻止AppDomain死亡的情况下在您的应用程序中调用虚拟页面的计划任务,但最终会.

我还假设当您更改配置文件或更改程序集时,将重新启动.


mcs*_*tar 9

如果您希望在所有呼叫中获得最佳性能,请仔细考虑您的体系结构.例如,当应用程序加载而不是在每个请求上使用数据库调用时,预先缓存服务器RAM中经常使用的查找可能是有意义的.该技术将确保常用数据的最小应用响应时间.但是,您必须确保具有良好的过期策略,或者在发生影响缓存数据的更改时始终清除缓存以避免并发问题.

通常,当本地缓存的信息变得陈旧或需要事务性时,您应该努力设计分布式体系结构,以仅需要基于IO的数据请求.任何"线上"数据请求通常需要比内存缓存检索中的本地检索长10-1000倍.与"本地与远程"数据问题相比,仅此一个事实通常使得关于"冷与热数据"的讨论无关紧要.

  • "与"本地与远程"数据问题相比,这一事实本身常常使得"冷与热数据"的讨论变得无关紧要." 并不是的.如果你没有在本地缓存它(你最初不会这样),你仍然需要点击EF并遭受初始化的痛苦才能填满你的缓存.在您的缓存未初始化的相同位置,EF将是未初始化的.因此,如果唯一的问题是EF初始化时间,那么添加一层缓存可能无济于事,但它会增加另一层复杂性...... (2认同)

udo*_*rog 8

一般提示.

  • 执行严格的日志记录,包括访问的内容请求时间.
  • 在初始化应用程序时执行虚拟请求以热启动从上一步骤中获取的非常慢的请求.
  • 除非这是一个真正的问题,否则不要打扰优化,与应用程序的消费者沟通并询问.如果只是为了找出需要优化的东西,那么就可以获得持续的反馈循环.

现在解释为什么虚拟请求不是错误的方法.

  • 更低的复杂性 - 您正在以一种无论框架中的变化如何都可以工作的方式来加热应用程序,并且您不需要找出可能以正确的方式执行它可能的时髦API /框架内部.
  • 更大的覆盖范围 - 您正在预热与慢速请求相关的所有缓存层.

解释缓存何时"冷".

这种情况发生在框架中应用缓存的任何层,性能页面顶部有一个很好的描述.

  • 如果在使缓存失效的潜在更改之后必须验证缓存,则可能是超时或更智能(即缓存项目中的更改).
  • 当一个缓存项被驱逐时,执行此操作的算法在您链接的性能文章中的"缓存逐出算法"一节中进行了描述,但简而言之.
    • LFRU(最少使用 - 最近使用)缓存命中数和年龄,限制为800项.

您提到的其他内容,特别是重新编译和重新启动IIS,清除部分或全部内存缓存.