假设我有一个对象,例如站点导航节点树,从头开始构建可能很昂贵,当它变大时,从缓存中反序列化可能会变得很昂贵。
假设我将我的ITreebuilder注册为DI
中的单身人士services.TryAdd(ServiceDescriptor.Singleton<INavigationTreeBuilder, XmlNavigationTreeBuilder>());
并且消费者调用下面显示的GetTree方法:
private TreeNode<NavigationNode> rootNode = null;
public async Task<TreeNode<NavigationNode>> GetTree()
{
if (rootNode == null)
{
await cache.ConnectAsync();
byte[] bytes = await cache.GetAsync(cacheKey);
if (bytes != null)
{
string json = Encoding.UTF8.GetString(bytes);
rootNode = BuildTreeFromJson(json);
}
else
{
rootNode = await BuildTree();
string json = rootNode.ToJsonCompact();
await cache.SetAsync(
cacheKey,
Encoding.UTF8.GetBytes(json),
new DistributedCacheEntryOptions().SetSlidingExpiration(
TimeSpan.FromSeconds(100))
);
}
}
return rootNode;
}
这个单例对象会在应用程序的生命周期内保存在内存中吗? 每个Web服务器节点都有它自己的单例副本,但在第一个节点将对象放入分布式缓存后,其他节点不必构建它? 缺少的部分将是如何检测分布式缓存何时无效,以便在需要时可以重建内部rootNode
这听起来像管理像这样的潜在昂贵对象的好的,合理的或可行的策略吗?
如果我们从每个Web请求的分布式缓存中获取树,它将避免涉及的反序列化开销。我想在反序列化之后使用IMemoryCache存储对象以避免在每个Web请求上反序列化它,但是这个想法似乎会将它保留在内存中而不必管理2层缓存并且更容易实现。
有关如何在不从缓存中请求对象的情况下检测分布式缓存何时无效或更新的任何提示?也许我可以使用时间戳同时缓存一个较小的对象,我可以检查这个时间戳是否改变了?