2

ドキュメントには、

    /// The cache manager must have at least one cache handle configured with <see cref="CacheHandleConfiguration.IsBackplaneSource"/> set to <c>true</c>.
    /// Usually this is the redis cache handle, if configured. It should be the distributed and bottom most cache handle.

Cachemanager の Web サイトで例として示されているため、RedisCacheHandle でそれを行う方法を知っています。

var cache = CacheFactory.Build<int>("myCache", settings =>
{
    settings
    .WithSystemRuntimeCacheHandle("inProcessCache")
    .And
    .WithRedisConfiguration("redis", config =>
    {
        config.WithAllowAdmin()
            .WithDatabase(0)
            .WithEndpoint("localhost", 6379);
    })
    .WithMaxRetries(1000)
    .WithRetryTimeout(100)
    .WithRedisBackplane("redis")
    .WithRedisCacheHandle("redis", true);
});

問題は、キャッシュ リソースとして Redis を使用したくないことです。Redis Pub/Sub メカニズムの力で分散キャッシュを作成したいだけです。コードを介したデバッグによると、Redis バックプレーン機能を使用することで、実際に Redis との間でメッセージを送受信できます。では、なぜ RedisCacheHandle を使用せず、代わりに SystemRuntimeCacheHandle を使用するのでしょうか?

したがって、私の期待は、次のキャッシュ構成で正常に実行されることでした

var cache = CacheFactory.Build<int>("myCache", settings =>
{
    settings
    .WithSystemRuntimeCacheHandle("inProcessCache")
    .And
    .WithRedisConfiguration("redis", config =>
    {
        config.WithAllowAdmin()
            .WithDatabase(0)
            .WithEndpoint("localhost", 6379);
    })
    .WithMaxRetries(1000)
    .WithRetryTimeout(100)
    .WithRedisBackplane("redis")
    .WithSystemRuntimeCacheHandle("inProcessCache", true);
});

しかし、それは機能していません。解決策を教えてください。私は何を間違っていますか?または、ドキュメントに次のように書かれていますが、

...通常、これは redis キャッシュ ハンドルです...

RedisCacheHandle なしでキャッシュ同期機能を使用する方法はありますか?

https://github.com/MichaCo/CacheManager/issues/111

4

1 に答える 1

0

「動作しない」とは、他のキャッシュが同期されないことを意味していると思います。たとえば、キャッシュAからキーを削除しても、キャッシュBから削除されませんか? はい、これは現在予期されている動作です。

バックプレーンは、状態が 1 つしかないプロセス外キャッシュで動作することを目的としています。キャッシュの 2 つのインスタンスが両方ともシステム ランタイム キャッシュを使用しているため、2 つの proc キャッシュが完全に切断されています。

通常、Redis レイヤーがあり、キャッシュ インスタンス A からキーを削除すると、アイテムは Redis レイヤーから削除されます。メッセージは同じキャッシュの他のインスタンスに送信され、redis (バックプレーン ソースとしてマークされたもの) 以外の他のキャッシュ レイヤーからキーが削除されます。これは、バックプレーン ソースが既に同期していることを意味します。

バックプレーン ソースとしてインプロセス キャッシュがある場合はどうなるでしょうか。両方のインスタンスが常に同期していないため、これは機能しません。

この例を見てみましょう:

var cacheConfig = ConfigurationBuilder.BuildConfiguration(settings =>
{
    settings
    .WithSystemRuntimeCacheHandle("inProcessCache")
    .And
    .WithRedisConfiguration("redis", config =>
    {
        config.WithAllowAdmin()
            .WithDatabase(0)
            .WithEndpoint("localhost", 6379);
    })
    .WithMaxRetries(1000)
    .WithRetryTimeout(100)
    .WithRedisBackplane("redis")
    .WithSystemRuntimeCacheHandle("inProcessCache", true);
});

var cacheA = new BaseCacheManager<string>(cacheConfig);
var cacheB = new BaseCacheManager<string>(cacheConfig);

cacheB.Backplane.Removed += (obj, args) =>
{
    Console.WriteLine(args.Key + " removed from B.");
};

cacheA.Add("key", "value");

var result = cacheB.Get("key");
Console.WriteLine("Result should be null:" + result);

cacheB.Add("key", "value");
result = cacheB.Get("key");
Console.WriteLine("Result should not be null:" + result);

// triggers backplane remove event
cacheA.Remove("key");

// lets give redis some time send messages
Thread.Sleep(100);

result = cacheB.Get("key");
Console.WriteLine("Result should be null again but isn't:" + result);

Console.ReadKey();

これを実行すると、バックプレーン イベントが実際に発生することがわかりますが、唯一のインプロセス キャッシュはバックプレーン ソースであるため、キーは削除されません。そのため、最後にキーが返されます。

私が言ったように、それは現在予想される動作です。

ただし、これらのイベントをリッスンしてカスタム ロジックを実装することはできます。(イベントは次のバージョンで少し変更されます。現在、いくつかのバグと矛盾があります)。

また、バックプレーンがキャッシュ値を他のインスタンスに転送するとは思わないでください。それは決して起こらないでしょう。通常、データはアウト プロセス キャッシュによって処理されるため、CacheManager はデータではなくキー イベントのみを送信します。つまり、バックプレーンのみのインプロセス キャッシュがある場合、キャッシュ A にアイテムを追加しても、アイテムはキャッシュ B にコピーされません! changeただし、cacheB のキーのイベントを取得する場合があります。

それが理にかなっていることを願っています;)

于 2016-11-22T13:56:56.633 に答える