2012-03-07 16 views
24

スタックオーバーフローでredisが使用されるようになったので、キャッシュ無効化も同じ方法で処理されますか?すなわち、照会文字列+名前にハッシュされたアイデンティティのリスト(名前は何らかの目的またはオブジェクトタイプ名であると推測される)。スタックオーバーフロー、Redis、およびキャッシュの無効化

おそらく、キャッシュから不足している個々のアイテムをidで直接取得します(これはデータベースインデックスの束をバイパスし、より効率的なクラスタードインデックスを代わりに使用する可能性があります)。それはスマートでしょう(ジェフが言及している復水?)。

今、私はこのすべてを簡潔な方法でピボットする方法を見つけるのに苦労しています。最初に自分でやる前に自分の考えを明確にするために使うことができるこの種の事例はありますか?

また、.netキャッシュ(System.Runtime.CachingまたはSystem.Web.Caching)を使用して、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)は、すべてのノードに変更されているキーを簡単にブロードキャストすることができるので、ローカルコピーをドロップすることができます - 次回は、 。したがって、変更しているキー名は、単一のイベント・チャネル名に対してブロードキャストします。

ツール:ubuntu serverでredis;レディスラッパーとしてのBookSleeve; protobuf-net、GZipStream(サイズに応じて自動的に有効/無効)を設定します。

ので:Redisのパブ/サブイベントがすべてのノードにノード(状態を知っている1が変更された)すぐに(ほとんど)から指定されたキーのキャッシュを無効にするために使用されています。

異なるプロセスについて(コメントから、「複数の異なるプロセスに同じデータを供給するための共有メモリモデルを使用していますか?」):いいえ、それはしません。各Web層ボックスは実際には1つのプロセス(任意の階層の)をホストしており、マルチテナントにあるため、同じプロセス内に70のサイトがある可能性があります。従来の理由(すなわち、"それは動作し、修正する必要はありません")、私たちは主にサイトIDを持つhttpキャッシュをキーの一部として使用します。

大量のデータ集約型のシステムでは、ディスクに永続化するメカニズムを備えているため、ウェブが自然にリサイクル(または再配置)されると、メモリ内モデルを連続したアプリケーションドメイン間で受け渡すことができます。それは赤みとは無関係です。ここで

は、これはうまくいくかもしれない方法の 幅広い味を示し、関連する例を示します - 以下のインスタンスの数をスピンアップし、その後にいくつかのキー名を入力します。

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)); 
     } 
    } 
} 

あなたは何をすべきキー名を入力すると、実行中のすべてのインスタンスにすぐに表示され、そのキーのローカルコピーがダンプされます。明らかに実際の使用では、2つの接続をどこかに置いて開いておく必要があるので、ではなく、usingとなります。これにはほぼシングルトンを使います。

+0

このイベントはまた戻ってメモリ内のバージョンを無効にしますか?もしそうなら、クール。 re:in-memory - 複数の異なるプロセスに同じデータを供給するために、あらゆる種類の共有メモリモデルを使用していますか?メモリ内のコンポーネントが重複する可能性があります。 – sgtz

+0

@sgtzは編集します –

+0

Marcに感謝します。今、情報を消化しています(精神的な歯はまだ終わっていません)。メモリからの有効期限を外部から管理することは、とても素晴らしいことです。それを考えなかった。 (!) – sgtz