Jason Roth、Rama Ramani、Jaime Alva Bravo
2011 年 3 月
本白皮书为 Windows Server AppFabric 缓存 容量规划提供指南。
- 简介
- 评估 AppFabric 缓存性能
- 容量规划方法
- 步骤 1:了解瓶颈并确定缓存候选项
- 步骤 2:评估当前工作负荷模式
- 步骤 3:了解物理基础结构和硬件资源
- 步骤 4:完成所有应用程序所需的性能 SLA
- 步骤 5:确定相应的 AppFabric 功能和配置设置
- 步骤 1:了解瓶颈并确定缓存候选项
- 容量规划工具
- 容量规划后续步骤
- 监视现行缓存容量要求
简介
Windows Server AppFabric 缓存提供一个分布式内存中缓存群集。本文为 Windows Server AppFabric 缓存的内部部署提供容量规划指南。
本文档详细介绍了 Windows Server AppFabric 缓存的体系结构。有关详细信息,请参阅 Windows Server AppFabric 缓存功能。总之,AppFabric 缓存群集是由一个或多个缓存服务器(也称为缓存主机)组成的。缓存是跨缓存主机分布的并且存储在内存中。
注意 |
---|
请注意,还有一个 Windows Azure AppFabric 缓存版本,用于在云中使用缓存。本文中的关于估计内存要求的某些步骤将适用于基于云的解决方案,但本文特别关注内部缓存群集方案。有关使用 Azure AppFabric 缓存功能的详细信息,请参阅 Windows Azure AppFabric 缓存。 |
本文中的信息基于 Microsoft 已经对客户进行的规划工作。所有 AppFabric 缓存客户都提出了一个常见的问题:“我的方案需要多少服务器?”在很多这样的讨论中,我们的典型回答都是“看情况而定”。然后,我们快速深入了解各种详细信息并最终到达一个很好的起点。在此过程中,出现了其他更具体的问题:
- 我的应用程序需要多少缓存内存?
- 我应该在缓存群集中使用多少计算机?
- 每台计算机上应该有多少内存,以及如何配置这些内存?
- 网络带宽如何影响缓存群集性能?
本白皮书的目标是从这种类型的客户讨论中吸取教训,提供可以用于容量规划的方法。
如果您正在阅读本文,那么您可能会落入若干开发阶段之一:
- 您刚刚开始考虑分布式缓存并且对于混合工作负荷、性能要求或服务器部署拓扑没有任何深入数据。此时,您可能想先看看 AppFabric 缓存的一些性能数据。
- 或者,您已经调查了 AppFabric 缓存的功能和性能。现在,您想要获得帮助,以便密切关注你的具体方案以及高级要求。您将在此处获得容量规划的详细信息。
- 最后,您可能已经在生产。在此阶段,您要了解如何分析性能数据以确保您拥有足够的容量。此外,您还要为将来工作负荷的增加作出规划,基于 AppFabric 缓存的运行时行为了解主要指标和最佳实践。
本白皮书的结构是按顺序致力于这些阶段。如果您刚刚评估了 AppFabric 性能,我们将谈到由我们的合作伙伴 Grid Dynamics 编写的综合白皮书。此处,我们将采用简单的方式对该白皮书中的数据进行分组,以便评估并告知容量规划过程。
如果您已准备好进行容量规划过程,我们会提供将可以应用于您的方案的方法正式化的一组步骤。
如果您正在使用或测试缓存群集,则可以通过查看一组关键的性能指标来验证容量规划过程,以确保您拥有正确的容量。此外,我们还将讨论一些最佳实践。
评估 AppFabric 缓存性能
我们的合作伙伴 Grid Dynamics 最近完成了对 AppFabric 缓存性能的一系列测试。他们在下列白皮书中发布了他们的结果:Windows Server AppFabric 缓存:详细的性能&可伸缩性数据表。
每个测试都关注一个特定的变量,如缓存的大小或缓存群集中服务器的数量。可以使用 Grid Dynamics 论文来评估 AppFabric 缓存的性能和可伸缩性。您可以将大范围测试方案和拓扑的吞吐量和延迟数字与您的应用程序要求相比较。通常,在每个测试中,只改变一个或两个参数,以便关注其对性能的影响。整个参数集包括:
负载模式 |
缓存使用模式,即“Get”、“Put”、“BulkGet”、“GetAndLock”、“PutAndUnlock”操作的百分比 |
缓存数据大小 |
在测试期间存储在缓存中的数据量 |
群集大小 |
缓存群集中的服务器数量 |
对象大小 |
序列化之后存储在缓存中的对象大小 |
类型复杂性 |
存储在缓存中的不同 .NET 对象类型,如字节,string[] 等 |
安全 |
缓存群集的安全设置 |
除了验证 AppFabric 缓存的性能和可伸缩性之外,Grid Dynamics 还提供了测试工具,以便您能够使用自己的数据和工作负荷重复进行测试。这是评估您的特定方案缓存性能的另一个选项。
尽管我们强烈建议查看整个论文及其结论,但是下面概括了该论文的几个结论,这些结论将告诉我们本文后面讨论的最佳实践:
- 随着向缓存群集中添加越来越多的计算机,AppFabric 缓存将线性放大。
- 缓存大小的影响比较小,但具有高百分比写入的大型缓存除外。在其他因素中,当托管堆大小比较大时高写入工作负荷对 .NET 垃圾收集的压力比较大。
- 较高的类型复杂性由于序列化而只影响客户端性能。
- Bulk Get 调用导致网络利用更好。直接缓存访问比代理 (ASP.NET, WCF) 速度更快,但这是由于中间层的性能而不是缓存性能。
- 悲观和乐观锁定以相似方式执行,因此您应该使用最适合您应用程序设计的技术。当冲突率降低时延迟和吞吐量都会改进。
- 缓存群集安全不会降低性能,并且默认情况下处于启用状态。当禁用安全时会获得最高的吞吐量和最低的延迟,但由于数据和业务要求的敏感性,这个结果可能是无法接受的。
- 通过在应用程序服务器和缓存服务器之间使用专用网络来减少网络瓶颈。
请注意,Grid Dynamics 论文是开始评估 AppFabric 缓存的好地方,此外,它还包含原始数据以及可以用来告知容量规划进程的观察模式。
容量规划方法
一旦您确定您的应用程序可能会从分布式内存中缓存(如 AppFabric 缓存)中获益,您便可以进入容量规划阶段。尽管可以通过对 AppFabric 缓存群集进行直接测试来执行某些容量规划步骤,但如果没有这种类型的测试,您可能需要创建一个模拟。这就是本部分的焦点所在。以下部分提供一种考虑您的 AppFabric 缓存要求的系统化方式:
- 了解瓶颈并确定缓存候选项
- 评估当前工作负荷模式
- 了解物理基础结构和硬件资源
- 完成所有应用程序所需的性能 SLA
- 确定相应的 AppFabric 功能和配置设置
本文通过分析在线商店应用程序示例的需求来提供这些步骤的示例。但是,任何类型的 .NET 应用程序都可以使用缓存,您可以让多个应用程序访问同一个缓存群集。在此方案中,您应该为每个应用程序执行下面的步骤并将结果合计以获得对容量的精确评估。
步骤 1:了解瓶颈并确定缓存候选项
首先确定要缓存的数据。完成该操作的方法是:使用性能分析工具(如 SQL Server Profiler、性能监视器、Visual Studio 测试)以及很多其他工具。这些工具可以确定经常访问的数据库对象或降低调用 Web 服务的速度。从这些后端存储中返回的数据集是缓存的潜在候选项。将该数据临时存储在缓存中可以提高性能并缓解对后端数据存储的压力。
确定潜在的缓存候选项之后,最好将这些对象分为三大类之一:活动数据、参考数据和资源数据。最好使用示例对它们进行解释。
- 活动数据包含与单个用户相关的读取/写入数据。例如,在某个在线商店中,用户的购物车就是活动数据。该数据应用于用户的当前会话并且可能会经常更改。尽管保持购物车的高可用性非常重要,但并不一定需要将该数据永久存储在后端数据库中。由于其暂时的特性,活动数据便成为缓存的逻辑候选项。
- 参考数据是由多个用户或多个应用程序实例共享的只读数据。该数据经常访问,但不经常更改。例如,在在线商店的示例中,产品目录就是参考数据。该目录应该在一天或若干天内有效,但不同的用户可能会访问几千次。这种类型的数据也是缓存的重要候选项。如果没有某些类型的缓存,则查看产品目录的每个用户都需要访问数据库中的数据。使用缓存可以缓解对后端数据库重复请求半静态数据的压力。由于其永久的特性,参考数据便也成为缓存的逻辑候选项。
- 资源数据是在用户之间共享的读取/写入数据。例如,支持论坛就包含这种类型的数据。所有用户都可以阅读对论坛帖子的回复。
由于不同类型的缓存数据将具有不同的使用模式,因此将数据分为这些类别可能会非常有帮助。例如,确定某个对象是否是参考数据会自动建议,该对象更像是只读工作负荷。还可以帮助确定过期策略,对于经常更改的数据来说一般更短一些。对于开发,这些合理的划分可以建议代码中可以封装的区域。
建议您为各个对象创建评估,然后再将该数据合计起来。下表显示了在此阶段收集的信息示例:
要缓存的对象 | 缓存分类 | 永久存储位置 |
---|---|---|
购物车对象 |
活动数据 |
无 |
用户参考对象 |
活动数据 |
后端数据库 |
产品目录 |
参考数据 |
后端数据库 |
用户论坛线程 |
资源数据 |
后端数据库 |
确定缓存的候选数据时,不需要您在每个类别中查找要缓存的数据。您可能发现只是缓存应用程序的购物车就可以提高性能和可伸缩性。此步骤最重要的一点是使用可用的信息来确定要缓存的最佳项目。
步骤 2:评估当前工作负荷模式
确定要缓存的适当数据之后,您必须了解应用程序当前访问该数据以及关联的工作负荷模式的方式。在此步骤结束时,您应该能够得出缓存内存要求的粗略估计。您还应该更好地了解访问和使用数据的方式,这在后面的步骤中非常重要。
例如,如果您将产品目录作为缓存的候选项,则您应该探究应用程序检索目录数据的时间以及进行这些请求的频率。基于之前的步骤,您知道这是参考数据,因此主要是只读工作负荷。详细了解不同对象的工作负荷模式将指导将来的容量决策。让我们仔细看看此步骤中涉及的内容。
有很多方法可以更好地了解您的当前数据访问模式:
- 仔细查看代码,以了解访问数据的位置以及访问的频率。
- 使用可以提供方法调用频率以及关联的性能数据的代码探查器。
- 在特定数据访问部分的代码中创建规范。记录数据访问尝试以及数据操作的关联性能。
- 使用数据库探查器(如 SQL Server Profiler)观察数据库操作的数量以及持续时间。
请注意,在之前的步骤中可能已经使用了很多这种技术,用于确定缓存的目标数据。但是,在此阶段您对可以在将来容量规划计算中使用的更详细数字感兴趣。
此评估部分涉及了解读取与写入的比率。读取/写入工作负荷可能影响以后有关容量的决定。例如,写入百分比较高的工作负荷将触发更多的 .NET 垃圾收集。将在后面的步骤中对此进行讨论。
另一个因素是峰值负载期间读取和写入的频率。下表显示了在此阶段为示例购物车对象收集的示例数据。
要分析的对象 |
购物车 |
读取百分比 |
50% |
写入百分比 |
50% |
每秒的读取操作数(最大值) |
250 |
每秒的写入操作数(最大值) |
250 |
此外,还应该对每个对象类型进行这种分析。不同的对象类型将具有不同的访问模式,并且在负载下每秒的最大读取和写入数也不相同。
若要了解缓存要求,您必须在任何给定的时间对缓存中每个类型的最大活动对象数进行估计。此估计涉及平衡对象插入的频率与这些对象的平均寿命。使用示例可以更好地了解此过程。
在 ASP.NET Web 应用程序示例中,操作数据可能显示存在 25000 个并发用户的高峰时段。每个用户都需要会话状态信息,因此是 25000 个缓存对象。但可以将这些对象的过期时间设置为 30 分钟。在高峰时段,操作数据可能显示 1 小时有 5000 个新用户,这意味着在 30 分钟的过期时间内 2500 个新用户可能会到达。此外,一些用户可能会关闭其浏览器,启动一个新会话。尽管他们是相同的用户,但他们现在使用不同的会话。因此,为了解决此问题,需要进行额外的补充。最后,应该计划在接下来的 6-12 个月中的任何预期发展。最终,计算缓存中活动对象的最大数量可能如下所示:
要分析的对象: |
购物车 |
并发用户峰值 |
25000 |
过期时间(30 分钟)内的新用户数 |
2500 |
启动新的浏览器会话的现有用户 |
250 |
将来发展估计 (25%) |
6940 |
活动对象总数(最大值): |
最多大约 35000 个活动对象 |
如果对输入(如过期时间)进行更改,则将更改峰值负载期间缓存中存在的未过期对象数。这仅仅是思考过程的一个示例。其他对象类型可能有不同的模式,并且参与计算的变量也不同。例如,如果某个共享的产品目录一整天都有效,则在这一天内缓存中的产品目录对象的最大数量应该为 1。
但是,只有您还知道平均对象大小时,知道缓存中的最大对象数才有帮助。从本质上说,这是一个很难的问题。在购物车示例中,一个用户可能将一个项目放入其购物车,而同时另一个用户可能拥有 10 或 20 个项目。目标是了解平均值。与此过程中的大多数数字一样,它不会太完美,但最终结果是缓存群集的深思熟虑的起点,而不是简单的猜测。
对象以序列化的形式存储在缓存中。因此,若要了解平均对象大小,您必须计算平均的序列化对象大小。AppFabric 先使用 NetDataContractSerializer 类进行序列化,然后将项目存储在缓存中。若要确定平均对象大小,请向应用程序中添加序列化对象并记录其序列化大小的规范代码。
以下代码示例尝试估计单个对象的平均大小。正在进行序列化的对象名为 obj
。使用 length
变量记录长度。如果使用 NetDataContractSerializer 获取大小时遇到任何问题,则使用 BinaryFormatter。您可以将其封装在某个方法中以便使用。这种情况下,obj
将以参数的形式传递,并且将从该方法中返回 length
。
// requires following assembly references: // //using System.Xml; //using System.IO; //using System.Runtime.Serialization; //using System.Runtime.Serialization.Formatters.Binary; // // Target object “obj” // long length = 0; MemoryStream stream1 = new MemoryStream(); using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateBinaryWriter(stream1)) { NetDataContractSerializer serializer = new NetDataContractSerializer(); serializer.WriteObject(writer, obj); length = stream1.Length; } if (length == 0) { MemoryStream stream2 = new MemoryStream(); BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(stream2, obj); length = stream2.Length; }
注意 |
---|
请注意,如果您拥有测试缓存群集设置,则可以向缓存中添加项目并且可以使用 Windows PowerShell 命令 Get-CacheStatistics 来查找已添加到缓存的一个或多个对象的大小。或者您也可以用缓存中多个对象的大小除以缓存中对象的个数。可以选择通过代码收集估计或者通过测试收集估计。 |
如果您计划对会话状态使用 AppFabric 缓存,则了解 ASP.NET 会话状态的 SQL Server 提供程序始终使用 BinaryFormatter 而不是 NetDataContractSerializer 非常重要。有时,由 NetDataContractSerializer 类序列化的对象可能比使用 BinaryFormatter 的对象的序列化大小大几倍。当您查看 SQL Server 中会话状态对象的大小时这一点非常重要,因为您无法使用该大小并且假定它就是缓存中的大小。您可以用该大小乘以 6 来获得一个大致的估计。若要获得更好的估计,请对会话状态中存储的对象使用上述代码。借助收集到这一点的数据,您便可以开始计算总内存要求。此步骤涉及以下几个子任务:
- 关注某个对象类型(例如,购物车对象)。
- 对于该对象,首先获取平均的序列化对象大小。
- 然后,用平均大小加上 500 个字节来计算缓存开销。
- 用该大小乘以活动对象的最大数量。这将得到该对象类型的总缓存内存要求。
- 增加内部缓存结构的估计开销 (5%)。
- 对每个确定的对象类型重复这些步骤。
- 这些结果合计起来便可以获得缓存内存要求。
在此过程中,请注意每个对象大约有 0.5 KB 的开销,您应该将此添加到大小估计中。此外,缓存中还有其他需要内存的内部数据结构。区域、标记和通知所有这些都需要额外的内存进行管理。在我们的示例计算中,我们增加了总数的 5% 来计算这些内部结构,但对于您来说这个值可能大了或小了,具体情况取决于您使用这些缓存功能的程度。
此时,您应该考虑一个特定的 AppFabric 缓存功能,即高可用性的影响。该功能会在辅助服务器上创建缓存项目的副本。这意味着如果一个缓存服务器出现故障,辅助缓存服务器将接管并且数据不会丢失。如果您选择使用高可用性,则您必须使内存估计加倍。您还必须使用 Windows Server 2008 Enterprise Edition 或更高版本。请注意,高可用性功能是在命名缓存级别获得的。这意味着如果您想在同一群集中创建两个命名缓存,则不一定对每个缓存都使用高可用性。应用程序可以在具有高可用性的命名缓存中放置一些项目,将另一些项目放置在没有高可用性的缓存中。这样可以帮助您充分利用您的内存资源。因此了解有关高可用性的决定非常重要,因为它会使使用它的缓存的内存要求加倍。
作为一个示例,下面是我们评估同一应用程序中活动数据和参考数据要求的表格。根据您的方案,您可以选择在对象级别或应用程序级别进行此估计。我们刚刚向该示例中添加了多个列并且相应地对这些列进行了标记。
要分析的对象: |
活动数据 |
参考数据 |
平均序列化对象大小: |
250 KB |
60 KB |
每个对象的缓存群集开销: |
0.5 KB |
0.5 KB |
调整后的平均序列化对象大小: |
250.5 KB |
60.5 KB |
最大活动对象数: |
~35000 |
~68000 |
缓存内存要求: |
8.4 GB |
3.9 GB |
是否支持高可用性? |
16.8 GB |
不支持 |
内部数据结构开销 (5%): |
0.8 GB |
0.2 GB |
总内存要求: |
17.6 GB |
4.1 GB |
这些估计合计起来就构成了缓存群集的初始内存要求。在本例中,总计为 21.7 GB。有了这个估计,您现在就可以开始查看其他考虑事项,包括物理基础结构、SLA 要求以及 AppFabric 缓存配置设置。
步骤 3:了解物理基础结构和硬件资源
了解您的物理基础结构以及资源的可用性非常重要。下面是一些常见的问题:
- 您能够设置物理计算机或虚拟计算机吗?
- 如果您有现成的硬件,那么计算机配置都有哪些内容(例如,8 GB RAM,双核)?
- 缓存群集将与应用程序服务器位于相同的数据中心吗?
- 网络功能都哪些?
如果您考虑使用虚拟机作为缓存服务器,则有很多考虑事项。例如,您必须考虑在同一物理计算机上拥有多个虚拟机所带来的影响。多个虚拟机可以共享同一网卡,但却增加了网络瓶颈的可能性。还可以在都是同一物理计算机上的虚拟机的主要缓存主机和辅助缓存主机之间设置高可用性。如果物理计算机出现故障,则不会留下任何数据副本。有关详细信息,请参阅在虚拟机中运行 AppFabric 缓存的指南。
对于现有的计算机,不建议这些规范。但是,对于大型缓存群集,我们曾经看到过 16GB RAM 双核的计算机工作出色。通常,计划正确的物理内存和网络负载数量是最重要的考虑事项。
对于物理计算机和虚拟机,您应该记住使用缓存的应用程序或 Web 服务器的缓存群集的位置。如果它们位于各自的数据中心,则确保这些数据中心之间的延迟不会对性能产生不利影响。在此阶段,可以尝试使用应用程序或 Web 服务器作为缓存服务器。尽管可以,但不支持这样做。首先,这些计算机上由服务(如 IIS) 带来的任何资源使用峰值都可能会影响缓存群集。其次,缓存服务假定自己位于专用服务器上并且可能会使用多于您指定的内存数量。
对于网络功能,您应该评估预期的网络负载并将其与您的基础结构进行比较。首先,您必须知道每个缓存服务器预期处理的数据数量以及网卡功能是否足够。如果不够,则可能需要更多缓存服务器。例如,考虑一个方案,其中平均缓存对象大小为 500.5 KB 并且在缓存群集上每秒有 240 个操作。如果使用一个缓存主机,则结果将如下所示:
每秒读取/写入的对象数量: |
240 |
缓存群集中的计算机数量: |
1 |
每秒每台计算机的缓存操作数量: |
240 |
平均对象大小: |
500.5 KB |
每秒传输的数据大小: |
240 * 500.5 = 117.3 MBps |
如果每台计算机都拥有一个 1Gbps 的网卡,则最大吞吐量大约为 119 MBps。计算的值为 117.3 MBps 可能会压倒那台服务器。更有可能的是该网络将成为一个瓶颈。但是,如果在缓存群集中使用三台计算机,则平均分布缓存请求会导致每台服务器获得该负载的 1/3。
还要考虑访问缓存群集的应用程序服务器的网络利用率。如果它们与其他系统交换大量数据,则您应该考虑在应用程序服务器和缓存群集之间创建一个专用网络。这需要在每台应用程序服务器上安装一个附加的网卡,以便用于此目的。
最后一个网络考虑事项为网络是否可以沿着整个路径处理所需的负载。每台缓存服务器上只拥有一个 1Gbps 的网卡是不够的。网络上的交换机和其他位置也必须能够处理负载。使用操作来满足此要求。
步骤 4:完成所有应用程序所需的性能 SLA
决定最后一项配置之前,您还必须了解所有业务要求,包括性能和可靠性服务级别协议 (SLA)。在实际意义上,此步骤影响对缓存群集数量以及每个群集中缓存主机数量的决定。
例如,如果您拥有一个使用缓存群集的关键任务应用程序,则您可能希望将该缓存群集与其他优先级较低的应用程序隔离。这些优先级较低的应用程序可能会使用更多内存、网络或 CPU 资源,这将对关键任务应用程序产生不利影响。
下面是影响此决定的具体因素:
- 安全性保持在缓存群集级别。如果某个用户具有对缓存群集的访问权限,则该用户可能会访问缓存群集上的任何数据(假定该用户知道缓存名称以及要请求的密钥)。如果您需要对不同类型的数据进行不同的安全设置,则分离缓存群集可能比较有意义。有关详细信息,请参阅管理安全。
- 当内存达到高水印级别时会逐出未过期的项目。低估一个缓存所必需的内存数量可能会影响群集上的所有缓存。当由于内存压力而发生逐出时,即使只有一个缓存负责内存压力,也会在所有缓存上发生逐出。创建不可逐出的缓存可能会有所缓解,但必须谨慎执行此操作。有关详细信息,请参阅过期和逐出。
- 通过将缓存群集分离到某个点上可以更容易进行管理。您可能不希望为 100 个不同的缓存管理各自的群集。但让两个不同的大型缓存拥有各自的缓存群集可能非常有用,因为您可以分别管理、缩放和监视它们。
最后,某些要求可能涉及考虑延迟和吞吐量。若要获悉此决定,请参阅 Grid Dynamics 白皮书以便获得指导和测试结果。例如,您可以将缓存群集的吞吐量要求与 Grid Dynamics 白皮书中发布的测试结果进行对比。他们的研究可能指出,对于您的吞吐量目标来说,您拥有的服务器太少了。重要的是,要认识到该研究可能并不能与您的对象类型、对象大小以及物理和逻辑基础结构完全匹配,但它仍然可以为您提供经过证实的测试结果,这些结果可以帮助您作出明智的决定。
步骤 5:确定相应的 AppFabric 功能和配置设置
此过程的这个部分考虑 AppFabric 缓存的特定配置设置以及 AppFabric 缓存群集的体系结构。即使拥有所收集到的所有合适的经验和业务数据,但如果忽略这些 AppFabric 缓存设置,您仍然可能会制订错误的规划。
下表列出了各种 AppFabric 缓存功能以及关联的容量规划考虑事项。
区域 |
您可以创建多个区域,但每个区域只能在一个缓存主机上。若要利用分布式缓存,应用程序必须使用多个区域。请注意,所有未指定区域的调用都会自动在内部使用默认区域。缓存群集中的每个缓存主机必须能够托管最大的区域(最大大小)。 |
通知 |
缓存可以启用通知并且缓存客户端可以接收这些通知。这会在服务器端增加网络流量和处理器利用率。影响因通知间隔和发送的通知数量而异。以非常短的间隔发送大量通知可能会对性能和可伸缩性有影响。估计此影响没有严格的准则,因此必须在测试过程中进行观察。 |
本地缓存 |
本地缓存通过将对象缓存在客户端和服务器上来提高性能。考虑使用本地缓存时内存对客户端计算机的影响。该功能对服务器端容量规划没有任何影响,因为所有本地缓存的项目也存在于服务器上。但是,如果通知用于使本地缓存无效,则服务器端可能会受到通知处理的影响。 |
客户端应用程序设计 & 配置 |
客户端应用程序设计可能会影响您的整体性能。例如,您应该存储您创建的任何 DataCacheFactory 对象以便重复使用,而不是每次调用都重新创建这些对象。为每个线程创建一个 DataCacheFactory 对象,您可能也会从中受益。或者如果您让多个线程共享一个 DataCacheFactory 对象,则考虑提高 MaxConnectionsToServer 设置。这会增加每个 DataCacheFactory 与缓存服务器的连接数量。 |
高可用性 |
如上所述,使用高可用性的缓存需要使计算的内存要求加倍。但该功能还需要至少三台服务器。如果一台服务器出现故障,必须有两个剩余的服务器来支持发生故障后每个项目的主要和辅助副本。请注意,该功能还需要在所有服务器上安装 Windows Server 2008 Enterprise Edition 或更高版本。 |
命名缓存 |
此时,存在 128 个命名缓存的限制。当您拥有需要多于此设置数字的应用程序时,这便成为容量规划决定。此时,您需要多个缓存群集或者您的应用程序必须设计为使用较少的缓存。另一个战略是通过编程方式在命名缓存中创建区域。 |
XML 配置存储 |
当您使用共享网络位置作为缓存群集配置存储时,您应该在群集中至少有三台服务器全部指定为主要主机。有关这些原因的详细信息,请参阅更新缓存服务器。 |
毫无疑问,要了解的最重要的设置之一是每个缓存主机上的内存设置。可以使用 Windows PowerShell 命令 Get-CacheHostConfig
查看每个缓存主机上的默认内存设置。
注意 |
---|
有关如何使用缓存 Windows PowerShell 命令的信息,请参阅常规缓存群集管理任务。 |
以下屏幕截图显示了 RAM 为 4 GB 的计算机上 Get-CacheHostConfig
的输出。
默认情况下,在给定服务器上为缓存预留的内存数量为总 RAM 的 50%。在本例中,RAM 的一半是 2 GB。然后,剩余的内存用于操作系统和服务。即使在内存非常大的计算机上,也建议您保留此默认设置。如前所述,缓存服务假定它在专用计算机上运行,并且它使用的内存可能多于为缓存分配的内存。尽管此内存使用的一部分是由于缓存服务的内部设计,但其中一部分也与 .NET 内存管理和垃圾收集相关。即使在 .NET 应用程序中释放内存时,也必须等待垃圾收集从进程内存中释放。该进程需要物理内存的缓冲来解决垃圾收集本身的不确定性。
了解垃圾收集的影响之后,您可能会看到写入高百分比和高频率的工作负荷将需要较大的内存缓冲来解决垃圾收集的循环。大部分为只读的工作负荷将没有此顾虑。这种情况下,您可以考虑在某些情况下提高为缓存预留的内存数量。例如,在 16 GB 的计算机上,您可以考虑为缓存大小设置预留 12 GB(而不是默认值 8 GB),为操作系统和服务提供 4 GB 的开销。该操作假定此计算机专用于缓存服务,因为缓存服务是当前唯一支持的配置。在本例中,您应该用预期的负载测试此内存配置。如果内存分配太过分,那么测试将通过与内存相关的问题(如逐出或限制)显示此错误。有关详细信息,请参阅服务器问题疑难解答(Windows Server AppFabric 缓存)。以下示例使用 Set-CacheHostConfig
命令将名为 Server1
的服务器上的缓存大小设置为 12 GB:
Set-CacheHostConfig -HostName Server1 -CachePort 22233 -CacheSize 12288
要在 Get-CacheHostConfig
输出中观察的其他项目是水印值。LowWatermark 值的默认值为缓存大小设置的 70%。当缓存内存达到 LowWatermark 时,缓存服务开始逐出已过期的对象。该操作非常好,因为这些对象无论如何都无法访问。
HighWatermark 值的默认值为缓存大小设置的 90%。在 HighWatermark 级别,无论对象是否过期都会逐出,直到内存回到 LowWatermark 级别为止。很明显,这有可能会损害性能,并且还有可能会导致不良的用户体验。
我们建议您将缓存使用计划到 LowWatermark 级别,以避免达到 HighWatermark 的可能性。有关详细的描述,请参阅“过期和逐出”。
技巧 |
---|
完整的垃圾收集循环可能会导致短暂的延迟,这通常会在重试错误中看到。由于这个原因,我们建议每个缓存主机拥有 16 GB 或更少的内存。RAM 大于 16 GB 的计算机对于完整的垃圾收集循环可能经历更长的暂停。根据这种说话,对于每个缓存主机使用更多内存没有任何限制。大部分为只读的工作负荷可能无法经常经历完整的垃圾收集循环。您可以通过负载测试来更好地确定此内容。 |
在之前的示例中,我们为总缓存内存要求计算的估计为 21.7 GB。由于我们希望高可用性,因此必须至少有三台服务器。假定每台服务器都有 16 GB 的 RAM。在本例中,我们将每台服务器上的默认缓存大小设置保留为 8 GB。如前所述,LowWatermark (70%) 应该是每台服务器上可用的目标内存。这意味着每台服务器的估计内存为 5.6 GB。由于这些因素,下表显示了四台服务器将提供 22.4 GB 的缓存内存并且将满足 21.7 GB 的要求。
总内存要求 |
21.7 GB |
初始内存(缓存主机) |
16 GB |
缓存大小设置(缓存主机) |
8 GB |
低水印(缓存主机) |
70% |
调整后每个缓存主机的内存目标 |
5.6 GB |
缓存群集上的总内存(3 台计算机) |
5.6 GB * 4 台服务器 = 22.4 |
此外,请记住,您还可以使用 Grid Dynamics 白皮书中发布的结果来验证与吞吐量和延迟目标有关的这个估计。这些测试结果可能会使您稍微更改此初始估计,如通过添加额外的缓存服务器。此处比较重要的一点是使用像这样的可用资源来作出明智的决定。
容量规划工具
在之前的部分中,电子表格是用于容量规划步骤的逻辑工具。我们将您可以在此处下载的示例电子表格放在一起。带有星号的条目是您应该根据您的规划和资源进行修改的项目。剩下的计算由该电子表格来完成。
该电子表格的第一部分指定每个缓存主机的服务器配置。请注意,您可以作为规划过程的一部分更改此内容并在最终计算结果中观察差别。以下屏幕截图显示了这个第一部分。
要点 |
---|
除非您使用的是默认安装值,否则您负责在每个缓存主机上使用 Set-CacheHostConfig 命令应用 CacheSize 和 LowWatermark 设置。 |
第二部分允许您填写不同类型对象的估计。在此示例电子表格中,仅为“活动数据”和“参考数据”使用了两个部分。之后提供了一系列空白列。您可以根据在您的规划中使用的粒度级别(对象、类别、应用程序等)来重命名这些列。以下屏幕截图显示了这个第二部分。
第三部分估计网络要求。您填写平均读取/写入对象大小以及每秒的最大读取/写入操作数量。该部分计算该对象类型的最大网络带宽要求。使用该部分可以大致了解您的计算机和网卡组合是否可以处理负载。如前面的部分所述,您还希望查看整个网络路径上的带宽。以下屏幕截图显示了这个第三部分。
最后一个部分将内存和网络部分的要求合计在一起。然后,使用通过第一部分指定的计算机配置计算服务器的数量。“其他服务器”字段允许您增加此计算的总数(如果需要)。例如,如果计算指定只需要两台服务器,则您可以向最终总数中增加一台额外的服务器,以便适当支持高可用性。以下屏幕截图显示了这个最后一部分。
注意 |
---|
上面的屏幕截图使用与本文中的示例相似的数字,但估计的服务器数为三台,而不是四台。原因是该电子表格将 Cache Size Setting(Set-CacheHostConfig) 值设置为 12 GB 以演示这个自定义设置。将该值更改为 8 GB 产生的结果类似于在本文的前面部分看到的结果。 |
容量规划后续步骤
在前面的部分中,提供了一个用于确定缓存群集数量、每个群集中缓存主机数量以及这些缓存主机配置的初始估计的方法。但是,您应该认识到这只是一个估计,该估计可能会因测试以及进行的监视而异。
如果您决定按计划向前推进,以使用 AppFabric 缓存,则您可能会创建一个概念证明以便了解 AppFabric 缓存在您的解决方案中的工作方式。之后,您将希望设置一个测试缓存群集,以在您的环境中运行测试。根据测试结果,您可能需要对配置进行进一步更改以便实现容量、性能和可伸缩性要求。以下部分介绍您可以在测试和生产过程中查看的现行具体指标。
监视现行缓存容量要求
缓存容量规划从来不是精确的科学。结论中的很多数字都是估计的。此外,应用程序的使用和模式都会随时间而改变。因此,您应该监视性能指标,以确保缓存群集实现容量要求。成功的容量规划是一个持续的过程,会在测试和生产环境中不断继续。
性能监视器工具是持续监视容量的最佳方法。在每个缓存主机上,我们建议您监视以下计数器:
监视类别 | 性能监视器计数器 |
---|---|
内存 |
AppFabric Caching:Host\Total Data Size Bytes AppFabric Caching:Host\Total Evicted Objects AppFabric Caching:Host\Total Eviction Runs AppFabric Caching:Host\Total Memory Evicted AppFabric Caching:Host\Total Object Count .NET CLR Memory(DistributedCacheService)\# Gen 0 Collections .NET CLR Memory(DistributedCacheService)\# Gen 1 Collections .NET CLR Memory(DistributedCacheService)\# Gen 2 Collections .NET CLR Memory(DistributedCacheService)\# of Pinned Objects .NET CLR Memory(DistributedCacheService)\% Time in GC .NET CLR Memory(DistributedCacheService)\Large Object Heap size .NET CLR Memory(DistributedCacheService)\Gen 0 heap size .NET CLR Memory(DistributedCacheService)\Gen 1 heap size .NET CLR Memory(DistributedCacheService)\Gen 2 heap size Memory\Available MBytes |
网络 |
Network Interface(*)\Bytes Received/sec Network Interface(*)\Bytes Sent/sec Network Interface(*)\Current Bandwidth |
CPU |
Process(DistributedCacheService)\% Processor Time Process(DistributedCacheService)\Thread Count Process(DistributedCacheService)\Working Set Processor(_Total)\% Processor Time |
Throughput |
AppFabric Caching:Host\Total Client Requests AppFabric Caching:Host\Total Client Requests AppFabric Caching:Host\Total Get Requests AppFabric Caching:Host\Total Get Requests /sec AppFabric Caching:Host\Total Get Requests AppFabric Caching:Host\Total Get Requests /sec AppFabric Caching:Host\Total GetAndLock Requests AppFabric Caching:Host\Total GetAndLock Requests /sec AppFabric Caching:Host\Total Read Requests AppFabric Caching:Host\Total Read Requests /sec AppFabric Caching:Host\Total Write Operations AppFabric Caching:Host\Total Write Operations /sec |
杂项 |
AppFabric Caching:Host\Cache Miss Percentage AppFabric Caching:Host\Total Expired Objects AppFabric Caching:Host\Total Notification Delivered |
此处列出的很多计数器直接连接到容量规划过程。例如,存在很多内存计数器。“Memory\Available Mbytes”显示计算机上可用的物理内存数量(以 MB 为单位)。如果该计数器低于总物理内存的 10%,则发生限制的可能性比较大。有关详细信息,请参阅限制疑难解答。其他计数器都特定于缓存功能。“AppFabric Caching:Host\Total Eviction Runs”表示逐出内存的频率。当内存级别通过高水印时,该计数器将指向当内存回到低水印时运行的这些逐出。同样,其他计数器与在本文的前面部分发现的容量规划思考过程相关联。
请注意,还捕获服务 DistributedCacheService 的过程计数器以及计算机的 Processor 计数器。高处理器利用可能会对缓存群集性能产生不利影响。如果您检测高处理器利用的时段,则需要确定它是否与缓存服务 (DistributedCacheService.exe) 或计算机上的其他过程相关,这一点非常重要。
除了性能监视器工具之外,您还可以使用随 AppFabric 一起安装的 Windows PowerShell 命令。可以使用其中的很多命令来监视缓存群集的运行状况和状态。有关详细信息,请参阅运行状况监控工具和 AppFabric 缓存中的日志记录和计数器。
另请参阅
其他资源
安装 Windows Server AppFabricMSDN Windows Server AppFabric 缓存文档
AppFabric 缓存编程指南
配置 ASP.NET 会话状态提供程序
缓存群集配置存储选项
Windows Server AppFabric 缓存部署和管理指南
Windows Server AppFabric 以及 Windows Azure AppFabric 链接和资源