随着高流量应用的快速增长,可扩展性是这个时代的需要。 由于这个原因,分布式缓存系统已经进入了当今应用程序的核心和灵魂。 NCache – 领先的 .NET 应用程序分布式缓存也不例外。
当我们通常考虑缓存系统时,自然会认为它是易失性和非持久性的,如果缓存重新启动,缓存中存储的任何数据都将不再可用。
假设一家在线电子商务商店每天有成百上千的用户交易,将其所有数据保存在分布式缓存中,这导致用户必须以非常快的速度访问这些数据。 电子商务商店希望将其所有数据保存在非易失性分布式缓存中,并且即使缓存由于任何不可预见的情况而崩溃或重新启动,也能保留数据。
我们有一个解决方案,使用 NCache的服务器端部署来修改您的缓存并使其持久化。 您可以在 GitHub 上找到解决方案 NCache 持久缓存. 此解决方案使用 Read-Thru 和 Write-Thru 提供程序将缓存的行为更改为持久缓存。 持久缓存绝不是常规数据库的替代品,而只是使其更快、更易于访问的扩展。 它可以使用 NET 的两个领先的数据库系统 SQL 和 Cosmos DB 来实现,而无需任何额外的代码。 让我们更详细地看看这个。
运用 NCache持久缓存的特性
NCache 持久数据存储使您能够存储更长的时间跨度的数据。 通常,数据存储在具有预定义到期时间的持久存储中,或者直到应用程序发送删除命令。 持久性存储位于分布式缓存之外,存储在缓存中的任何数据都将自动保存在持久性存储中,以便在缓存由于其易失性而被清除时可用。 在应用程序发出的每个读取请求中,如果缓存中没有请求的数据,则缓存将自动从持久存储中检索条目,并且不会丢失缓存数据。 如图 1 所示:
NCache 持久化存储为您提供以下服务器端部署功能,以确保在缓存中存储的数据不可用时事务的顺畅和无缝。
- 持久启动加载器: 每次缓存启动时,此提供程序都会将数据从持久存储加载到缓存中。 在缓存中进行的每次写入操作都会更新持久存储,并且每次缓存重新启动时将所有持久数据加载到缓存中。 因此,即使在整个缓存集群因任何原因关闭然后重新启动后,缓存数据也不会丢失。
- 持久写入提供程序: 当您向持久缓存写入内容时,会自动调用此提供程序。 它复制写入持久存储的内容,以便在缓存重新启动时仍然可用。有 2 个选项可用于配置此提供程序 - Write-Thru 和 Write-Behind。 这些允许用户在后台进行复制或在写入操作之前进行复制。
写阈值u,在每次写入操作时,数据同时保存到持久存储中,然后将控制权交还给应用程序。
后写, NCache 将操作排入队列并在后台执行,在执行数据库操作之前将流返回给用户。 - 持久读取提供程序: 如果用户需要缓存中不可用的数据,则会调用此提供程序。 使用 Read Through 提供程序的缓存集群将从持久存储中获取此数据并将其保存到缓存中。
持久性 WriteThru 提供程序的快速示例
让我们看一个快速示例,说明如何使用持久缓存 NCache. 在本例中,我们将使用 WriteThru 提供程序. 当用户将项目添加到缓存中时,会调用与缓存服务器一起部署的直写提供程序,同时将项目保存在持久数据存储中。 现在,如果缓存关闭或未使用 Write-Thru 从缓存中删除项目,该项目将从缓存中删除,但不会从持久存储中删除; 数据不会丢失,因为它将在持久存储中。 当需要该项目时,它将从持久存储中提取到缓存中。
这是显示 Write-Thru 提供程序接口的基本代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class PersistenceWriteThruProvider : ProviderBase, IWriteThruProvider { public OperationResult WriteToDataSource(WriteOperation operation) { OperationResult operationResults = new OperationResult(operation, OperationResult.Status.Success); switch (operation.OperationType) { case WriteOperationType.Add: var items = new Dictionary<string, ProviderItemBase>(); items.Add(operation.Key, operation.ProviderItem); _persistenceProvider.Add(items); break; // Update and remove cases are similar and need to be handled } return operationResults; } } |
以下是如何在启用 write-thru 的情况下将项目插入缓存,以便它利用您部署的 write-through 实现:
1 2 3 4 5 6 |
// Enable write through for the cacheItem created var writeThruOptions = new WriteThruOptions(); writeThruOptions.Mode = WriteMode.WriteThru; // Add the item in the cache with WriteThru enabled CacheItemVersion itemVersion = cache.Insert(key, cacheItem, writeThruOptions); |
持久性 ReadThru 提供程序
假设应用程序需要缓存中的一些数据。 此数据以前存储在缓存中,但由于某种原因不再可用。 通常,如果用户尝试访问此类数据,缓存将返回空值,因为缓存不包含所需的数据,并且必须编写包含查询的附加代码才能从数据库中获取数据。 这将导致应用程序逻辑变得过于复杂。 首先在缓存中搜索所需的项目,如果不可用,请检查数据库,然后加载数据。
当我们使用 NCache 持久性数据存储,从缓存中删除的数据仍将存储在持久性数据存储中,并且缓存将调用 读通提供者 实现,数据将在缓存中调用并返回给用户。 因此,即使它已从缓存中删除,您现在也将获得所需的数据,而无需额外的代码。
这是显示 Read-Thru 提供程序接口的基本代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class PersistenceReadThruProvider : ProviderBase, IReadThruProvider { public ProviderCacheItem LoadFromSource(string key) { return (ProviderCacheItem)(_persistenceProvider.Get(new string[] { key })[key]); } public ProviderDataTypeItem LoadDataTypeFromSource(string key, DistributedDataType dataType) { ... } public IDictionary<string, ProviderCacheItem> LoadFromSource(ICollection keys) { ... } } |
您可以在启用读取的情况下从缓存中获取数据,因此如果缓存中不存在数据,它将根据您对读取提供程序的实现从数据源中获取数据。
1 2 3 4 5 6 |
// Specify the readThruOptions for read through operations var readThruOptions = new ReadThruOptions(); readThruOptions.Mode = ReadMode.ReadThru; // Retrieve the data of the corresponding item with reads thru enabled Product data = cache.Get(key, readThruOptions); |
持久性启动加载器
如前所述,缓存是易失的,一旦缓存关闭,缓存中的所有数据都会被清除。 重新启动后,缓存为空,需要重新填充。 在需要时使用 Read-Thru 提供程序加载每个条目会使获取数据和操作的过程变慢。 如果我们可以在缓存启动时加载缓存中的所有数据怎么办? 随着 缓存加载器 提供的接口 NCache,持久存储中的所有数据在启动时都会复制到缓存中,因此可供应用程序使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class PersistenceStartupLoader : ProviderBase, ICacheLoader { public LoaderResult LoadNext(object userContext) { if (persistentItems == null) persistentItems = _persistenceProvider.GetAll(); LoaderResult result = new LoaderResult(); foreach (var item in persistentItems) { result.Data.Add(new KeyValuePair<string, ProviderItemBase>(item.Key, item.Value)); } return result; } } |
从持久数据存储中删除数据
在我制作的解决方案中,持久存储链接到您的缓存,因此在缓存中进行的任何更改也将在持久存储中进行。 例如,数据项存储在缓存和持久存储中。 当用户从缓存中删除它时,它也会在直写提供程序的帮助下从持久存储中删除。 这将确保主缓存与持久数据存储保持同步。
但是,这是完全灵活的,即使应用程序发送删除命令,您也可以更改它并将项目存储在持久存储中。
为什么 NCache?
NCache 是一种快速且可扩展的市场领先的内存分布式缓存,100% 用于 .NET / .NET Core 应用程序。 它提供服务器端功能来支持缓存持久性,并且可以根据需要进行许多配置以使用缓存持久性。 数据可以从缓存持久化到我们选择的任何数据库。 NCache 缓存应用程序数据并消除与数据存储和数据库相关的性能瓶颈。 它使您能够将数据存储在缓存中更长的时间,以确保您的数据在需要时可用。 NCache 持久性数据存储消除了每次缓存启动时将数据从数据库移动到缓存的需要。 这确保了您的数据的高可用性,而无需编写额外的代码!
前往 NCache 文档以了解有关如何实施和使用的更多信息 NCache 持久数据存储以及您的分布式缓存。