Redis和C#随机提供Timeout执行PSETEX

时间:2014-10-19 15:42:20

标签: c# asp.net redis ubuntu-14.04

我刚刚开始尝试使用Redis作为我的asp.net站点的输出缓存提供程序(客户端是StackExchange.Redis)。

但有时我会收到超时异常:

[TimeoutException: Timeout performing PSETEX c2cbc817d14b825e7b40b9c8e41bffd1__-1753266091, inst: 1, mgr: ExecuteSelect, queue: 2, qu=0, qs=2, qc=0, wr=1/1, in=0/0]
   StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl(Message message, ResultProcessor`1 processor, ServerEndPoint server) +919
   StackExchange.Redis.RedisBase.ExecuteSync(Message message, ResultProcessor`1 processor, ServerEndPoint server) +66
   StackExchange.Redis.RedisDatabase.StringSet(RedisKey key, RedisValue value, Nullable`1 expiry, When when, CommandFlags flags) +95
   TestSite.RedisCachingProvider.Set(String cacheKey, Object entry, DateTime utcExpiry) in c:\TestSite\RedisCachingProvider.cs:125
   System.Web.Caching.OutputCache.InsertResponse(String cachedVaryKey, CachedVary cachedVary, String rawResponseKey, CachedRawResponse rawResponse, CacheDependency dependencies, DateTime absExp, TimeSpan slidingExp) +682
   System.Web.Caching.OutputCacheModule.OnLeave(Object source, EventArgs eventArgs) +93
   System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +136
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69

我的提供者是否有遗漏或未想到的事情?

public class RedisCachingProvider : OutputCacheProvider
{
    private static readonly object m_InitLockObj = new object();
    private static bool m_HasBeenInit;

    private static ConnectionMultiplexer ConnectionMultiplexer { get; set; }


    public override void Initialize(string name, NameValueCollection config)
    {
        base.Initialize(name, config);

        if (!m_HasBeenInit)
        {
            lock (m_InitLockObj)
            {
                ConnectionMultiplexer = ConnectionMultiplexer.Connect("192.168.0.240");

                m_HasBeenInit = true;
            }
        }
    }

    public override object Get(string key)
    {
        var storageDetails = GetStorageDetails(key);
        var redis = storageDetails.Database;
        var cachedBytes = redis.StringGet(storageDetails.Key);

        return cachedBytes.IsNull
            ? null
            : DeserializeObject(cachedBytes);
    }


    public override object Add(string cacheKey, object entry, DateTime utcExpiry)
    {
        var cachedEntry = Get(cacheKey);

        if (cachedEntry == null)
        {
            Set(cacheKey, entry, utcExpiry);
            return entry;
        }

        return cachedEntry;
    }

    public override void Set(string cacheKey, object entry, DateTime utcExpiry)
    {
        var storageDetails = GetStorageDetails(cacheKey);
        var redis = storageDetails.Database;
        var newBytes = SerializeObject(entry);

        redis.StringSet(storageDetails.Key, newBytes, utcExpiry.Subtract(DateTime.UtcNow));
    }

    public override void Remove(string cacheKey)
    {
        var storageDetails = GetStorageDetails(cacheKey);
        var redis = storageDetails.Database;

        redis.KeyDelete(storageDetails.Key);
    }



    private static StorageDetails GetStorageDetails(string cacheKey)
    {
        return new StorageDetails
        {
            Database = ConnectionMultiplexer.GetDatabase(),
            Key = TransformKey(cacheKey)
        };
    }

    private static string TransformKey(string cacheKey)
    {
        return cacheKey.ToMD5() + "__" + cacheKey.GetHashCode();
    }


    private static byte[] SerializeObject(object entry)
    {
        var bf = new BinaryFormatter();
        using (var ms = new MemoryStream())
        {
            bf.Serialize(ms, entry);
            return ms.ToArray();
        }
    }

    private static object DeserializeObject(byte[] bytes)
    {
        var bf = new BinaryFormatter();
        using (var ms = new MemoryStream(bytes))
        {
            return bf.Deserialize(ms);
        }
    }
}

public class StorageDetails
{
    public IDatabase Database { get; set; }
    public RedisKey Key { get; set; }
}

redis.conf尚未修改,我在Ubuntu 14.04.1 LTS上运行redis

运行redis-server --version告诉我:

  

Redis服务器v = 2.8.4 sha = 00000000:0 malloc = jemalloc-3.4.1 bits = 64 build = a44a05d76f06a5d9

0 个答案:

没有答案