1

Azure Web サイトで Redis Cache を使用しています。キャッシュは Azure でホストされます。監視を通じてキャッシュに値を設定するときに、いくつかのタイムアウトに気付きました。そのため、ローカル サーバー キャッシュから redis の使用に移行する前に実行したいくつかの負荷テストを実行しましたが、以前のテストの実行と比較して、主に redis キャッシュへのタイムアウトが原因で、結果はかなり悪いものでした。

StackExchange.Redis ライブラリ バージョン 1.0.333 の厳密な名前のバージョンを使用しています。

キャッシュにアクセスするたびに新しい接続を作成しないように注意しました。

負荷テストは実際にはサーバーにそれほど負荷をかけておらず、結果は以前は 100% 成功していましたが、現在はタイムアウトが原因で約 50% のエラー率になっています。

キャッシュへのアクセスに使用されているコード。

 public static class RedisCacheProvider
{
    private static ConnectionMultiplexer connection;
    private static ConnectionMultiplexer Connection
    {
        get
        {
            if (connection == null || !connection.IsConnected)
            {
                connection = ConnectionMultiplexer.Connect(ConfigurationManager.ConnectionStrings["RedisCache"].ToString());
            }
            return connection;
        }
    }

    private static IDatabase Cache
    {
        get
        {
            return Connection.GetDatabase();
        }
    }


    public static T Get<T>(string key)
    {
        return Deserialize<T>(Cache.StringGet(key));
    }

    public static object Get(string key)
    {
        return Deserialize<object>(Cache.StringGet(key));
    }

    public static void Set(string key, object value)
    {
        Cache.StringSet(key, Serialize(value));
    }

    public static void Remove(string key)
    {
        Cache.KeyDelete(key);
    }

    public static void RemoveContains(string contains)
    {
        var endpoints = Connection.GetEndPoints();
        var server = Connection.GetServer(endpoints.First());
        var keys = server.Keys();
        foreach (var key in keys)
        {
            if (key.ToString().Contains(contains))
                Cache.KeyDelete(key);
        }
    }

    public static void RemoveAll()
    {
        var endpoints = Connection.GetEndPoints();
        var server = Connection.GetServer(endpoints.First());
        server.FlushAllDatabases();
    }

    static byte[] Serialize(object o)
    {
        if (o == null)
        {
            return null;
        }

        BinaryFormatter binaryFormatter = new BinaryFormatter();
        using (MemoryStream memoryStream = new MemoryStream())
        {
            binaryFormatter.Serialize(memoryStream, o);
            byte[] objectDataAsStream = memoryStream.ToArray();
            return objectDataAsStream;
        }
    }

    static T Deserialize<T>(byte[] stream)
    {
        if (stream == null)
        {
            return default(T);
        }

        BinaryFormatter binaryFormatter = new BinaryFormatter();
        using (MemoryStream memoryStream = new MemoryStream(stream))
        {
            T result = (T)binaryFormatter.Deserialize(memoryStream);
            return result;
        }
    }

}
4

2 に答える 2

1

IsConnected が false の場合、新しい ConnectionMultiplexer を作成しないでください。既存のマルチプレクサはバックグラウンドで再接続します。古いマルチプレクサを破棄せずに新しいマルチプレクサを作成すると、接続がリークします。次のパターンをお勧めします。

private static Lazy<ConnectionMultiplexer> lazyConnection =
    new Lazy<ConnectionMultiplexer>(() => {
        return ConnectionMultiplexer.Connect(
            "mycache.redis.cache.windows.net,abortConnect=false,ssl=true,password=...");
    });

public static ConnectionMultiplexer Connection {
    get {
        return lazyConnection.Value;
    }
}

Azure portal でキャッシュへの接続数を監視できます。異常に高いと思われる場合は、これがパフォーマンスに影響を与えている可能性があります。

さらにサポートが必要な場合は、'azurecache@microsoft.com' までご連絡ください。

于 2014-10-14T05:50:41.720 に答える