2012-03-07 136 views
24

現在堆棧溢出使用redis,它們是否以相同的方式處理緩存失效?即一個身份列表哈希到查詢字符串+名稱(我猜這個名字是某種目的或對象類型名稱)。Stack Overflow,Redis和Cache失效

也許他們然後直接檢索從緩存中丟失的單個項目(繞過一堆數據庫索引,而不是使用更有效的聚簇索引)。那會很聰明(Jeff提到的補液)。

現在,我正在努力尋找一種方法來以簡潔的方式來實現所有這些。有沒有這樣的事情的例子,我可以用來幫助澄清我的想法,然後再做自己的第一次切割?

此外,我想知道在使用.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

回答

40

老實說,我不能決定,如果這是SO問題或MSO問題,但是:

去查詢另一個系統是從來沒有快於查詢本地內存(只要它是鍵控);簡單的答案:我們同時使用!所以我們使用:

  • 本地內存
  • 其他檢查Redis的,並更新本地內存
  • 從源頭別的讀取和更新Redis的和本地內存

這就如你所說,導致緩存失效的問題 - 儘管實際上在大多數地方不是關鍵。但是爲此 - redis事件(pub/sub)允許一種簡單的方法來廣播正在改變到所有節點的密鑰,以便他們可以放棄他們的本地副本 - 這意味着:下次需要時,我們將從redis中獲取新副本。因此,我們廣播對單個事件頻道名稱進行更改的鍵名稱。

工具:在Ubuntu服務器上的Redis; BookSleeve作爲redis包裝器; protobuf-net和GZipStream(根據大小自動啓用/禁用)打包數據。

所以:Redis的發佈/訂閱事件被使用(已經改變,知道國家的)對給定鍵緩存從一個節點立即失效(幾乎)到所有節點。

關於不同的進程(來自注釋,「你是否使用任何種類的共享內存模型來處理多個不同的進程以提供相同的數據?」):不,我們不這樣做。每個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聲明中。我們爲此使用了一個近乎單身的單身人士。

+0

該事件是否也會回來並使內存中的版本無效?如果是這樣,很酷。回覆:內存中 - 您是否使用任何類型的共享內存模型來處理多個不同的進程,以提供相同的數據?我看到內存組件重複的潛力。 – sgtz 2012-03-07 07:22:46

+0

@sgtz將編輯 – 2012-03-07 07:40:16

+0

感謝Marc。現在消化信息(心理齒輪尚未完成轉向)。從外部管理內存到期是一個非常好的接觸。沒有想到這一點。 (!) – sgtz 2012-03-07 10:03:43

相關問題