老实说,我无法确定这是SO问题还是MSO问题,但是:
进入另一个系统 永远不会 比查询本地内存快(只要有密钥)。简单的答案:我们都使用!因此我们使用:
- 本地记忆
- 否则检查redis,并更新本地内存
- 否则从源获取,并更新redis和本地内存
正如您所说,这会导致缓存失效的问题-尽管实际上这在大多数地方并不 重要 。但是,为此-redis事件(pub /
sub)提供了一种简便的方法来广播更改为所有节点的密钥,因此它们可以删除其本地副本-
意思是:下次需要时,我们将从redis中提取新副本。因此,我们广播了针对单个事件通道名称而更改的键名。
工具:在Ubuntu服务器上的Redis;BookSleeve作为Redis包装器;protobuf-
net和GZipStream(根据大小自动启用/禁用)以打包数据。
因此:redis pub / sub事件用于使给定密钥从 一个 节点(知道状态已更改的那个节点)的缓存立即(几乎)失效(到几乎 所有
节点)。
关于不同的进程(从注释中可以看出,“您是否对共享相同数据的多个不同的进程使用任何类型的共享内存模型?”):不,我们不这样做。每个Web层框只有真正承载一个过程(在任何给定层的),与多租户
内, 这一点,所以同样的过程中,我们可能有70个站点。由于遗留原因(即“有效且不需要修复”),我们主要使用带有站点标识的http缓存作为密钥的一部分。
对于系统中少量的大量数据密集型部分,我们具有持久存储到磁盘的机制,以便可以在Web自然回收(或重新部署)时在连续的应用程序域之间传递内存模型。与redis无关。
这是一个相关示例, 仅 展示了其工作方式的 大致 含义-旋转以下内容的多个实例,然后在其中键入一些键名:
static class Program{ static void Main() { const string channelInvalidate = "cache/invalidate"; using(var pub = new RedisConnection("127.0.0.1")) using(var sub = new RedisSubscriberConnection("127.0.0.1")) { pub.Open(); sub.Open(); sub.Subscribe(channelInvalidate, (channel, data) => { string key = Encoding.UTF8.GetString(data); Console.WriteLine("Invalidated {0}", key); }); Console.WriteLine( "Enter a key to invalidate, or an empty line to exit"); string line; do { line = Console.ReadLine(); if(!string.IsNullOrEmpty(line)) { pub.Publish(channelInvalidate, line); } } while (!string.IsNullOrEmpty(line)); } }}您应该看到的是,当您键入密钥名称时,该名称会立即显示在所有正在运行的实例中,然后实例将转储其密钥的本地副本。显然,在实际使用中,这两个连接需要放置在某个地方并保持打开状态,因此
不会 出现在
using语句中。为此,我们使用了几乎一个单例。



