当前位置: 首页 > 面试题库 >

堆栈溢出,Redis和缓存失效

沈思博
2023-03-14
问题内容

现在,Stack
Overflow使用redis,它们是否以相同的方式处理缓存失效?即散列到查询字符串+名称的身份列表(我想这个名称是某种用途或对象类型的名称)。

也许他们然后直接通过id(从一堆数据库索引中绕过,而是使用效率更高的聚集索引)直接从缓存中检索缺少的单个项。那会很聪明(杰夫提到的补液?)。

现在,我正在努力寻找一种简洁地解决所有问题的方法。在我自己进行初次切割之前,是否有任何此类示例可以用来澄清我的想法?

另外,我想知道在使用.net缓存(System.Runtime.Caching或System.Web.Caching)与退出并使用Redis之间的截止点在哪里。还是Redis放慢手脚了?

这是2009年的原始SO问题:

https://meta.stackexchange.com/questions/6435/how-does-stackoverflow-handle-
cache-invalidation

其他几个链接:

https://meta.stackexchange.com/questions/69164/does-stackoverflow-use-
caching-and-if-so-
how/69172#69172

https://meta.stackexchange.com/questions/110320/stack-overflow-db-
performance-and-redis-
cache


问题答案:

老实说,我无法确定这是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语句中。为此,我们使用了几乎一个单例。



 类似资料:
  • 我写了以下内容: 解决4clojure.com的问题#118:http://www.4clojure.com/problem/118 当我询问时,不出所料,我会得到一个clojure.lang.lazyseq,但我不知道这与简单地删除lazy-seq“包装”有什么区别。 当然,现在如果删除lazy-seq,我会得到一个stackoverflow,为什么要执行这个: 否则(也就是说:如果我让lazy

  • 我有一个执行快速排序的应用程序。在我开始给它一些更大的数字(我第一次得到它是10000000)之前,它工作得很好。我知道是由递归引起的,但我不明白为什么我的应用程序会因此而崩溃。如有任何建议,将不胜感激。这是我的密码:

  • 问题内容: 下面给出的代码显示了运行时的Stackoverflow错误。但是,如果我使另一个类CarChange创建Car的对象,它将成功运行。我是一个初学者,请执行以下代码以了解在Java中进行向上转换的重要性。 问题答案: 一个stackoverflow通常意味着您有一个无限循环。 收到此消息的原因是因为您从testdrive方法调用驱动器,并且在该方法中再次调用drive。

  • 问题内容: 这有效:http : //play.golang.org/p/-Kv3xAguDR。 这导致堆栈溢出:http : //play.golang.org/p/1-AsHFj51O。 我不明白为什么。在这种情况下,使用接口的正确方法是什么? 问题答案: 这个 将呼叫您的,依次呼叫,等等。如果您需要解组JSON然后对其进行处理,那么一种巧妙的技术是声明一个本地类型,将数据解组到其中,然后转换

  • (使用Java 15.0+) 我正在用这些实现一个堆栈 如何检查堆栈是否下溢?从Overflow boolean变量中,我们知道如果一个数字不能用8位来表示,就会导致溢出。但是,如果数字不能以这种方式表示,我们如何检查呢?我还认为应该有更多的情况下堆栈溢出,像jumpz或jumpn导致通过指令的无限循环。

  • 问题内容: 我正在研究一些与安全性相关的东西,现在我正在玩自己的堆栈。我正在做的事情应该是微不足道的,我什至没有试图执行堆栈,只是为了表明我可以控制我的64位系统上的指令指针。我已经关闭了所有我知道的保护机制,以便能够使用它(NX位,ASLR,还可以使用- fno-stack-protector -z execstack进行编译)。我在64位汇编方面没有太多经验,花了一些时间进行搜索和实验后,我想