如今,大多数依赖大量数据库调用的用户应用程序都在结合分布式缓存以获得更好的性能和线性可扩展性。 为此,用户希望每当数据库中发生更改时,该更改也立即反映在缓存中。 NCache 作为内存中的分布式缓存,为我们提供了用于类似目的的不同技术,以使数据在缓存中保持新鲜。
首先, NCache 提供 過期 在预定义的时间间隔后,数据会自动从缓存中删除。 其次,是战略 缓存对数据库的依赖 缓存中的数据与数据库保持同步,并且在更改时失效。 同样,还有另一种机制是 缓存刷新器 它以预定的时间间隔在后台运行,并以受控的方式保持数据的新鲜和更新。
这个博客是关于解释 Cache Refresher 的不同策略以及它如何使数据在缓存中保持新鲜。
缓存刷新:概述和概念
假设用户运行一个视频流媒体频道,并在缓存中缓存了一些新信息以及他们各自的视频。 在较长一段时间内,缓存中的视频保持不变,但现在由于某种原因,某些新视频被添加,其他视频在数据库中得到更新。 这会导致用户观看已经更新的旧视频(陈旧数据)。
NCache 提供 缓存刷新器 通过以特定刷新间隔刷新数据来保持缓存中数据新鲜的功能. 缓存数据的刷新包括在数据源中的数据更改时添加、更新和删除它。
要配置Cache Refresher,用户首先需要实现 缓存启动加载器. 此加载器用于在缓存启动时以数据集的形式预加载缓存中的数据,数据集表示将不同类型的数据组合在一起以实现并行性的一种方式。 每次缓存启动时,缓存加载器都会根据配置的数据集自动从数据源中获取数据。 为了使这些预加载的数据保持新鲜并与数据源中的更新数据保持同步,使用了缓存刷新器,它在预定的时间间隔后分别刷新这些数据集。
缓存刷新器的不同属性
在开始实现之前,用户需要了解缓存刷新器的一些属性。 下面解释了需要牢记的细节。
- 数据集: 数据集是用户对不同类型的数据进行分组的一种方式,以便他们可以以不同的时间间隔或事件分别加载或刷新它们以实现并行性。
- 数据集调度: 数据集根据数据集计划进行刷新。 这个时间表可以是: 每日时间、每日间隔、每周 和 包月. 所有这些,在它们独特的实现中,决定了数据集需要刷新的确切时间。 每个数据集都可以有自己的刷新计划。 一个例子可以是,刷新有关数据集的视频 烘焙食品 每个月的每个星期天中午。 有关详细信息,请参阅 Docs 中的数据集调度.
- 刷新间隔: 这是一个时间间隔,在此时间间隔之后,一个线程会运行以检查在计划时间到达时准备好刷新的数据集。 每个数据集都有不同的计划刷新间隔,但此间隔在缓存级别保持不变。 此时间间隔可以分别设置为最短 15 分钟和最长 60 分钟。
如何实现缓存刷新器?
要使用 Cache Refresher 实现,首先用户需要配置 缓存加载器 界面。 第二, NCache 调用实现的 LoadDatasetOnStartup 方法将数据加载到缓存中。 然后它使用 RefreshDataset 方法刷新由 Cache Loader 加载到缓存中的数据。
假设用户在数据库中有两个视频,一个是重新评分烘焙产品,另一个是服装产品. 以下实现将视频预加载到缓存中,然后对于任何更新都会在两个单独的刷新间隔上刷新数据。
初始化缓存和连接
在 Cache Startup 上调用 Init 方法来配置连接。 下面是一个示例实现 在里面 ICacheLoader 接口的方法。 在这里,我们打开一个 SQL 连接并使用用户给定的名称初始化一个缓存。
1 2 3 4 5 6 7 8 |
public void Init(IDictionary<string, string> parameters, string cacheName) { string connectionString = parameters["connectionString"] as string; connection = new SqlConnection(connectionString); connection.Open(); cache = CacheManager.GetCache(cacheName); } |
在缓存中加载数据集
第二步,用户使用 启动时加载数据集, 一种在缓存启动时调用的方法,用于将指定的数据集从数据库加载到缓存中以预填充缓存。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public object LoadDatasetOnStartup(string dataset) { // Create a list of datasets to load at cache startup IList<object> datasetToLoad; switch (dataSet.ToLower()) { // If dataset is "products", fetch products from data source to load in cache case "products": datasetToLoad = FetchProductsFromDataSource(); // Insert fetched product in the cache foreach (var product in datasetToLoad) { string key = $"ProductID:{product.Id}"; cache.Insert(key, product); } break; default: // Invalid dataset } // User context is the time at which datasets were loaded in the cache object userContext = DateTime.Now; return userContext; } |
刷新加载的数据集
第三,要定期刷新数据集,用户应提供 刷新数据集. 在这里,用户应该更新缓存加载器加载的已经预加载的数据,添加新数据或从该特定数据集中删除数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public object RefreshDataset(string dataset, object userContext) { *DateTime? lastRefreshTime; switch (dataset.ToLower()) { // If dataset is "bakery products", fetch updated products from data source case "bakery products": lastRefreshTime = userContext as DateTime?; IList<Product> productsToRefresh = FetchUpdatedProducts(lastRefreshTime) as IList<Product>; // Insert updated products in the cache foreach (var product in productsToRefresh) { string key = $"ProductID:{product.Id}"; CacheItem cacheItem = new CacheItem(product); _cache.Insert(key, cacheItem); } break; default: // Invalid dataset } // User context is the time at which datasets were refreshed userContext = DateTime.Now; return userContext; } |
实施基于轮询的刷新器
现在,方法来了 获取数据集刷新, 它在每个刷新间隔调用,并且只有在用户想要使用自己的自定义逻辑来控制不同加载数据集的刷新时间时才应提供。 返回的这些数据集要么立即刷新,要么在告知的同一天刷新。
按需刷新数据集
最后,用户还可以选择在运行时通过 调用刷新数据集 cmdlet。 在这里,数据集可以立即或在接下来的 24 小时内使用 RefreshPreference
选项。 下面显示了一个示例,其中数据集产品立即刷新 demoClusteredCache
在服务器 20.200.20.11 上。
1 |
Invoke-RefresherDataset -CacheName demoClusteredCache -Server 20.200.20.11 -Dataset product -RefreshPreference RefreshNow |
通过配置缓存加载器和刷新器 NCache 网络管理员
一旦用户实现了缓存启动加载器和刷新器,他/她可以通过 Web 管理器进行配置,并根据自己的要求设置刷新间隔。 下面是如何做到的。
结束博客!
快到最后,到目前为止讨论的所有内容都表明需要有效地更新缓存,而缓存刷新器是最好的方法。 如果数据库中发生任何更改,它会以非常系统的方式更新缓存数据。 就像缓存刷新器一样, NCache 提供了许多有趣的功能,可以在没有任何不便的情况下执行。 查看我们的网站了解更多详情!