Stack Overflow が redis を使用するようになった今、キャッシュの無効化も同じ方法で処理されるのでしょうか? つまり、クエリ文字列 + 名前にハッシュされた ID のリストです (名前は何らかの目的またはオブジェクト タイプ名だと思います)。
おそらく、キャッシュから欠落している個々のアイテムを ID によって直接取得するのでしょう (これにより、多数のデータベース インデックスがバイパスされ、代わりにより効率的なクラスター化インデックスが使用される可能性があります)。これは賢いやり方です (Jeff が言及しているリハイドレーションでしょうか)。
現時点では、これらすべてを簡潔にまとめる方法を見つけるのに苦労しています。自分で最初のカットを行う前に、考えを明確にするのに役立つような例はありますか?
また、.net キャッシュ (System.Runtime.Caching または System.Web.Caching) を使用することと、実際に redis を使用することの境界はどこにあるのでしょうか。それとも、Redis の方が断然速いのでしょうか?
以下は 2009 年の元の SO の質問です。
https://meta.stackexchange.com/questions/6435/stackoverflow-handle-cache-invalidation はどのように機能しますか?
その他のリンクをいくつか紹介します:
https://meta.stackexchange.com/questions/110320/stack-overflow-db-パフォーマンスとredis-キャッシュ
ベストアンサー1
正直に言って、これが SO の質問なのか MSO の質問なのかはわかりませんが、
別のシステムに移行することは一度もないローカルメモリをクエリするよりも高速です(キーが付けられている限り)。簡単な答え:両方を使用します!したがって、次を使用します。
- ローカルメモリ
- それ以外の場合は、Redisをチェックし、ローカルメモリを更新します。
- そうでない場合はソースから取得し、Redisとローカルメモリを更新します。
これは、あなたが言うように、キャッシュの無効化の問題を引き起こします - しかし、実際にはそうではありません致命的ほとんどの場所では、Redis イベント (pub/sub) を使用すると、変更されるキーをすべてのノードにブロードキャストする簡単な方法が提供されるため、ノードはローカル コピーを削除できます。つまり、次回必要になったときに、Redis から新しいコピーを取得します。したがって、変更されるキー名を単一のイベント チャネル名に対してブロードキャストします。
ツール: Ubuntu サーバー上の redis、redis ラッパーとしての BookSleeve、データをパッケージ化するための protobuf-net および GZipStream (サイズに応じて自動的に有効化/無効化)。
つまり、Redisのpub/subイベントは、特定のキーのキャッシュを無効にするために使用されます。1つノード(状態が変化したことを知っているノード)は、すぐに(ほぼ)全てノード。
個別のプロセスに関して(コメントから、「同じデータを供給する複数の個別のプロセスに何らかの共有メモリモデルを使用していますか?」):いいえ、私たちはそうしません。各Web層ボックスは、実際には1つのプロセス(任意の層)のみをホストしており、マルチテナントです。内でつまり、同じプロセス内に 70 個のサイトが存在する可能性があります。レガシーな理由 (つまり、「動作しており、修正する必要がない」) により、私たちは主に、サイト ID をキーの一部として含む 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));
}
}
}
キー名を入力すると、実行中のすべてのインスタンスにすぐに表示され、そのキーのローカルコピーがダンプされることがわかります。実際の使用では、2つの接続をどこかに置いて開いたままにしておく必要があるため、ないステートメント内にありますusing
。これにはほぼシングルトンを使用します。