【问题标题】:Scaling an Entity Framework Application / Multiple Apps hitting the same database?扩展实体框架应用程序/多个应用程序访问同一个数据库?
【发布时间】:2013-06-27 17:33:38
【问题描述】:

我有一个使用 MVC/EF Code First 编程的应用程序。它进行了大量的服务器端处理,并且非常耗费资源。

我知道如何设置负载平衡,但是我想知道扩展 EF 应用程序是否像配置新服务器、部署应用程序和指向数据库集群一样简单 - 或者我会遇到什么问题关于多个 EF 应用程序访问同一个数据库服务器?

我似乎找不到任何建议/指南,我担心我选择了 EF 而不是更简单/更直接的东西,我做出了错误的选择!

【问题讨论】:

  • 对于性能:这取决于瓶颈在哪里。如果您有一个运行起来特别昂贵的查询并且需要运行多次,那么将这些执行分散到多个数据库实例中可能是可行的方法。但是,如果您有很多轻量级查询并且大部分时间都花在您的应用程序中,那么数据库集群将无济于事。如果您还没有这样做,请尝试分析您的应用程序并查看您的代码、外部代码和外部资源(数据库、Web 服务调用)花费的时间百分比。
  • 但在更基本的层面上,处理 MVC 应用程序的多个实例的复杂性之一是状态管理。例如。如果您在内存中保留有关下一页请求的一些信息,但用户在另一台服务器上得到负载平衡......该服务器如何知道第一台服务器在内存中获得了什么?
  • @te.speot.is - 问题几乎与 I/O 相关......该应用程序只不过是一个 API......我有发送包含大量请求的大型请求的客户端数据和我的应用程序必须在存储到后端数据库之前进行处理/排序/过滤...我需要支持更多的客户端并且只想了解 EF 缩放/我担心当两个前端都需要时会发生什么写入同一张表。
  • 最重要的是,理想情况下,我想构建一些“额外”的支持应用程序来连接到同一个数据库......而且,我只是不确定 EF 将如何处理多个应用程序到同一个DB....想知道我是否应该去 Linq,至少我知道事情会如何运作:/

标签: asp.net-mvc entity-framework n-tier-architecture


【解决方案1】:

...问题...关于访问同一数据库服务器的多个 EF 应用程序?

稍微回顾一下,您的应用程序是一个基于 ASP .NET MVC 的应用程序。拥有多个它的实例可能会引发状态管理的幽灵。

MSDN 对why this is an issue 有很好的介绍:

HTTP 是一种无状态协议。这意味着 Web 服务器将页面的每个 HTTP 请求视为一个独立的请求。服务器不保留先前请求期间使用的变量值的知识。 ASP.NET 会话状态将在有限时间窗口内来自同一浏览器的请求标识为会话,并提供一种在该会话期间保持变量值的方法。默认情况下,为所有 ASP.NET 应用程序启用 ASP.NET 会话状态。

会话状态的替代方案包括:

  • 应用程序状态,用于存储可供 ASP.NET 应用程序的所有用户访问的变量。

这一点是一种极其常见的状态存储方式,但在涉及应用程序的多个实例时会失效(状态仅对其中一个实例“可见”)。

通常可以使用SessionStateModeStateServerSQLServer 值来解决此问题。同一篇文章很好地总结了每个选项(强调我的)。

  • StateServer 模式,它将会话状态存储在称为 ASP.NET 状态服务的单独进程中。这可确保在重新启动 Web 应用程序时保留会话状态并且还可以使 Web 场中的多个 Web 服务器可以使用会话状态

  • SQLServer 模式将会话状态存储在 SQL Server 数据库中。这可确保在重新启动 Web 应用程序时保留会话状态并且还可以使 Web 场中的多个 Web 服务器可以使用会话状态

如果您的应用程序是无状态的,这是一个有争议的问题。

我担心我选择了 EF 做出了错误的选择

就应用程序的多个实例访问数据库的问题而言,任何类型的数据访问技术都会出现问题。

这是基本场景:假设您的应用程序按计划向用户发送欢迎电子邮件。

给定表Users

UserId | Email           | WelcomeLetterSent
-------+-----------------+------------------
     1 | user@domain.com | 0

还有一些伪代码:

foreach (var user in _context.Users.Where(u => !u.WelcomeLetterSent))
{
    SendEmailForUser(user);
    user.WelcomeLetterSent = true;
}

_context.SaveChanges();

有一个race condition,您的应用程序的实例一和实例二可能会同时评估_context.Users.Where(...),然后它们中的任何一个都有机会设置WelcomeLetterSent = true 并调用SaveChanges。在这种情况下,可能会向每个用户发送两封欢迎电子邮件,而不是一封。

并发可能是一件阴险的事情。在here 上,有一篇关于使用实体框架管理并发的入门书,但这只是冰山一角。

您的问题的答案?这取决于您的应用程序做什么:)

最重要的是,理想情况下,我希望构建一些“额外”的支持应用程序来连接到同一个数据库......而且,我只是不确定 EF 将如何处理同一个数据库的多个应用程序......

如果您的应用程序可以容忍其自身访问一个数据库的多个实例,那么让这些“支持应用程序”运行良好通常不是一件容易的事。并发是来自一个应用程序的多个实例还是来自多个应用程序,每个应用程序都有一个实例,并没有太大区别。

【讨论】:

  • 您没有提到 EF 迁移。如何在不关闭所有服务器的情况下执行迁移?
  • @Kugel 把他们都拿下来。 OP 不要求 100% 可用性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-29
  • 1970-01-01
  • 2016-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多