用于线性可扩展性的缓存拓扑
NCache 提供多种缓存拓扑,以实现线性可扩展性,同时保持数据的一致性和可靠性。 这样做的目的是满足从非常小的两服务器缓存运行到由数十甚至数百个缓存服务器组成的非常大的缓存集群的应用程序的需求。 缓存拓扑本质上是跨多个缓存服务器的集群缓存中的数据存储、数据复制和客户端连接策略。
以下是主要的缓存拓扑 NCache 规定:
分区缓存
分区副本缓存
复制缓存
镜像缓存 (2 节点主动/被动)
客户端缓存 (InProc 速度;本地缓存连接到集群缓存)
参考数据与交易数据
参考数据是不经常更改的数据,您可以将其缓存以一遍又一遍地访问并偶尔更新它。 另一方面,事务性数据是变化非常频繁的数据,您可以随时更新它。
对于价格变动不频繁的产品目录,缓存数据属于参考数据。另一方面,ASP.NET Core Session 存储则被视为事务性应用,因为会话数据会在每次 Web 请求时读取和更新一次,而 Web 请求可能每隔几秒钟就会发生一次。
在早期,缓存被认为主要用于参考数据,因为频繁更改的数据会变得陈旧并且与数据库中的最新数据不同步。 但, NCache 现在提供了非常强大的功能,使缓存能够保持其缓存数据与数据库同步。
所有缓存拓扑都适用于参考数据,但只有一些缓存拓扑特别适用于事务数据。 您需要确定要执行的读取次数和写入次数,以确定哪种拓扑最适合您。 此外,一些缓存拓扑不会专门针对更新进行扩展,因此请记住这一点。
下面是缓存拓扑列表及其对读取和写入的影响。
分区缓存(无复制): 非常好 . 读写速度超快,还可以通过添加服务器进行线性扩展。 最快的拓扑,但不复制数据,因此如果缓存服务器出现故障,则会丢失数据。
分区副本缓存 (最受欢迎): 非常好 . 读写速度超快,还可以通过添加服务器进行线性扩展。 第二快的拓扑,但在不影响线性可扩展性的情况下复制数据以提高可靠性。 速度/可扩展性和数据可靠性的最佳组合。
复制缓存 : 非常适合较小的环境 . 读取速度超快且线性可扩展。 在 2 节点集群中写入速度适中,但不会随着您添加更多服务器而扩展,因为写入是在所有缓存服务器上同步完成的。
镜像缓存 : 非常适合较小的环境 . 读取速度超快。 写入速度比 2 节点主动/被动的复制缓存快。 但是,不会超出此范围。
客户端缓存 : 非常适合阅读密集型使用 与所有缓存拓扑。 让您通过分布式缓存实现 InProc 速度。
拓扑
读取性能。
写入性能。
可靠性
最佳用例
分区副本
极端
高
高
交易数据/电子商务
分区的
极端
极端
没有
瞬态数据/最大性能
已复制
极端
中
高
小型集群/读取密集型
镜像
高
高
高
双节点主动/被动配置
客户端缓存
进程内速度
中
高(同步)
读取密集型/本地 L1 缓存
分区缓存
分区缓存是读取和写入的最快和最具可扩展性的缓存拓扑。 它适用于更大的缓存集群,即使在峰值负载下,读取和写入的性能仍然非常好。 但是,它不会复制数据,因此如果缓存服务器出现故障,则会丢失数据。
NCache 分区缓存,实现线性可扩展性和分布式存储。
以下是分区缓存的一些特性。
动态分区: 缓存在运行时被划分为多个分区,每个缓存服务器都有一个分区。 每个集群缓存总共有 1000 个桶,平均分布到所有分区。 添加/删除缓存服务器会导致在运行时创建/删除分区。 将数据添加到缓存时,分配给分区的存储桶不会更改。 相反,它仅在添加或删除分区或发生数据平衡时更改(见下文)。
分布图: 缓存集群创建一个分布图,其中包含有关哪些桶存在于哪些分区中的信息。 每当添加或删除分区或发生数据平衡时,分布图就会更新(见下文)。 分布图传播到所有服务器和客户端。 客户端使用它来确定要与哪个缓存服务器通信以读取或写入某个缓存项。
动态数据平衡: 由于所有存储桶实际上都是 HashMap 存储桶,其中基于键上的哈希算法存储数据,因此根据使用的键,某些存储桶可能比其他存储桶拥有更多的数据。 如果这种不平衡超过了可配置的阈值, NCache 自动移动存储桶以平衡此负载。
客户端连接到所有分区: 客户端连接到所有缓存服务器,因此它们可以在来自服务器的一个请求中直接读取或写入数据。 如果客户端与缓存服务器的连接中断,则它会要求其他服务器之一读取或写入存在于它无法访问的服务器上的缓存项。 而且,该服务器可以帮助客户端实现这一目标。
分区副本缓存
注意:分区缓存中提到的所有内容在这里也是如此。
就像 分区缓存 , Partition-Replica Cache 是一种非常快速且线性可扩展的缓存拓扑,适用于读取和写入。 它适用于更大的缓存集群,即使在峰值负载下,读取和写入的性能仍然非常好。 最重要的是,分区副本缓存还复制数据,因此即使缓存服务器出现故障也不会丢失数据。
分区副本缓存是我们的 最流行的缓存拓扑 因为它为您提供了两全其美的性能/线性可扩展性和数据可靠性。
NCache 分区副本缓存,实现数据可靠性和线性可扩展性。
以下是 Partition-Replica Cache 的一些特性。
动态分区: 一样 分区缓存 .
动态副本: 在运行时创建或删除分区时,也会创建或删除其副本。 副本始终位于不同的缓存服务器上,并且分区只有一个副本。
异步复制: 默认情况下,从 Partition 到 Replica 的复制是异步的。 这意味着客户端可以添加、更新或删除分区中的任何数据,并且所有这些操作都会排队。 然后,它们在副本上以 BULK 形式复制。 这提高了性能,但如果分区发生并且并非所有更新都已复制到副本,则存在轻微的数据丢失风险。 但是,在大多数情况下,这完全没问题。
同步复制: 如果您的数据非常敏感(例如财务数据)并且您无法承受过时的数据,那么您可以在配置中选择“同步复制”选项。 选中后,所有写入操作都会在 Partition 和 Replica 上同步执行,直到它们被认为已完成。 这样,如果操作在 Replica 上失败,它也会在 Partition 上失败。 而且,您可以保证缓存中的所有数据(在分区和副本中)始终保持一致。 但是,这具有性能影响,因为它比异步复制慢。
分布图: 一样 分区缓存 .
动态数据平衡(分区和副本): 一样 分区缓存 . 但是,在 Partition-Replica Cache 中,当分区进行数据平衡时,Replica 中也会发生数据平衡。
客户端连接到所有分区: 一样 分区缓存 . 此外,在 Partition-Replica Cache 中,客户端只与分区而不是它们的副本对话。 这是因为副本是被动的,只有分区在向其复制数据时才与它们的副本对话。
复制缓存
复制缓存通过在两个或更多缓存服务器上进行复制来提供数据可靠性。 它的读取速度非常快且可扩展。 但是,它不能针对写入进行扩展,因为它们与集群中的所有服务器同步。 对于 2 节点集群,写入速度比数据库快,但不如数据库快 分区副本缓存 . 对于 3 个或更多服务器集群,写入性能会下降并最终变得没有吸引力。
NCache 复制缓存可实现高数据可靠性和读取可扩展性。
以下是复制缓存的一些特性。
动态复制节点: 您可以在运行时向现有缓存添加或删除缓存服务器,而无需停止缓存或您的应用程序。 新添加的服务器将整个缓存的副本(副本)复制到自身。 并且,被删除的服务器会更新集群成员身份,并且其所有客户端都会移动到其他服务器。
每个节点上的整个缓存: 整个缓存被复制到集群中的每个服务器。
读取是可扩展的: 添加更多服务器时,读取速度超快且可扩展。 但是,添加更多服务器不会增加缓存大小,因为新添加的服务器只是整个缓存的另一个副本。
写入是同步的: 对于 2 节点集群,写入速度非常快,并且比您的数据库更快。 但是,写入是同步的,这意味着在所有缓存服务器同步更新之前,每个写入操作都不会完成。 因此,写入速度不如其他拓扑,并且当您将集群大小增加到超过 2 节点时,它们的性能会下降。
客户端仅连接到一台服务器: 每个缓存客户端仅根据缓存服务器确定的负载平衡算法连接到集群中的一台服务器。 如果此缓存服务器出现故障,客户端将连接到列表中的下一个服务器。 如果您不想使用负载平衡,也可以在缓存配置文件中手动指定要连接的服务器。
镜像缓存
镜像缓存是用于较小环境的 2 节点主动/被动缓存集群。 它通过从主动节点到被动节点的异步复制/镜像来提供数据可靠性。 读取和写入都非常快(实际上写入速度比 复制缓存 ) 但不会扩展到此 2 节点主动/被动集群之外。
NCache 镜像缓存,实现双节点主备高可用性。
以下是镜像缓存的一些特性。
1 个主动和 1 个被动服务器: 镜像缓存只有两台服务器。 一个是主动的,另一个是被动的。 它们都有整个缓存的副本。 如果 Active Server 出现故障,Passive Server 将自动变为 Active。 并且,如果先前关闭的 Active Server 重新启动,它将被视为被动服务器,除非您在运行时通过管理工具更改此指定。
具有故障转移支持的客户端连接: 每个缓存客户端只连接到集群中的 Active Server 来执行它们的读写操作。 如果此 Active Server 出现故障,所有客户端都会自动连接此时已变为 Active 的 Passive Server。 这种故障转移支持可确保即使服务器出现故障,镜像缓存也始终处于启动和运行状态。
异步镜像: 在主动服务器上完成的任何写入都会异步镜像/复制到被动服务器。 这可确保被动服务器始终与最新数据同步,以防主动服务器出现故障而被动服务器必须变为主动。 异步镜像也意味着更快的性能,因为多个写入是在被动服务器上作为 BULK 操作执行的。
特性
分区的
分区副本
已复制
镜像
最大簇大小
数百个节点
数百个节点
较小的集群
双节点(主动/被动)
复制类型
没有
异步/同步
Synchronous
异步
资料安全
低(无备用)
高(复制品)
高(完全备份)
高(镜面)
主要好处
最高性能
可扩展性 + 可靠性
读取密集型扩展
小规模可用性
客户端缓存(InProc 速度)
客户端缓存位于您的 Web / 应用服务器本地,并且非常靠近您的应用程序,并允许您缓存从分布式缓存(任何缓存拓扑)中读取的数据。 您可以将其视为“缓存之上的缓存”,并进一步大大提高了您的应用程序性能和可扩展性。 如果在 InProc 模式下使用 Client Cache,则可以实现 InProc 速度。
在您的应用程序本地时,客户端缓存不是独立的。 相反,它始终与集群缓存同步。 这可确保客户端缓存中的数据永远不会过时。
NCache 客户端缓存,实现亚毫秒级进程内性能。
以下是镜像缓存的一些特性。
适合阅读密集型案例: 仅当您有一个读取次数比写入次数多很多倍的读取密集型用例时,客户端缓存才有效。 如果写入次数与读取次数相同,则客户端缓存实际上更慢,因为写入涉及在两个位置更新它。
像本地缓存一样更快的速度(InProc / OutProc): 客户端缓存存在于您的应用程序进程中(InProc 模式)或本地到您的 Web / 应用程序服务器(OutProc 模式)。 无论哪种情况,与仅从集群缓存中获取此数据相比,它都能显着提高您的应用程序性能。 InProc 模式允许您在“应用程序堆”上缓存对象,从而为您提供任何分布式缓存都无法匹配的“InProc Speed”。
不是独立缓存: 客户端缓存可能是本地缓存,但它不是独立缓存。 相反,它使自己与集群缓存保持同步。 这意味着,如果另一个客户端更新您在客户端缓存中的集群缓存中的数据,集群缓存会通知客户端缓存使用该数据的最新副本更新自身。 而且,这是异步但立即完成的。
乐观/悲观同步: 默认情况下,客户端缓存使用乐观同步,这意味着 NCache 客户端假定客户端缓存拥有的任何数据都是最新的副本。 如果客户端缓存没有任何数据,客户端从集群缓存中获取数据,放入客户端缓存,然后返回给客户端应用程序。 悲观同步意味着缓存客户端首先检查集群缓存是否有更新版本的缓存项。 如果是,则客户端获取它,将其放入客户端缓存中,然后将其返回给客户端应用程序。 否则,它将返回客户端缓存中的任何内容。
无需任何代码更改的插件: 客户端缓存的最大优点是它不涉及应用程序中的代码更改。 相反,您只需通过配置更改将其插入即可。 和, NCache 幕后的客户端 API 知道如何使用客户端缓存。
接下来做什么?
常见问题
分区副本拓扑和分区拓扑是最具可扩展性的。它们使用包含 1000 个桶的分布式映射将数据分区到所有节点上,从而允许集群随着服务器数量的增加而线性扩展存储容量和事务吞吐量。
NCache 拓扑结构允许开发人员优先考虑特定的 CAP 属性。分区副本拓扑结构使用异步复制来保证可用性和分区容错性 (AP),而同步复制选项可以启用以确保敏感事务数据(例如财务记录)的严格一致性 (CP)。
参考数据(例如产品目录)读取密集且更改频率较低,因此非常适合采用复制缓存拓扑结构。事务数据(例如 ASP.NET Core 会话)更改频繁且需要高性能写入,因此建议采用分区副本拓扑结构以兼顾性能和数据可靠性。
客户端缓存充当“缓存之上的缓存”,驻留在应用程序本地(进程内或进程外)。通过将频繁访问的对象存储在应用程序堆上,它可以消除网络延迟和序列化开销,在提供进程内速度的同时,与分布式集群保持同步。
是的。 NCache 通过其分区副本和镜像拓扑结构确保高可用性。通过在单独的节点上维护每个分区的副本, NCache 如果服务器宕机,可防止数据丢失,自动提升副本或异步镜像数据,以确保持续正常运行时间。
是的。主要优势之一是 NCache 拓扑结构是在配置级别处理的。您可以通过以下方式从分区式切换到分区副本式,或者添加客户端缓存: NCache 无需修改 .NET、Java 或 Node.js 源代码,即可管理中心或配置文件。