在文档上说
/// The cache manager must have at least one cache handle configured with <see cref="CacheHandleConfiguration.IsBackplaneSource"/> set to <c>true</c>.
/// Usually this is the redis cache handle, if configured. It should be the distributed and bottom most cache handle.
我知道如何使用RedisCacheHandle,因为它在Cachemanager的网站上作为示例提供
var cache = CacheFactory.Build<int>("myCache", settings =>
{
settings
.WithSystemRuntimeCacheHandle("inProcessCache")
.And
.WithRedisConfiguration("redis", config =>
{
config.WithAllowAdmin()
.WithDatabase(0)
.WithEndpoint("localhost", 6379);
})
.WithMaxRetries(1000)
.WithRetryTimeout(100)
.WithRedisBackplane("redis")
.WithRedisCacheHandle("redis", true);
});
问题是我不想使用Redis作为缓存资源;我只想通过Redis Pub / Sub机制的强大功能来创建分布式缓存。根据我通过代码调试,通过使用Redis Backplane功能,我能够确实向Redis发送消息并从Redis接收消息。那么为什么不使用RedisCacheHandle而是使用SystemRuntimeCacheHandle?
所以,我的期望是使用以下缓存配置成功执行
var cache = CacheFactory.Build<int>("myCache", settings =>
{
settings
.WithSystemRuntimeCacheHandle("inProcessCache")
.And
.WithRedisConfiguration("redis", config =>
{
config.WithAllowAdmin()
.WithDatabase(0)
.WithEndpoint("localhost", 6379);
})
.WithMaxRetries(1000)
.WithRetryTimeout(100)
.WithRedisBackplane("redis")
.WithSystemRuntimeCacheHandle("inProcessCache", true);
});
但它没有用。你能告诉我一个解决方案吗?我究竟做错了什么?或者,尽管它已在文档中写为
...通常这是redis缓存句柄...
有没有办法在没有RedisCacheHandle的情况下使用缓存同步功能?
答案 0 :(得分:0)
我猜你“不工作”你的意思是其他缓存没有被同步,例如如果我从cacheA中删除一个密钥,它不会从cacheB中删除? 是的,这是目前预期的行为。
背板旨在与只有一个状态的进程外缓存一起使用。 使用系统运行时缓存的2个缓存实例,在proc缓存中有两个完全断开连接。
通常,如果您有一个Redis图层并从缓存实例A中删除一个键,则该项将从Redis图层中删除。消息将发送到同一缓存的其他实例,并将从任何其他缓存层中删除密钥,但redis(标记为背板源的密钥)。 这意味着,我们希望背板源已经同步。
现在,如果您将进程内缓存作为背板源,该怎么办?这不起作用,因为两个实例总是不同步。
让我们看看这个例子:
var cacheConfig = ConfigurationBuilder.BuildConfiguration(settings =>
{
settings
.WithSystemRuntimeCacheHandle("inProcessCache")
.And
.WithRedisConfiguration("redis", config =>
{
config.WithAllowAdmin()
.WithDatabase(0)
.WithEndpoint("localhost", 6379);
})
.WithMaxRetries(1000)
.WithRetryTimeout(100)
.WithRedisBackplane("redis")
.WithSystemRuntimeCacheHandle("inProcessCache", true);
});
var cacheA = new BaseCacheManager<string>(cacheConfig);
var cacheB = new BaseCacheManager<string>(cacheConfig);
cacheB.Backplane.Removed += (obj, args) =>
{
Console.WriteLine(args.Key + " removed from B.");
};
cacheA.Add("key", "value");
var result = cacheB.Get("key");
Console.WriteLine("Result should be null:" + result);
cacheB.Add("key", "value");
result = cacheB.Get("key");
Console.WriteLine("Result should not be null:" + result);
// triggers backplane remove event
cacheA.Remove("key");
// lets give redis some time send messages
Thread.Sleep(100);
result = cacheB.Get("key");
Console.WriteLine("Result should be null again but isn't:" + result);
Console.ReadKey();
如果运行此操作,您可以看到背板事件实际触发但由于唯一的进程内缓存是背板源,因此密钥不会被删除。 这就是为什么最后,你仍然会把钥匙还给你。
正如我所说,这是目前预期的行为。
您可以通过侦听这些事件来实现自定义逻辑。 (事件将在下一个版本中略有变化,目前存在一些错误和不一致)。
此外,不要指望背板会将缓存值传输到其他实例。这不会发生。 CacheManager只发送键事件,而不是数据,因为数据通常由进程外缓存处理。
这意味着,如果只有背板的进程内缓存,在cacheA中添加项目,则不会将项目复制到cacheB!您可能会在cacheB上获得密钥的change
事件。
我希望这是有道理的;)