簡體   English   中英

Stack Overflow,Redis和Cache失效

[英]Stack Overflow, Redis, and Cache invalidation

現在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緩存和site-identity作為密鑰的一部分。

對於系統中少數大量數據密集型部分,我們有機制持久存儲到磁盤,以便內存模型可以在連續的應用程序域之間傳遞,因為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語句。 我們使用幾乎一個單身人士。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM