我刚刚开始尝试使用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