通过扩展方法在 EF Core 中使用 .NET 缓存

录制的网络研讨会
罗恩侯赛因和尼克 Zulfiqar

Entity Framework (EF) Core 是 Microsoft 流行的 Entity Framework 的新的跨平台轻量级版本。 EF Core 是用于 .NET 的对象关系映射引擎,无需开发人员编写的大部分数据访问代码。

EF Core 越来越多地用于高事务服务器应用程序(ASP.NET、WCF 和其他 .NET 服务器应用程序)。 而且,这些应用程序需要可扩展性来处理大量用户请求而不会减慢速度。 但是,数据库成为瓶颈,必须使用分布式缓存来消除这个瓶颈。

学习如何使用分布式缓存,例如 NCache 在您的 EF 核心应用程序 用于消除数据库可伸缩性瓶颈。

该网络研讨会将涵盖(包括动手源示例:

  • EF Core 及其新功能介绍(模型、查询、保存数据)
  • EF Core 中的数据库可扩展性瓶颈以及分布式缓存如何解决这些瓶颈
  • 各种使用选项 NCache 在 EF Core 中(直接 API 和 EF Core 扩展方法)
  • 使用 EF Core 扩展方法进行缓存的详细信息
  • 如何为引用和事务数据处理集合和关系的缓存?
  • 一个好的分布式缓存的一些重要特性,比如 NCache

EF Core 是一个用于 .NET 和 .NET Core 应用程序。 这允许开发人员自动生成数据访问代码,通常必须自己编写该代码。 如同 .NET Core, EF Core 也是跨平台的,我的意思是你可以在 Windows、Linux、Mac 上运行它,它在开发人员社区中越来越受欢迎。

在本次网络研讨会中,我们将讨论 EF Core 应用程序中的性能和可扩展性需求,并将演示使用 EF Core 扩展方法缓存引用和事务数据的不同策略。 在典型的 EF Core 应用程序中您将面临哪些性能和可伸缩性挑战,然后我们将讨论在 Entity Framework Core 应用程序中使用缓存的各种选项。

我将主要关注扩展方法,我们为实体框架核心应用程序实现的 EF 扩展方法。 所以,我将介绍所有的 Entity Framework Core Extension Methods NCache 然后我们将讨论尼克建议的处理参考数据和事务数据的不同策略。 当您开始使用分布式缓存时,我们还将了解当数据存在于两个不同的位置时如何保持数据同步。 所以,这就是我们今天网络研讨会的议程。 我会很快开始的。 我们有很多东西要讲。 我想展示很多动手实践的例子。 所以,让我们快速开始吧。

什么是实体框架/EF Core?

因此,第一张幻灯片更多地介绍了 Entity Framework 和 EF Core。

什么是实体框架核心

EF 和 EF Core,这是一个用于 .NET 和 .NET core 应用程序。 最新版本的实体框架被命名为 EF Core。 你知道,我们最近看到 EF Core 2.1 与 .NET Core 2.1。 你知道,它简化了你的数据库编程。 您知道,它允许您自动生成数据访问模型。 所以,你不必自己写。 它减少了为此所需的开发工作。 您不必编写通常在 ADO.NET 级别上自己编写的持久性代码,然后您必须在数据模型和对象模型之间进行映射。 因此,它只是为您优化。

所以,它非常灵活。 它在开发人员社区及其跨平台中变得非常流行,并且在 .NET 和 .NET Core 应用程序,特别是处理大量请求负载的高事务性应用程序。

Entity Framework 架构图

这是实体框架的架构图。

架构图

你知道,它也适用于 EF Core。 EF 和 EF Core 之间几乎没有区别。 EF Core 是轻量级的。 它采用模块化方法。 没有很多,你不必经历完整的安装。 您可以采用模块化方法。 他们已将其分解为更小的包,因此,您可以使用您感兴趣的包。

因此,您不必为此进行完整的安装,而且他们还摆脱了 .edmx 和那些映射文件。 因此,您知道,NuGet 包和您运行的一些命令会为您生成模型,然后您只需在应用层使用 LINQ to Entities API,整体方法保持不变。

什么是可扩展性?

通常,在您知道的 EF Core 应用程序中,我们将讨论性能和可伸缩性的要求。 可扩展性是应用程序中的一种能力,您可以在其中增加该应用程序必须处理的请求数量。 例如,您的用户负载增长或那些对请求负载有贡献的用户,该请求负载在应用程序内增长,如果您的应用程序变慢,则该应用程序不可扩展。

因此,峰值负载下的高性能就是我们归类为可扩展性的内容。 如果您的应用程序运行良好,在亚毫秒内,XNUMX 个用户的延迟,它应该具有相同的性能,相同的延迟,低延迟,比方说,XNUMX 用户或 XNUMX 用户等等请求负载。

因此,在高压力负载、峰值负载下的高性能,这就是我们将其归类为可扩展性的原因。 EF 核心。

哪些应用程序需要可扩展性?

什么应用程序需要可扩展性

它可能是一个 ASP.NET Web 应用程序。 ASP.NET 或 ASP.NET Core 这可能会处理很多请求。 它可能是 .NET 和 .NET Core 网络服务,再次在网站上。 然后我们有物联网服务器应用程序。 同样,它可能是 .NET 或 .NET Core 或任何其他通用 .NET 和 .NET Core 可能正在处理自己域中的大量请求或用户的应用程序。

因此,这些是可扩展性的候选者。

可扩展性问题究竟出在哪里?

通常,EF 和 EF Core 部署在 Web 场上。 如果它是一个 Web 应用程序,它们会线性扩展。 您在应用程序层上没有任何可伸缩性问题,但它们总是必须与后端关系数据源通信。 它可能是 SQL Server。 它可以是 Oracle 服务器,也可以是 EF 或 EF Core 支持的任何其他数据存储。 在 EF Core 中,他们有很多数据提供者。 有一个供应商列表供您选择。 因此,您最终与数据库交谈。

尽管您的应用程序层可以很好地扩展,但是这种数据存储、数据库、关系数据库成为争用的来源。 启动很慢,因为它不在内存中。 尽管 EF Core 提供了一个内存数据提供程序,但那是一个 InProc、存储并且用于本地测试。 这简化了您的测试,但是一旦您的应用程序部署到生产环境中,您就必须处理一个速度缓慢且无法横向扩展的关系数据库。 它非常适合存储,但当您在应用程序中实际需要可扩展性时,它不会横向扩展。

所以,它是一个单一的来源,它可以在极端负载下窒息。

解决方案

解决方案非常简单,您开始使用受干扰的缓存系统,例如 NCache,对于您的 EF 核心应用程序,您可以将它与关系数据库结合使用。

部署架构

下面是部署架构 NCache.

部署架构

首先,它在内存中。 因此,相比之下,它是超快的。 然后你有多个服务器正在存储,这些数据通常让你从后端关系数据源中获取。 您可以将其放入缓存中,它可以是您的 ASP.NET 或 ASP.NET Core 应用程序、.NET 或 .NET、Web 服务或者它可以是 .NET 或 .NET Core 服务器应用程序或任何类型的 .NET 或 .NET Core 应用程序甚至 Java 应用程序都可以利用这种分布式缓存系统。 它可以节省您访问关系数据源的昂贵费用。 它在内存中。 您可以添加更多服务器,并且可以线性方式增加此缓存集群的容量。

因此,这不是单点故障。 这不是性能,瓶颈。 这不是可扩展性瓶颈。 所以,这是推荐的方法,这就是我们今天将详细介绍的内容,如何使用 .NET 缓存,这将是 NCache 通过扩展方法作为 EF Core 应用程序中的示例产品。

3个常用的分布式缓存用例

分布式缓存用例

分布式缓存的一些常见用例。 您可以将其用于数据缓存。 您可以使用直接 API 调用。 或者甚至对 EF Core 应用程序使用实体框架或扩展方法,您可以尽可能多地保存到数据库的行程。

然后在网站上,网站的东西,你有ASP.NET,ASP.NET Core 缓存。 它可以是 Web 应用程序或 Web 服务。 如果它是一个 Web 应用程序,那么如果您可能想要使用会话。 您可能想使用 ASP.NET 和 ASP.NET Core SignalR Backplane, ASP 的响应缓存.NET Core. 同样,IDistributedCache 接口可用,视图状态和输出缓存。 这些都是您的应用程序的无代码选项。

然后,您就有了强大的 Pub/Sub 消息传递。 您可以拥有订阅的主题,然后在不同的应用程序之间共享消息。 发布者和订阅者可以互相发送消息。

所以,这是一个普遍的想法。 今天,我们将更多地关注 EF Core 应用程序中的数据缓存,我将引导您完成简单的入门步骤,然后我们将实际进行更多扩展,分享关于不同场景的越来越多的详细信息。

所以,让我们快速开始吧。

APP 数据缓存:EF 核心实体

我今天要介绍的第一件事是应用程序数据缓存。

什么-ef-core-entities-to-cache

您有一个 EF Core 实体。 因此,需要缓存这些实体。 因此,您可能会看到单个实体。 例如,您有一个计数,总和。 这是一个值,或者你可以,你正在做一些排序,你从中得到第一个客户,或者标准是它返回一个客户、单一产品、单一订单。 那么,这是一个单一的实体,如何缓存它? 同样,我们有查询结果,它可能是实体集合。 所以,它不是一个单一的实体。 它是实体的集合。 有两种选择。 您可以将整个集合作为一个项目缓存在缓存中,也可以将每个集合项目、该集合中的每个实体分别缓存在分布式缓存中。

EF Core 实体缓存选项

所以,让我们来看看这方面的方法。

efcore-实体缓存选项

如前所述,您可以使用直接 NCache 蜜蜂。 NCache API 是一个键值存储,你添加数据到 NCache 你自己,然后你自己从它那里接收,或者你可以使用 EF Core 扩展方法并负责这个,单个实体和实体集合。

所以,让我先告诉你直接 NCache API 方法,适用于所有类型的应用程序。 您可以在 EF Core 中使用它。 您可以在常规 EF 或任何其他 .NET 应用程序中使用它,然后我将讨论专为您的 EF 核心应用程序设计的 EF Core 扩展方法,这使您的生活变得更加轻松,因为它可以自动完成很多事情为您服务,您只需在查询时调用此扩展方法。 因此,我将一一向您展示这两种方法,然后我们将更多地关注未来的扩展方法。

缓存 EF Core 单一实体: NCache 直接 API

因此,我们的第一个示例是缓存 EF Core 单个实体。

Customers GetCustomer (string CustomerId)
{
	string key = "Customer:CustomerId:" + CustomerId;
	Customers customer = (Customers)_cache.Get(key);
	
	if (customer != null)
	{
		return customer;
	}
	else
	{
			customer = (from cust in database.Customers
					where cust.CustomerId == CustomerId
					select cust).FirstOrDefault();
                    _cache.Insert(key, customer);
	
		return customer;
}
}

我们在这里有一个 GetCustomer 方法。 我将在我为此制定的示例应用程序的帮助下向您展示这一点。 所以,这是我们的第一种方法。 我希望你能看到我的屏幕。 所以,我们有获取客户。 它采用了我们的客户 ID,这里的想法是返回一个实体,对吧。 因此,通常使用直接 API,挑战在于您必须考虑或必须自己实现的东西。

首先,您需要有一个密钥,该密钥是您识别内部实体的东西 NCache 并且您需要以相同的格式维护所有密钥。 您可以想出一个示例格式,如屏幕上所示。 有一个客户关键字,然后是客户 ID 和客户 ID 的运行时参数,这些参数构成了缓存键。

In NCache 一切都存储在一个键值对中。 键是字符串键,值是 .NET 允许的对象,它也可以是任何 EF Core 实体,但是您制定键,然后将该实体用作要存储的对象 NCache. 现在,您首先通过调用 cache.Get 来检查该键是否已存在于缓存中,如果您确实直接从缓存中获取该客户,这是直接 NCache API cache.Get,你传递密钥,如果你得到那个客户,你从这里返回代码,如果它不为空。 但是,如果它为空,例如,您是第一次执行该查询,对,缓存中还没有任何内容。 因此,在这种情况下,您将针对 Entity Framework Core 执行针对数据库的 LINQ API,然后从数据库中获取该客户并调用 cache.Insert,使用您制定的相同密钥存储它,然后客户就是您要添加的实体,然后您也将其返回。

因此,这就是您使用正确的 API 实际处理单个实体的方式。

缓存 EF Core 实体集合: NCache 直接 API

然后是收藏。 集合可以是作为单个对象的集合,也可以是作为单个实体的集合。

List<Customers> GetCustomersByCity (string CustomerCity)
{
	string key = "Customers:City = " + CustomerCity;
	List<Customers> custList;
    custList = (List<Customers>)_cache.Get(key);

	if (custList != null)
	{
		return custList;
	}
	else
	{
		custList = (from cust in database.Customers
					where cust.City == CustomerCity
					select cust).ToList();

		_cache.Insert(key, custList);
		return custList;
	}
} 

每个集合条目可以是单独添加到缓存中的单个实体。 因此,为此我们按城市获取客户,这是下一个方法。 它正在返回一个客户列表。 同样,它以客户城市为标准。 同样,您制定了一个密钥。 同样,这是你知道的,这是代表基于城市的客户集合,然后这个城市可能是这里的运行时参数。 纽约,巴黎,伦敦,然后您首先通过调用缓存来获取。自己从缓存中获取,然后检查它是否存在于缓存中,如果它从这里返回,如果不存在,您只需将其存储为单一收藏。

因此,此客户列表存储为一个对象。 其他替代方法可能是您遍历客户实体中的个人客户列表并调用缓存。单独插入,如下所示。 对? 因此,使用直接的单个实体和实体集合 NCache 将使用这些方法缓存的 API。 现在我们已经介绍了直接 API。 这是您可以在任何应用程序中使用的东西。

缓存 EF Core 单个实体:EF Core 扩展方法

让我们关注实体框架核心扩展方法。 因此,与单个实体和实体集合相同,使用 NCache 扩展方法。 所以,我要介绍FromCache。

Customers GetCustomer (string CustomerId)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities
	};
	
	Customers customer  = (from cust in database.Customers
							where cust.CustomerId == CustomerId
							select cust).FromCache(out string cacheKey,
                            options).FirstOrDefault();
	return customer;
}

这是我们的第一个扩展方法,顺便说一下要使用这个扩展方法,首先需要介绍一下 NCache NuGet 包 应用程序内的 Entity Framework Core NuGet 包。 所以,这是必须的。 如果你去安装,这是一个 Alachisoft.NCache.EFCore NuGet 包。 这就是您需要在应用程序中引入的内容,这是一个,然后您所要做的就是,让我打开上下文。 因此,在您只需调用的上下文中 NCacheConfiguration.Configure 并且它采用我从应用程序设置中读取的 cacheID,然后它还采用类型,如果您使用依赖项,这是 Entity Framework Core 扩展方法中的高级功能。 您需要提供数据源的类型。

但是,一旦你打电话 NCache 配置方法,这个方法请求的东西有很多。 您也可以设置一个记录器,仅此而已。 这使您可以开始通话 NCache, 应用程序内的 EF Core 扩展方法。

缓存 EF Core 实体集合:EF Core 扩展方法

所以,你也知道,方法,但这次是通过扩展方法来获取客户。

List<Customers> GetCustomersByCity (string CustomerCity)
{
	List<Customers> custList; 
	CachingOptions options = new CachingOptions
	{	
		StoreAs = StoreAs.Collection
	};
	custList = (from cust in database.Customers
				where cust.City == CustomerCity
				select cust).FromCache(out string cacheKey,
                options).ToList();
	return custList;	
}

这将使一切变得更简单。 您不必自己检查缓存中的数据,也不必自己显式调用 insert,最重要的是,您不必调用,也不必自己构造缓存键。 作为“FromCache”实现的一部分,这是完全自动化的。

现在,从行为的角度来看,这正是我们之前所展示的。 FromCache,首先需要一个缓存选项,选项和'cacheKey'是一个out引用。 因此,它会在幕后为您自动构建缓存键。 您只需要在查询旁边作为扩展方法从缓存中调用,并且您只需传递存储该选项的选项,如果它总是返回一个集合,对吧。 因此,在这种情况下,您可以选择它作为单独的实体或单独的集合,对。 因此,它可以是实体的集合,也可以是该集合之外的单独实体。

因此,FromCache 的工作方式是,如果一个实体或您执行的查询以及这些结果实体已经在缓存中,它将从 NCache 自动地。 但是,如果在这种情况下它们不在缓存中,它将自动对数据库执行该查询并返回结果集,同时它也被缓存,我们还为后续调用附加了数据库上下文。

例如,如果您第一次调用 FromCache,它会缓存它。 下次执行相同的查询时,显然它将针对缓存而不是数据库执行。 这一次你的上下文,如果之前已经处理过,并且对于这个请求,你正在使用 using 构造,如果你在实体中进行了任何更改,也会将这些更改附加到上下文中。 当您调用 Save Changes 时,对从缓存中获取的那些实体所做的所有更改实际上都应用于数据库。 所以,这又是一个稍微高级的概念。 我将在稍后阶段花更多时间,但只是让您知道,from cache 方法的工作方式是,如果缓存中没有某些内容,它将从数据库中获取并缓存它。 但是,如果缓存中已经有可用的东西,它会从那里返回它。 因此,这为您自动化了整个直接的 API 方法,但它也构建了密钥。 它还自动将数据组织在单独的实体或单独的集合中,您只需从缓存中调用并传递 out 键和选项。

集合的情况相同。 对于集合,按城市获取客户。 它将存储为一个集合,然后您可以再次从缓存中调用。 所以,这就是开始使用 Entity Framework Core 扩展方法是多么简单。

在 EF Core 中缓存哪些数据?

我们的下一个主题是,我们的下一个主题再次是关于缓存中数据类型的使用。

在 efcore 中缓存什么数据

您可以拥有参考数据或交易数据。 有问题吗?

是的,罗恩,我有一个问题。 的扩展方法 NCache 使用 EF Core,你推荐 .NET Core 2.0 框架或 .NET Framework?

好的。 因此,由于 EF Core 本身可以在 .NET 以及 .NET Core,所以,它非常灵活。 NCache 扩展方法绝对可以正常工作。 事实上,我正在运行这个示例应用程序 .NET framework 4.6.1 我相信我还有另一个正在开发的示例应用程序 .NET core 2.0。 所以,这是 .NET Core 2.0。 所以,它适用于两者 .NET frameworks,基本上你最好使用 .NET Core,但它很灵活。 它对双方都有效。 我希望这能回答你的问题。

继续,演示中的下一个部分是当您开始计划正确缓存时,显然实体框架核心扩展方法使您的生活在缓存方面变得更加轻松。 因此,它实际上可以自动完成很多事情。 那么,下一个问题是要缓存哪些数据,对吗?

因此,我将数据分为两类。 我们有参考数据。 这是一个查找数据,然后我们有我们的事务数据,这些数据是动态创建的并且变化非常频繁。 因此,参考数据,一个简单的例子就是产品、员工。 这不是 100% 的静态数据,但它不会经常变化。 但是,它确实发生了变化,变化的频率并没有那么大。 为此,您应该计划缓存整个参考数据。 所有的参考数据都应该被缓存,然后事务数据是动态创建的数据。 例如订单、账户、某些特定集合上的某些工作流处理、数据以及该集合的范围仅针对该工作流。 一旦该工作流完成执行,就不再需要该数据,并且该数据也可以非常频繁地更改。 如此之多,它可以在五分钟内改变。 而参考数据通常是可能在几个小时之间变化的查找数据。 1 到 2 小时、5 到 10 小时甚至几天。

我们在这里有一个问题。 在使用 EF 扩展检索时,您将如何识别此缓存对象,就像自动创建的键一样? 实际上,不是检索而是删除特定密钥?

好的。 因此,我们确实有一个用于检索的扩展方法。该扩展方法与 EF Core 一起执行。 因此,返回对象将在您的 LINQ 查询识别它的同一行上被识别。 我认为这个问题更关注当您计划更新记录时会发生什么,为此我们有一组 API。 我们为您提供允许您针对实体生成密钥的方法。 我们公开了一种密钥生成方法。 因此,在直接对缓存进行更改之前,我假设这个问题更侧重于删除缓存中的某些内容或更新缓存中的某些内容,或者明确删除或添加缓存中的某些内容。 我们已经公开了缓存类,稍后我将向您展示,然后是密钥生成。 同样,您传递一个字符串,使用 out 引用,您也传递实体。 因此,针对该实体,我们使用相同的方法,我们会给您一个密钥,使用该密钥您可以识别该实体的对象,如果它存在于缓存中,您应该能够更新它并删除它。

我想最后我会向您展示如何实现这一目标的示例,但只是为了让您知道,我们接触过一些方法,从 NCache 也是。 我希望能回答你的问题。

在 EF Core 中缓存引用数据

继续。 所以,我们已经讨论了查找数据,然后是动态创建的数据。

ef-core 中的缓存参考数据

所以,我将一一介绍不同的方法来处理这个问题。 因此,首先我们将讨论 EF Core 中的引用数据。 正如我所提到的,这通常是一个查找数据。 所以,有两件事是你必须做的。 您应该首先将整个数据、整个参考数据加载到缓存中,这是必须的,这里的动机是这些数据不会经常更改。 它是电子商务应用程序中 EF 中的产品目录。 某些产品有一些折扣,而该折扣已启用,比如说三天。 这些产品可能不会改变,因此,最好将所有这些产品缓存到 NCache 并尽可能多地节省昂贵的数据库旅行。 100%,数据应该加载到缓存中。 因此,您不必返回数据源,然后始终将它们缓存为单独的实体。 为什么? 因为产品,整个数据集可能是成千上万的产品。

比方说,Northwind 数据库。 产品的范围可以从 50,000 到 100,000 种产品。 但是,对于给定的请求,您可能只需要其中的 10 个或其中的 100 个。 因此,如果将它们存储为单独的实体,则可以运行 LINQ 查询。 NCache 还支持 LINQ NCache 直接地。 因此,您可以在获取数据子集时运行 LINQ,查询实体子集 NCache 以及。

因此,这是您必须遵循的两条规则,我有一个示例,在这里我将介绍我们的第二个扩展方法,称为加载到缓存中。

在 EF Core 中缓存引用数据:预加载缓存

现在,它以这种方式工作,并且仅针对参考数据。 这是缓存中的预加载器。

void LoadAllProducts (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities,
	};	
	
	// Loads all products into cache as individual entities
	var res = (from products in database.Products select
    products).LoadIntoCache(options).ToList();
}

所以,这里的动机是你应该调用这个方法,比如说加载所有产品,你应该确保你将它存储为一个单独的实体,你应该运行一个查询,它说来自数据库产品中的产品并选择产品. 因此,您没有指定任何标准,这意味着这会将所有 60,000 个产品加载到缓存中,然后您正在使用 LoadIntoCache,对。 当您说单独的实体时,您只需要传递此选项,我们将为缓存中的每个产品创建一个单独的实体,这又是一个预加载器,对吧。 你应该预加载这个..

有两种选择。 您可以为此运行一个单独的应用程序,该应用程序可以负责预加载缓存。 这可能是应用程序启动或单独的应用程序,也可能是缓存加载器实现 NCache 也是。 有一个缓存加载器,并且在未来的版本中也正在处理缓存刷新器。

缓存加载器的职责是它实际上在您的缓存启动时运行,然后它确保您要加载到缓存中的所有数据都作为其中的一部分加载。 这是你的实现,但是 NCache 简单地调用它。 但是,就像我提到的那样,您可以提出这样的方法,并确保您在应用程序启动时调用它一次,或者让一个单独的应用程序执行此操作并在所有应用程序实例之间共享此数据。

现在一旦完成,如何从缓存中查询数据以及此时。 我将介绍我的第三种扩展方法,即 From Cache Only。

在 EF Core 中缓存引用数据:仅从缓存中搜索引用数据
List<Products> FindDiscontinuedProducts (NorthwindContext database)
{
	//Fetch discontinued products only out of all products 
	List<Products> discontinuedProducts;
	
	discontinuedProducts = (from product in database.Products 
   	 where product.Discontinued == true
   	 select product).FromCacheOnly().ToList();
	
	return discontinuedProducts;

}

所以,第一个扩展方法是 FromCache,如果缓存中有东西,从那里获取它。 如果不是,则自动转到数据库并获取它。 LoadIntoCache 始终针对数据库执行。 尽管它正在返回,但它永远不会针对缓存执行,但这是必须从数据库返回的,以便刷新数据集。 加载了一个新数据,然后它也在缓存它,然后 FromCacheOnly 只针对执行 NCache 因为这只是为参考数据而设计的。 因此,对于参考数据,您将使用 LoadIntoCache 的组合。 这样所有数据集的数据作为单独的实体存在于缓存中,然后您将调用 FromCacheOnly 以便只有您感兴趣的数据集,在这种情况下已停产的产品仅从缓存中带来。 因此,您根本不必访问数据库。 我将讨论如何在数据库中的数据发生变化时保持这些数据的最新状态。 所以,我希望这是有道理的。 让我在这里向您展示这个示例。

所以,我在这里调用这个方法,然后我返回一个产品列表,使用简单的 EF 停产的产品,LINQ API 直接在 NCache 实体。

因此,这根本不会针对数据库执行。 这只会针对缓存执行,因为我使用的是 FromCacheOnly 扩展方法。 我希望这有帮助。 我们已经介绍了三种扩展方法,FromCache 更多的是事务数据用例,然后我们介绍了 LoadIntoCache 和 FromCacheOnly。 对于参考数据,您应该专注于使用 LoadIntoCache 使用整个数据,然后使用单独的实体,然后对于查询,您应该使用 FromCacheOnly。

在 EF Core 中缓存事务数据

接下来,我们将讨论事务性数据,然后我们将讨论如何使这些数据保持最新,以供参考和事务性使用。

在 efcore 中缓存事务性数据

现在,事务数据通常是一个工作集。 我已经介绍过它是一个动态创建的数据。 只有当前用户、当前请求或正在执行的工作流才需要它,一旦执行,您可能不再需要该数据。 因此,只有实际检索数据的应用程序实例才有可能只有该应用程序实例才需要这些实体。 因此,将所有事务数据存储在缓存中是没有意义的。 这不是一个要求。 您应该只缓存工作集。 所以,这是第一步。 因此,您应该缓存查询结果。 您可以获取最容易访问的实体,第二步是有两个选项 2a、2b。

获取并缓存为集合

您可以将事务数据缓存为整个集合。 这是首选方法。

List<Orders> GetCustomerOrders (string CustomerID)
{
	CachingOptions options = new CachingOptions	
	{
		StoreAs = StoreAs = StoreAs.Collection,
	};

	//Fetch from cache. If not found then fetch from DB.
	orderList = (from customerOrder in database.Orders 
				where customerOrder.Customer.CustomerId==CustomerID 
				select customerOrder)
				.FromCache(out string cacheKey, options).ToList();
	
	return orderList;
}

通常您总是需要整个集合,因为您正在处理它,然后您还可以存储单独的实体。 这完全取决于您,这适用于尽管您缓存了一个集合但仍将其存储为单独实体的情况,因为您可能只需要该集合中的两个或三个实体。 因此,在存储集合时最好采用细粒度的方法,我们有 GetCustomerOrders。 订单是非常具有交易性的数据。 必须有一个处理单元来处理某些订单,并且每个正在执行此操作的工作流都有自己的一组订单。

因此,我将快速向您展示这个示例。 所以,它以这样一种方式工作,它提供了很多缓存选项。 让我们实际上不在这里详细介绍。 作为收藏品存储。 这就是您选择将其存储为集合的方式,然后我使用 FromCacheOnly。 事务数据的原因,我使用 FromCache 因为数据可以存在于缓存中,如果它包含整个集合,我只需要使用它。 我不必去数据库。 但是,如果它在缓存中不存在并且该数据也经常更改,我们还为其设置了过期时间,例如 30 秒,因此您可能希望返回数据库。 如果使用 FromCacheOnly,如果缓存中不存在,如果它已经过期,则可以返回 null 值。

因此,对于事务数据使用扩展方法 From Cache,对于参考数据使用 LoadIntoCache 预加载,然后使用 FromCacheOnly。 所以,这就是解决问题的方法。

作为单独的实体获取和缓存

对于单独的实体,您所要做的就是存储,调用它。

List<Orders> GetCustomerOrders (string CustomerID)
{
	CachingOptions options = new CachingOptions	
	{
		StoreAs = StoreAs.SeperateEntities
	};

	//Fetch from cache. If not found then fetch from DB.
	orderList = (from customerOrder in database.Orders 
				where customerOrder.Customer.CustomerId==CustomerID 
				select customerOrder)
				.FromCache(out string cacheKey, options).ToList();
	return orderList;
}

让我使用它,而不是使用单独的实体,只是说,(我必须评论应该评论)对,存储为单独的实体。 这就是你需要做的。

所以,罗恩,当你讨论这个问题时,有一个问题。 在前面的例子中,查询参考数据,有没有索引? 因为,只有这才是你在数据库上要做的事情……。

绝对,这是一个非常好的问题,对于参考数据,因为它只针对缓存执行,所以这个 LINQ 查询要求你的产品和属性是你运行 LINQ 查询的索引,事实上我是使用索引数据,索引非常简单,你只需要提供类型,模型,然后提供你需要索引的属性。 因此,这些是索引属性,我们确实在针对索引属性运行查询。 我希望这能回答你的问题。

保持缓存新鲜

我将快速进入我们的动手部分,向您展示实际的产品,然后是本次网络研讨会最重要的部分,与数据库相比如何保持缓存数据的新鲜度,以及参考数据和交易数据。

好的,所以我要打开一个新项目。 好的,所以,动手演示部分我将快速向您展示实际的产品,以便您了解分布式缓存的外观,然后我们将针对它运行应用程序,我将向您展示如何保持它是新鲜的,数据和缓存也是新鲜的。

我已经安装了 NCache 在我的两个盒子 107 和 108 上。我将在此处将它们用作我的缓存服务器和我的个人计算机,我的笔记本电脑将充当客户端。

所以,首先我将启动 NCache 附带安装的管理器工具 NCache 我将创建一个缓存,比如说,我们将其命名为 EF Core 缓存。 我将使用两台服务器。 保留分区副本作为我们的缓存拓扑,然后是异步复制选项,因为它更快,在这里我指定了将托管我的缓存的服务器。 所以,我有两台服务器,演示 1 和演示 2 以及用于通信的 TCP/IP 端口。 就服务器和客户端之间的通信而言,一切都是由 TCP/IP 驱动的。

缓存的大小,基于您计划缓存的数据。 如果它是参考数据,您应该考虑到您正在加载所有产品,所有客户。 同样,如果它是事务数据,您需要考虑工作集和更多空间。 保持一切简单,选择完成,就是这样。 上手就是这么简单 NCache 并配置缓存。

因为,我在我的机器上运行应用程序,所以我只需要将我的盒子添加为客户端机器。 我可以启动并测试这个缓存集群,然后我就可以运行示例应用程序来连接它了。 就是这么简单。 我们有一个定期 NCache 架构和扩展 .NET 应用程序网络研讨会,我们将在其中详细讨论这些配置。 因此,如果有任何问题,您可能还想查看这些网络研讨会。

我还将向您展示一些监控方面。 统计窗口,然后我会打开 NCache 监控工具,这样我就可以实际运行随附安装的压力测试工具应用程序 NCache 并查看实际情况。 所以,这是一个压力测试工具。 我将针对它运行它,因为我的盒子是一个客户端,所以我可以简单地提供名称,它应该连接到这个,我应该能够在我的缓存集群上模拟一些虚拟负载,你去吧。 缓存大小正在增长,正在添加项目,每秒负载的请求也显示两台服务器上的活动,然后是这个监控工具,我认为这需要时间,它正在创建仪表板。

压力测试工具

所以,让它滚动,同时让我从服务器本身运行这个工具的另一个实例。 我的错。 好的,所以,您可以看到每秒请求数量的增加。 由于某种原因需要一些时间来加载仪表板,监控工具。 我想我一回来就把它放在这里我会向你展示这个工具的监控细节。

保持缓存新鲜:参考数据

好的,我们在本次网络研讨会中的下一部分是在 Entity Framework Core 应用程序中保持缓存数据的最新状态,为此我将再次使用参考数据和事务数据示例。 因此,我们将从参考数据开始。

保持缓存新鲜参考数据

我们已经确定,为了缓存参考数据,您应该在缓存中缓存整个数据集。 例如,您有产品,您应该将所有产品加载到缓存中,然后将它们作为单独的实体加载。 那么这有什么问题呢?

因为,引用数据,整个引用数据都在缓存中,然后你只使用使用 FromCacheOnly 扩展方法的缓存。 现在,您不想从缓存中获得部分数据集。 如果它是已停产的产品或者您正在运行某些标准,则您希望所有这些产品都在缓存中。 但是,这些产品有可能在数据库中实际发生变化。 现在数据存在于两个不同的地方。 您拥有作为主副本的数据库,尽管您在缓存中加载了整个数据,但仍有可能在应用程序范围之外更新数据库。

因此,为了使缓存数据保持最新,您需要确保有某种机制可以自动更新数据和缓存,为此我们有两种选择。 第一个选项是您使用到期。

void LoadAllProducts (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities,
	};
	
	options.SetAbsoluteExpiration(DateTime.Now.AddHours(10)); 	
    options.SetResyncProviderName("MyEFCoreResyncProvider");
	
	// Load all products into cache with Expiration and Auto-Reload
	var res = (from products in database.Products select
    products).LoadIntoCache(options).ToList();

}

这是一个基于时间的到期,然后你将它混合起来,你将它与自动重新加载功能一起使用。 NCache 过期功能允许您使数据过期,在指定时间段后删除数据,例如 5 小时、10 小时和参考数据,因为它很长,运行数据它是查找数据、主数据,因此更改频率不是太好了,所以你可以想出一个舒适的数字,小时数,或者你知道,可能是 5 小时、10 小时、24 小时。 因此,基于此,您可以设置到期时间。 但是,正如前面提到的,您并不想从缓存中丢失或删除该数据。

您真正需要的是更改的数据,例如,根据您指定的到期时间,有 10 个产品已过期,它应该使用自动重新加载机制自动将该数据重新加载到缓存中。 和 NCache 在通读处理程序的帮助下为您提供。 因此,您所要做的就是再次将整个数据和缓存加载到缓存中,使用单独的实体,但同时使用这些特征。 例如,设置绝对过期。

这是您将设置为所有产品的到期值,这些产品将被加载到缓存中,然后您设置重新同步提供程序,它本质上调用您的通读提供程序 NCache. 通读与到期相结合。 因此,它实际上是重新加载而不是从缓存中删除数据,因为它知道所有键和所有与数据库相关的信息,我们只需要您传递上下文并基于该上下文,我们实际上将您的提供者称为自动和重新同步。 我们从数据源中获取更新的值。

让我向您展示一个工作示例。 这是一个方法。 我将其存储为单独的实体。 通常情况下,我会设置 5 小时的到期时间,但由于我们没有那么多时间,所以,我真正要做的是设置大约 30 秒的到期时间,我会在此处放置一个断点,然后我会加载所有产品进入缓存。 我此时不会设置重新同步提供程序,只是为了向您展示过期的工作原理,一旦过期开始播放,它将从缓存中删除项目,然后我将向您展示如何处理这种情况以这样的方式,而不是删除,只需使用通读处理程序重新加载。

所以,我将使用本地缓存作为这个示例位。 为了安全起见,我将清除内容,然后运行这段代码并命中断点。 对。 所以,它有 30 秒的到期时间,我会打,我得到了停产的产品,对吧。 所以,我们这里有所有的产品,我们这里有大约一千个条目。 30 秒后,这千个项目将根据这个绝对过期时间过期,我们设置的标志,我将再次运行此查询,您会看到它不会返回任何内容,因为缓存中不存在任何内容。 它仅使用来自缓存。 所以,我们有物品过期了。 我会再运行一次,你会注意到我得到了 0 值。

因此,这不是推荐的或首选的,考虑到这是您的参考数据,整个数据已经加载到缓存中并且您正在调用 From Cache Only 扩展方法。 因此,您需要所有可用的数据,而不是部分响应或丢失的数据,同时应该在到期后重新加载。 而不是删除它应该重新加载,这正是我们将在此 Set Resync Provider 名称的帮助下所做的事情。

我有一个示例重新同步提供程序,就在这里,IReadThruProvider。 它的真正作用是,我们为您提供了一个默认实现。

namespace Alachisoft.NCache.EFSampleResyncProvider
{
    public abstract class EFDefaultResyncProvider : IReadThruProvider
    {
        public virtual void Init(IDictionary parameters, string cacheId)
        {
            db = InitializedDbContext();
        }
        public virtual void LoadFromSource(string key, out 					
        ProviderCacheItem cacheItem)
        {
            cacheItem = new ProviderCacheItem(FetchItemFromDb(key));
            cacheItem.AbsoluteExpiration = DateTime.Now.AddHours(10);
            cacheItem.ResyncItemOnExpiration = true;
        }
        public virtual void Dispose()
        {
            db.Dispose();
        }
    }
}

这是我们的 IReadThruProvider。 您所要做的就是,让我们在我们配置的缓存的帮助下展示这一点。 您必须设置通读处理程序。 比如让我新建一个缓存,让我新建一个本地缓存。 对。 所以,它只是一个本地缓存。 我将设置一个支持源。 启用通读,添加并假设 EF 默认值,这需要设置,我可以将其用作项目并且实施已经完成。

它的工作方式是我实现了 IReadThru 处理程序。 这是默认的重新同步提供程序,对。 它有一些方法。 它具有初始化数据库上下文的位置。 LoadFromSource 在到期时调用,在其中我从数据库中获取项目。 如果我进入定义,它实际上会处理所有与数据库相关的调用,这是我们作为实现的一部分提供的东西。 我们的 NuGet 包将其作为其中的一部分进行了涵盖。 因此,我们正在获取密钥并基于该密钥传递上下文,并且上下文用于直接从数据库中获取实际对象。

您所要做的就是知道、继承、​​实现这个 EF Default Resync Provider 并提供您自己的实现并为我们提供数据库上下文。

所以,这是我们给你的一个抽象类。 您只需要提供您的 Northwind 数据库上下文或您拥有的任何数据库上下文,并且基于此,一旦此方法被覆盖/实现,您只需将其注册到您的缓存中。 例如,这是一个重新同步提供程序。 如果我打开它,它包含其中两个。 一个是默认的,另一个是您的实现,如果需要,您可以传递连接字符串和其他信息,仅此而已。 您只需部署它。 让我把它带到这一点,它只会让你在这方面取得成功。 所以,必须这样做。 就像我提到的那样,这已经作为 NCache, 执行。 它有,NuGet 包附带一个重新同步提供程序,您可以通过在此处实现此特定方法并为我们提供上下文来简单地实现它,其余工作由此示例默认重新同步提供程序完成,它实际上与扩展在相同的行上工作方法起作用。

我们构建您的密钥,因此我们知道哪个密钥代表哪个实体,并基于该实体以及我们使用实体框架 API 实际查询数据库的密钥信息。 现在这已经为我的缓存完成了。 我在这里所做的是我有,它已经成功部署。 所以,对于我的缓存,我已经这样做了。 我有这个 EF 默认值并且我已经部署了它。 因此,我将运行相同的用例,但这次我不是简单地使它过期,而是实际上重新加载它。 所以,这就是我要做的。 我所要做的就是设置他们的重新同步提供程序名称,然后因为我也计划更新一些值,所以我将使用 60 秒。 通常,对于参考数据,您将有更多的时间指定为绝对到期时间,例如 5 小时甚至更多。 所以,我将只运行 60 秒,这一次我看到我的重新同步提供程序已设置。

所以,我将再运行一次这个用例,并向您展示它是如何更新而不是过期的,而不是删除。 所以,这已经运行了,希望它会回到这一点。 好的。 所以,我们已经加载了产品。 我将再运行一次,这次,由于它有 60 秒的有效期,我将更新这个特定的产品,产品 ID 17 我们要做的就是说更新它,好吧。

虽然它在数据库中更新了,但它还不会在应用程序上下文中更新,因为它只使用缓存数据并且还没有过期。 因此,我们将继续获取较旧的值,如果您注意到我的缓存中有数千个项目并且存在 Readthru/sec,这将在 60 秒后显示一些活动,然后它会自动调用我们拥有的通读处理程序刚刚设置。

所以,让我再运行一次,我期待订单值再次,如果还没有重新加载,但会有一个点它会重新加载,之后它会简单地而不是过期它只会重新加载 999产品。 有一个项目是额外的,通常是参考。 你去吧。 所以,不是过期,只有一个项目过期了,因为那是一个键列表,否则,所有基于我的查询的参考数据,让我向你展示查询,它说产品 ID 小于 1000。所以,实际上代表 1000 种产品。

因此,我将再运行一次此查询,这一次是因为数据已在到期时更新,而不是删除。 因此,我希望将更新的产品添加到缓存中。 所以,你去吧。 因此,我的产品已作为其中的一部分进行了更新。 因此,这是我们推荐的选项之一,即您使用到期但具有自动重新加载功能。 因此,您只需重新加载数据而不是到期,这将负责保持缓存数据的最新状态。 因此,您想出了一个舒适的时间,允许您将数据保留在缓存中,您会不断获取旧数据,并且一旦旧数据即将过期,这可能是一天的时间,比如说 24 小时,可以是 2 天或一周,以您的应用程序中的舒适时间为准。 也可能是几个小时,之后它只会重新加载缓存中的数据。

所以,这是我们的第一选择。 我希望这很简单。

选项二是您不使用到期时间。 所以,这只会解决这个问题,因为数据总是存在于缓存中。 但是数据在缓存中可能是陈旧的,并且可能永远是陈旧的。 为此,您应该手动重新加载,这也很简单。

void LoadAllProducts (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities,
	};
		
	var res = (from products in database.Products select
    products).LoadIntoCache(options).ToList();

}

您所要做的就是,您只需在定期间隔后调用此加载所有产品。 例如,如果我们回到这里。 所以,这个方法需要在一段时间后再次调用,如前所述,这通常是在您的应用程序启动时完成的,它可能是负责它的应用程序之一,它正在处理所有这些。 因此,它可能是那个,也可能是其中一个应用程序,一个正在执行此操作的单独应用程序。 因此,它可能是您的应用程序、您的应用程序实例之一,也可能是一个单独的应用程序,并且该应用程序可以在 5 小时、24 小时之后定期调用此方法,这也是您想要的舒适时间这将针对数据库执行,并且您希望重新加载您的产品。

因此,LoadIntoCache 将负责针对数据库执行并将新副本加载到缓存中的特定场景。 因此,这就是您负责参考数据的方式。 我希望我很直截了当。

保持缓存新鲜:事务数据

让我们继续下一个我们使用事务数据的部分。 现在交易数据是短暂的,对吧。 如前所述,这是一个工作集。 因此,您可以使用 5 到 10 分钟的到期时间。 因此,您在这里真正需要做的是,因为您使用的是针对缓存执行的 FromCache,如果它存在于缓存中并且如果它不存在于缓存中,它将始终自动针对数据库执行它。 因此,这是内置在此扩展方法中的,与您在参考数据场景中使用的 FromCacheOnly 不同,它仅针对缓存执行。 因此,无论您将其存储为集合还是单独的实体,都有一些可用数据是可以的。

有效期短,无自动重新加载
 private List<Orders> GetCustomerOrders (string CustomerID)
{
	CachingOptions options = new CachingOptions	
	{
		StoreAs = StoreAs = StoreAs.Collection
	};
	
	options.SetAbsoluteExpiration(DateTime.Now.AddSeconds(60));

    	List<Orders> orderList = (from customerOrder in database.Orders 					
        where customerOrder.Customer.CustomerId==CustomerID 
        select customerOrder).FromCache(out string cacheKey,
        options).ToList();

	return orderList;
 }

因此,您只需使用较短的到期时间,比如说 60 秒,尽管我使用该示例作为参考数据,但那是为了这个特定的演示,但对于参考数据,您通常有 5 到 10 小时的到期时间,而对于交易数据,您有介于 60 秒或相关的某个位置,附加到它的到期时间,并且由于您使用的是 From Cache,让我们实际看一下 Get Customer Orders,因为您使用的是应该允许您使用的 FromCache,让我们实际上把它当作例子。

对,所以,你在这里设置了一些过期时间,然后调用这个 FromCache 扩展方法,如果它在缓存中不存在,那么它应该负责从数据库中获取它,并且一段时间后你的工作集是否处于活动状态您可以从缓存中获取缓存,如果它在缓存中不活动,则可能不再需要它,对吧。 因此,您最终可能会回到数据库,而这对交易数据来说是正确的。 所以,我希望这涵盖了我们的参考数据以及事务数据场景,以及如何保持缓存数据在这两个方面的最新状态。

处理缓存中的关系

我将继续我们的下一部分,即处理缓存中的关系。

罗恩,我有几个问题。 是否 NCache 或者缓存的项目是否驻留在 NCache 服务器还是它们在每个应用程序服务器中都被隐藏?

他们居住在 NCache. 对,所以这些项目实际上存在于 NCache, 对。 因此,实际的存储库维护在 NCache 我们实际上在这些实体方法旁边构造了键和对象。 所以,这就是这里的想法。

另一个问题是,当我们将引用数据添加到缓存时,我们可以配置多个缓存加载器还是需要将它们全部配置为一个?

您可以,因为加载到缓存是一种通用方法,对。 因此,它实际上加载了您计划正确运行的查询。 因此,它与查询绑定。 您可以将多个加载到缓存中,并且可以有一个单独的应用程序,也可以是应用程序中的不同位置。 因此,它在这方面也非常灵活。

处理缓存中的关系:一对多

List<Region> GetRegionWithTerritories(NorthwindContext database)
{
	List<Region> regionDetails;
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities
	};

	regionDetails = (from region in database.Region select region)
					.Include(region => region.Territories)
					.FromCache(options).ToList();

	return regionDetails;
}

我想强调几个重要的概念。 如何处理人际关系? 一对多,你知道,多对多的例子。

让我们专注于一对多。 如果您说地区,那么地区是地区的一部分,地区和地区之间存在一对多的关系。 让我们进入同步方法和内部,实际上让我们从这里获取区域。

好的,所以,获取具有领土的区域。 这里的基本思想是你有 Include 关键字,然后你使用 FromCache 并且你总是将它存储为一个单独的实体。 这里的想法是,该区域的父项将作为单独的项存储在缓存中。 因为,区域也与领土具有一对多的关系,并且每个区域实体内部都有一组领土,所以, NCache 会服从的。 只要您调用 FromCache,它就会简单地获取区域,并且所有区域都存储为单独的实体,并且基于您指定的范围,并且在 FromCache 的帮助下所有区域都将作为单独的集合存储在每个区域内.

所以,它是一个实体,它有很多方面,集合方面是一个相关的对象。 因此,这就是您处理一对多用例的方式。

缓存聚合操作

然后你有缓存聚合操作。 您知道,您可以生成一个实体或生成一个值。

缓存聚合操作

例如,获得第一或默认托运人,对。 所以,就是这样,比方说,如果我只是在这里做一个 First 或 Default ,这会给我带来第一个托运人,然后你知道基于这个,这将被存储在 NCache.

同样,它可以是计数和。 它可以是任何聚合操作,所以它可以是一个值。 同样,这可以存储在 NCache 作为一个单独的实体。

Shippers GetFirstShipperInstance (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{ 
		StoreAs = StoreAs.Collection
	};

	Shippers shipper = database.Shippers.DeferredFirstOrDefault()
						.FromCache(out string cacheKey, options);

	return shipper;

}

同样,它可以是计数和。 它可以是任何聚合操作,所以它可以是一个值。 同样,这可以存储在 NCache 作为一个单独的实体。

int GetTotalShippersCount (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.Collection 
	};

	int count = database.Shippers.DeferredCount()
				.FromCache(out 	string cacheKey, options);
	
	return count;

}

分布式缓存架构

因此,就技术部分而言,这涵盖了我们的网络研讨会。 最后,我将向您展示一些分布式缓存架构。

高可用性

NCache 作为一个产品,它非常、可扩展、快速。 它是基于协议中的点对点架构的东西。 没有单点故障。 您可以从正在运行的缓存中即时添加或删除服务器。 您不必停止缓存或任何连接到它的客户端。 因此,您可以动态地更改正在运行的缓存集群。

高可用性

缓存拓扑

那么我们最流行的拓扑是 分区副本缓存. 这允许您以分区的形式简单地将数据分布在所有服务器上。 因此,他们将内存资源、计算资源汇集在一起​​,为您提供逻辑容量,并且每个服务也有一个备份。 Server1 是 2 上的备份。Serve2 是 1 上的备份,Serve3 是 Serve1 上的备份。 因此,以循环方式,每台服务器在另一台服务器上都有备份。

缓存拓扑

客户端缓存(靠近缓存)

同样,这是非常快速、非常可扩展、最流行的拓扑。 你也可以拥有一个 客户端缓存 它可以在您自己的应用程序盒上运行。 它是一个本地缓存,但它与服务器缓存同步。 数据的子集将自动带入缓存,无需任何代码更改。 如果您的数据主要是参考性质,这会提高您的性能。 因此,一旦加载到缓存中,然后通过调用 FromCacheOnly 客户端缓存开始调用此数据子集,在这种情况下确实会有所帮助。

客户端缓存

缓存的广域网复制

广域网复制 另一个特点是桥接复制。 您可以拥有主动-被动或主动-主动数据站点。 所有数据、EF Core 数据、ASP.NET 会话或常规数据都可以通过 WAN 以主动-被动或主动-主动方式传输到目标站点。 所以,这就是 NCache 覆盖作为它的一部分。

万复制

结论

重申一下,在我把它交给尼克之前,我会再花一分钟时间。 因此,我们讨论了使用直接 API 的单个实体和存储实体集合。 这在扩展方法方面略有不同,然后我们讨论了扩展方法,它们本质上非常简单,你知道,本质上也更灵活。 FromCache 是第一个从缓存中获取某些内容(如果存在)的方法,如果不存在,它会自动从数据源中获取它,这与您必须自己实现它的直接 API 不同。 它还构建您在此处设置的键和相关选项。

然后我们讨论了参考和交易数据。 为了处理参考数据,您需要使用 LoadIntoCache 加载整个数据,并且您应该调用 FromCacheOnly。 LoadIntoCache 总是针对数据库执行,然后您知道,FromCacheOnly 仅针对缓存执行,然后我们讨论了您可以在 FromCache 的帮助下处理的事务数据,并且您设置了一些过期时间。 参考数据,为了保持新鲜,您需要使用过期时间,然后使用自动重新加载或不使用过期时间,然后使用 LoadIntoCache 手动重新加载。 然后我们讨论了您需要提出的事务数据,某种过期并使用 FromCache 以便如果它存在于缓存中,您可以获取它。 如果它在缓存中不存在,您总是从数据库中获取它。

至此,我们的演示结束。 如果有任何问题,请告诉我。

您可以随时联系我们 support@alachisoft.com. 如果您有任何技术问题,您也可以通过以下方式联系我们 sales@alachisoft.com. 如果你想看看,下载产品,你可以去我们的网站 alachisoft.com,你可以下载 NCache 它附带 30 天试用版,您可以使用,如果有任何问题,请告诉我们,否则,非常感谢您参加今天的这个节目,网络研讨会,我们下次再见。 非常感谢罗恩。 谢谢你们。

接下来做什么?

 

联系我们

联系电话
©版权所有 Alachisoft 2002 - 版权所有。 NCache 是 Diyatech Corp. 的注册商标。