Web 基础结构

为 ASP.NET 应用程序提供可伸缩性

Iqbal Khan

 

概览:

  • 在 ASP.NET 应用程序中的可伸缩性瓶颈
  • 会话状态存储选项
  • 可用的缓存拓扑
  • 所需的分布式的缓存功能

内容

在该问题是否
这些问题存在的原因
什么是答案?
缓存的拓扑
不同的选项
成为现实的世界

ASP.NET,Microsoft,Web 应用程序框架的普及继续增长的 leaps 和 bounds 内企业,开发人员和 IT 等级。 存在但是是的难度的一个区域: 现成的缩放 ASP.NET 应用程序,只是不能。

可伸缩性在此上下文中有两种含义。 首先,您需要能够有效地处理高峰用户负载,因为每个应用程序经历峰值和随时登录时用户数的方面的峰谷数。 当您设计了基础结构时,想设计应用程序,以便它可以处理为高效地和为快速为 nonpeak 负载的高峰负载。

第二个,您必须以增加系统的总容量。 现在您可能只有 5,000 个用户。 六个月下在旅途中,, 一年您可能必须 10,000 个 15,000 或 20,000,和在几年中可以得到了 100,000 个用户中。 能够不 grinding 停止应用程序随着用户数量是何种可伸缩性是所有。 这意味着可以添加更多的用户,而不以任何明显的方式中产生不良影响性能,或者如果有任何下降也应是可接受的范围内。

典型的 ASP.NET 应用程序部署链接在一起带有负载平衡器分配到所有 Web 服务器通讯的网络场中的一个或多个 Web 服务器上。 从理论上讲更多的 Web 服务器您将添加更多的请求应当可以以每秒处理。 网络场的体系结构旨在为 ASP.NET 的可伸缩性。 这在理论上 ; 但实际上是有些不同。

ASP.NET 应用程序的问题是而 Web 技术提供了一个明确的体系结构的 Web场和负载平衡器,数据存储技术不具有保存设置。 当然您可以扩展 Web 应用程序中通过添加更多的服务器或增加的更多的内存和 CPU 能力的各个服务器的强度。

但那样的数据存储不能够在相同的比例缩放。 它不会扩展,但不是为得与 Web 应用程序层。 因此,在 ASP.NET 应用程序与数据存储或数据访问中的任何内容是潜在的可伸缩性瓶颈。 多点,一个数据库服务器会不扩展的会话或应用程序的数据。

在该问题是否

让我们一下不同的访问或存储操作开始会话存储的 ASP.NET 应用程序中发生的。 为每个用户请求会话是从开头存储中读取并且写回到响应的结尾处存储。 用户请求开头页必须能执行,而且,如果会话数据的需要。 称为"会话对象,"将整个会话数据加载,以便它所执行时页可以引用该数据。 页将读取某些数据从会话对象。 它会将一些更多的数据放到会话对象。 此所有发生在 ASP.NET 进程和进行行程没有会话存储。

完成页执行,一些导致发送回该用户的需要。 该会话可能是在此期间更新,以便会话现在将具有保存回到存储。 它将保留存储直到下一个用户请求同一会话的并在同一进程将重复自身。

从用户的角度您单击一个链接 ; 用户可以看到结果的链接的页面时,会话已被读取和会话已被写入回到存储一次。 因此有两个行程到 ASP.NET 应用程序已在会话存储。

现在,您执行在数学。 如果您已通过所有访问页在同一时间获得 10,000 个用户,则必须也许 1,000 个 Requests per second。 每个用户将被单击的内容每隔几秒必须至少 1,000 个和可能有多个请求将网络场那么每秒。

假设 1,000 个或多个请求将网络场和将 Web 服务器导致会话存储的两个过程的每个请求。 从 Web 角度看,这意味着 2,000 个行程到会话存储。 您可以看到负载可以提高速度。 这是一个可伸缩性瓶颈可能发生的一个位置。

页面执行和需要读取或写入一些应用程序数据时,也可以发生可伸缩性瓶颈。 让我们使用航空公司 Flight 可用性作为示例。 用户单击搜索航班从一个位置到另一个,这导致多个页面上的读取该应用数据库的行程。 然后,当然,用户想要使需要一些数据放入数据库 Flight 保留。 此数据被称为"应用程序数据",它存储在数据库中 ; 这保存操作可能会使多个数据库来存储多个数据元素的行程。

因此,您未能,最后,wind 设置的数目数据库旅行 5、 10、 15,或 20 倍多比实际用户请求数。 因此在数据库上的压力是的得是多,这可以是一个主要的瓶颈。

如果您正在使用 SOA (面向服务的结构) 的环境,并且您的应用程序正在调用您的数据中心或其他数据中心可以是另一个服务层,第三个可伸缩性瓶颈是有关。

Server 分层体系结构通常涉及到服务器场,因此可伸缩的 Web 应用程序体系结构一样。 但服务层具有相同的可伸缩性瓶颈,为应用程序,因为它依赖于自己的数据库。

您的应用程序这样将依赖项对其他服务依赖项对其数据库又具有可伸缩性的瓶颈的并且链只一样其最弱的链接。 如果服务不会因其数据库缩放的应用程序不能扩展 (请参见 图 1 )。

fig01.gif

图 1 </a0>-数据库成为一个瓶颈随着网络场增长

确实无关紧要数据库是大型机还是一个关系数据库。 数据访问的数据存储只是不是能够缩放,它不能保持速度 Web 技术的可伸缩性。 并在数据存储中的这些瓶颈防止 ASP.NET 应用程序扩展。

这些问题存在的原因

为什么数据存储不能扩展? 让我们首先解决 Microsoft 提供了三个的会话状态存储选项: InProc,StateServer,和 SqlServer。 InProc 有限制。 它专用于在单服务器、 单一进程环境,而它不能在多服务器或 multi-process ASP.NET 环境。 不保留在会话。

下面是会发生情况。 用户在一台服务器上, 开始,并有创建该会话。 如果负载平衡器然后将该用户发送到另一台服务器中,该应用程序不会发现该会话中,它将认为该用户是启动新,并要求用户重新登录。 每次用户单击任何,她需要登录,因此用户将无法继续。 应用程序不起作用。

一种方法可以解决这是使用"粘滞会话"功能,可以始终用户请求返回到在同一台服务器,以便应用程序将在服务器上找到该会话的路由。

此外可以通过不在服务器上创建 Web 园处理 InProc 限制。 网络园时应用程序具有同一个服务器上运行多个 ASP.NET 工作进程。 如果您避免使用 Web 园的只是一个进程,至少允许在网络场中使用的 InProc。

这些两种替代方法但是并远理想。 粘滞会话可导致一个主要的可伸缩性瓶颈,因为某些服务器负载增加多个其他因为用户会话的长度不统一。 某些用户登录只一分钟,其他 20 分钟。 某些服务器会大量会话,但那些将几乎为空或免费或空闲状态。 即使如果添加多个框,您不一定提高吞吐量。

此外,InProc 有内存限制。 所需 ASP.NET 过程中的每个会话内存所需内存的。 当您增加的会话数,辅助进程的内存要求显著增长。 在一个 32 位平台但是,没有一个工作进程在 1 GB 内存限制,这是个问题。 您不能增大超出了内容适合一个 1 GB 辅助进程内存随其他数据和应用程序代码中的会话数据。 因此 InProc 导致瓶颈。 多个用户,越您会遇到这些问题。

StateServer 将会话状态存储在独立于将 ASP.NET 辅助进程的进程中,但它太有限制。 您可以配置它,以便每个 Web 服务器都包含自己 StateServer 或可以使用专门的一个单独的框和维护该框完全的状态。

使用第一个选项问题是您仍然必须使用粘滞的会话。 只要创建会话的您始终必须返回到它。 此第一个选项只缓解了 InProc Web 园限制。 它不会解决粘滞会话问题,可以使不习惯即使其他人会堵塞的额外框。 用户在实际效果是其会话和响应时间变得非常慢。

此配置选项,其他缺点是,如果任何 Web 服务器断开,在 StateServer Web 服务器框也出现故障,使您丢失所有那些会话。 true,在不丢失一个网站中的所有会话,但确实已都丢失存储在该框上的任何会话,这并不是可接受。 理想情况下,希望丢失任何会话。

如果您选择其他配置 StateServer 提供) 专用的 StateServer 框,不再需要使用粘滞会话,由于每个 Web 服务器将转到同一个专用框。 但现在您有一个更大的问题: 如果该框是否出现故障,整个 Web 服务器场已关闭因为每个 Web 服务器尝试获得该框的会话。

这并不全部。 专用的 StateServer 该框获取 overwhelmed 添加更多的 Web 服务器以及每秒的事务提升。 因此,快速就可伸缩性瓶颈。 这样可伸缩性问题不解决与 StateServer,不使用配置。

现在我们有 SQL Server 数据库中存储会话状态的 SqlServer,并可被视为专用的 StateServer。 这是 Microsoft 的首要数据库服务器用于高事务环境。 则更具可伸缩性比一个 StateServer 是您可以创建的数据库服务器群集。

SqlServer 配置中, 所有 Web 服务器实际上都连接到所有会话的都存储位置在专用 SqlServer 框。 就像每个 Web 服务器连接到专用的 StateServer 框。 隐藏此概念是 SqlServer 将更具可伸缩性比一个 StateServer。 但 SqlServer 不状态服务器一样快,因为一个 StateServer 是一个内存中数据存储,而且相应,有可接受的性能。 而在另一方面,SqlServer 不对内存中数据存储。 是一个基于磁盘的数据存储区。 因为它们增长太大,所有数据库将都保留在磁盘上的内存不足以容纳整个数据库。 因此,数据库将是磁盘的永久存储上存储其数据。 由于磁盘存储 SqlServer 性能不为快速,导致性能拉。

SqlServer 可以有多个配置。 是最常见,独立配置中没有与所有 Web 服务器的只有一个数据库服务器,并且增加网络场的大小,并添加更多的 Web 服务器,放在数据库上的多负载 (参见 图 2 )。

fig02.gif

图 2 ASP.NET 会话仍一个瓶颈和数据库还不 fullyscalable

以及您进行性能问题,因为 SqlServer 不基于内存,并且必须可伸缩性问题因为它不能够尽可能扩展。 可以向上扩展通过使硬件通过向该框中添加 CPU 更强大,但您不能保留添加更多数据库服务器框为增加网络场。 您可以可能继续介于 1 到两个或两到三服务器以便 SqlServer 提供数据库群集这不会扩展到能超过一个的 StateServer 的功能,但它也有其本身的局限性。

其他问题 SqlServer 存储区是所有会话将保存在一个表。 向上扩展,锁定争用,并发访问和会话数据的并发更新立即成为明显。 当有多每秒的交易记录,您将进行多锁延迟,因为所有内容保留在一个表中。

因此,SqlServer 调整多个状态服务器时, 它将性能问题并不足够缩放。 此外,它不会不调整线性。 您应该能够增加网络场从 5-50 到 100 的服务器场,并本身 Web场应该非常顺利地增长 ; 但是,数据访问不相应增大。 如我前面数据库以便将会话存储在数据库中不进行任何重大改进是不增加的这些数据存储访问之一。 通过在状态服务器环境的一个增量改进。 此外,一个 SqlServer 成为应用程序数据以及,会话数据的一个瓶颈。 因此,一个数据库服务器不会扩展的会话或应用程序的数据。

什么是答案?

解决方案是一内存中的存储机制,因此可以非常快速、 一个 StateServer 一样快。 但是,应该几乎线性可伸缩性。 线性可伸缩性意味着当您添加更多的服务器,您几乎将产能。 是例如如果您未能处理秒一个框的 10,000 个交易记录,添加第二个框应使您接近每第二个总的 20,000 位交易记录。 请注意"几乎线性"并不意味着完全 20,000) 可能是 19,000 ; 它就不会但是,是 12,000 或 15,000。 这是我们需要: 几乎线性,增长的存储和它也应在内存中。

因以下的两个需要我们不谈论其他要求,并且用于长期持久存储。 虽然内存中存储始终暂时和临时数据库用于长期存储。 但我们需要是临时。 我们只需在此临时存储在用户会话或可能是中的数据存储的应用程序几天,或在大多数也许是几周几个小时的持续时间。 然后该数据可以消失因为始终是永久的主存储,是,我们可以重新加载从数据的数据库。

这样的这记住所有,我们可以将一种称为"分布式的缓存,"已成为流行,因为它提供好处上面,提到的概念的存储机制为 图 3 显示。

fig03.gif

图 3 relieving 在数据库服务器上的压力的分布式缓存

分布式的缓存处于的内存,以便它是快速,并为了相当线性,分发增长尤其是如果您有 (也称为缓存的拓扑) 在右侧的分发机制。

分布式的缓存必须提供高性能和线性的可伸缩性,并且因为它存在内存中,它必须提供复制,因此,如果任何计算机出现故障 (该计算机中的内存可用),另一台计算机具有数据并不会丢失任何。 复制提供在不同的位置相同数据的多个副本不同框和通过这样做,您获得您的数据存储的持续时间的时间的 100%。

分布式的缓存存储.NET 对象或 Java 对象或该关系中,任何其他数据像 XML 文档。 它以准备好的格式存储数据。 它并没有表和行和主键和外键的数据库的概念。 程序员,一个分布式的缓存是实质上是一个 HASH 表,其中有是一个键和每个项的值,值为的对象。 您需要知道该项,并且基于键,您可以获取所需的对象。 这是一个可以跨越多个服务器的逻辑缓存。 可以添加服务器在同一时间增加缓存的簇大小,并且可以在同一时间而不终止任何收缩缓存群集中删除框。

缓存的拓扑

应提供一个有效的缓存的在各种拓扑复制,分区,复制和分区的混合和客户端或本地缓存。 其理念是使用的具有不同的缓存拓扑不同类型,使缓存极其灵活。 在复制的拓扑复制缓存多次,根据方法很多时候您需要 (请参见 图 4 )。 供的有一个读需要缓存使用但不是更新大量。

fig04.gif

图 4 </a0>-复制的缓存非常适合读需要使用

一个分区的缓存是最具有高可伸缩性的拓扑,更新大量或事务性数据需要缓存的。 这可能是 ASP.NET 会话数据是非常事务。 如前所述,为每个 Web 请求该会话一次读一次,更新,因此它已读取和写入的相同数目。

一个分区的拓扑 (请参见 图 5 ) 是用于在更新必须完成至少多次为您正在进行读取的环境或非常接近的极好。 在此拓扑,划分缓存。 当您添加越来越多的缓存服务器,缓存更多分区方式,几乎一第 n 个 (N 表示的节点数) 缓存的存储在每个缓存服务器。

fig05.gif

图 5 分区的缓存非常适合写大量使用

在第三个的拓扑是分区和复制版本的混合。 您可以分区缓存,和可以与的同时复制所有分区。 因此,您获得最好的两个领域。 您可以进行分区和增长,以及您可以复制以确保没有数据丢失的可用性 (请参见 图 6 )。

fig06.gif

图 6 分区副本缓存是适合写 intensiveusage 的可靠性

分区和分区复制的混合拓扑的借助增长缓存线性的可伸缩性。

客户端或本地缓存是在第四个的非常有用拓扑,位于应用程序服务器上的。 这种类型的缓存非常接近应用程序,并甚至可以是 InProc。 它通常是实际的大型分布式缓存一小部分,并且基于任何时间当时该应用程序已被请求。 在任何应用程序请求客户端缓存中保存一个副本。 下次应用程序需要相同的数据时它会自动发现客户端缓存中。 它不必转到分布式缓存将甚至,保存为一个的旅行,因为分布式的缓存通常是在单独的缓存服务器或缓存服务器群集在网络上。 客户端缓存提供了附加的性能和可伸缩性提高。

客户端缓存中的数据必须保持同步分布式的缓存。 如果该相同的数据更改分布式缓存中,分布式缓存必须与客户端缓存中同步更改。 这是一个重要方面,不需要有只是一个完全断开连接的本地缓存。 这就相当于不可接受,因为有数据完整性问题的 InProc 缓存。 您有多个副本获取同步相同的数据。

不同的选项

有多个分布式的缓存功能... 并,大多数的情况下所示可用的解决方案提供更有限的功能集而专业的提供更多的选项和功能。

除了高性能、 可伸缩性和高可用性,有效的分布式的缓存必须包含了多种可以帮助您保留缓存,新和与主数据源同步,是否数据库或大型机的关键功能。 缓存应具有一个过期选项,因此可以了解执行可能的绝对时间或内容称为"滑动 Time"的自动过期。 基本上,这空闲时间 ; 如果没有人使用的数据,它已自动过期。

缓存也应该是能够管理不同类型的数据之间的关系。 大多数的数据是关系。 是例如如果您已获得客户,必须该客户订单因此客户数据和订单数据之间的关系。 如果您缓存客户和订单数据和您无意中删除客户数据从缓存,其意义顺序将被自动删除。 在这种情况不知道是否从缓存中移除客户数据或永久删除。 以防您永久删除它,顺序也是无效现在因为顺序必须为从有效的客户。

有必须管理缓存中的关系的其他类似类型。 如果缓存不会执行其,然后在应用程序保持跟踪,是很麻烦。 Microsoft 缓存对象非常有用的 ASP.NET 中称为"缓存依赖项概念"。 一个缓存的项依赖于另一个。 如果该其他缓存的项是过从缓存中删除,或者甚至更新中, 也删除第一个缓存项。 这是缓存关系数据的所有缓存中应该可用的一个功能强大的缓存依赖项概念。

与数据库同步将是用于缓存的另一个重要功能。 通常由多个应用程序共享数据库。 如果使用缓存应用程序是唯一的更新数据库,您可能不需要数据库同步功能。 但经常,其他应用程序有时会有第三方的应用程序将更新数据库中的数据,因为该数据库是一个共享的公用存储,并且这些应用程序不能使用您的缓存。 它们可能甚至无法.NET 应用程序。 它们可能是第三方应用程序不控制,但它们更新数据库中。 因此,您必须允许其中数据库可能会更新您的应用程序外,但某些更新数据库中的数据也被缓存的情况。 因此,缓存必须为能够同步。 它具有能够知道时它的数据不再数据库中。 它必须从缓存中删除该数据,并可能甚至重新加载最新副本从数据库中。 数据库同步可以通过触发由该数据库服务器或轮询数据库缓存的事件。 事件的更多实时课程并且轮询具有稍有延迟。 但轮询可以更有效,如果更改大量数据。

事件通知是有效的分布式的缓存应具有最重要功能。 缓存通常共享多个应用程序之间,甚至在多个用户之间的应用程序。 因此,缓存应具有的事件通知机制,以防,是例如缓存的对象是更新或删除。 如果您的应用程序正在使用的相同的数据,可以通知以便可以重新加载数据库或新副本从自身缓存。 通知机制在多个用户或多个应用程序通过缓存提高协作。

成为现实的世界

IT 管理面临与数据库,相关联的所有性能问题并瓶颈的情况如果您足够幸运,能够在其报告给开发人员,它们可能会尝试解决它们。 遗憾的是,开发并非总是内部的。 通常与生活和管理第三方应用程序。

在任何种情况下启动实现最好位置分布缓存以打开瓶颈和您的应用程序与 ASP.NET 会话存储,turbo 费用,因为无需依赖于开发人员。 这里没有编程涉及。 内存中分布式缓存中替换现有的会话存储一个简单问题。 此外,实现分布式的缓存 ASP.NET 会话存储使您有机会查看性能和可伸缩性,应计的好处,然后您可以决定是执行相同的应用程序数据。

若要体验可伸缩性改进,则或者必须运行分布式缓存在生产中的存储,或者必须以模拟在测试环境中的负载。 就这有助于将分布式的缓存放入生产之前模拟大的负载测试环境中执行压力测试的 QA 的访问。 大多数 IT 经理可能不会喜欢分布式的缓存中放置生产除非它们有测试第一次在其 QA 环境中,否则即使在无法模拟相同数量的负载。 因此,这是启动一个好地方。

一次您启动并运行与分布式的缓存和 reaping 其优点,您可以共享您新 ASP.NET 会话性能和可伸缩性发现与内部或第三方的供应商的开发团队。 与在现有硬盘的证据,您可以让开发团队分析,它们可以缓存以及此分布式缓存中的应用程序数据的区域。

缓存应用程序数据提供了进一步的提升,并在许多情况下很多更提升比只用于 ASP.NET 会话存储中使用分布式的缓存。 开发人员能够识别比它们进行更新更频繁地读取的所有数据元素。 即使它保持在缓存中过期前几分钟时间也甚至事务性的数据,(如客户、 订单和类似) 用于缓存,是一个很好的例子。 这是因为重新时间此简短段内数据可能会读取次数,如果此 rereading 缓存中且不是从数据库,它使您的数据库读取加载大量。

但是,开发人员可以缓存应用程序数据,它们必须通过在分布式的缓存 API 调用中实现的编程。 其理念是非常简单。 他们的应用程序尝试从数据库提取数据时, 应首先检查缓存。 如果缓存的数据,数据取自缓存。 否则为应用程序从数据库提取数据、 将其,缓存,然后给用户。 这种方式,数据将找到缓存中读取下一次。 同样,每当在数据库中修改数据时,就其应该也进行更新缓存中。 和,如果缓存居住在多个服务器上,它必须因此同步自动以确保如果您的应用程序运行在 Web 集群中,相同的缓存数据是从服务器场中的所有服务器访问。 对于主题如何开发使用分布式的缓存获得更好的可伸缩性的应用程序的详细信息,查找 MSDN Magazine 我即将发布文章 7 月期刊中。

Iqbal Khan 是总裁和技术推广人员的 Alachisoft,提供 NCache 的公司,该行业的前导.NET 分布式缓存 boosting 性能和企业应用程序中的可伸缩性。 Iqbal 1990 年中,在从 Bloomington,印第安纳大学 (University 的计算机科学中接收到一个 MS。 您可以 brian.noyes iqbal@alachisoft.com.