Azure中Redis缓存中的一致超时
我正在azure网站中使用Redis缓存。缓存托管在Azure中。我注意到在通过监控设置缓存值时出现了一些超时。因此,我运行了一些在从本地服务器缓存转移到使用redis之前运行的负载测试,与之前的测试相比,结果非常糟糕,主要是由于redis缓存超时造成的 我正在使用StackExchange.Redis库版本1.0.333强名称版本 我很小心,没有在每次访问缓存时创建新连接Azure中Redis缓存中的一致超时,azure,redis,stackexchange.redis,azure-redis-cache,Azure,Redis,Stackexchange.redis,Azure Redis Cache,我正在azure网站中使用Redis缓存。缓存托管在Azure中。我注意到在通过监控设置缓存值时出现了一些超时。因此,我运行了一些在从本地服务器缓存转移到使用redis之前运行的负载测试,与之前的测试相比,结果非常糟糕,主要是由于redis缓存超时造成的 我正在使用StackExchange.Redis库版本1.0.333强名称版本 我很小心,没有在每次访问缓存时创建新连接 public static class RedisCacheProvider { private static
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;
}
}
}
负载测试实际上并没有将服务器加载那么多,之前的结果是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;
}
}
}
如果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门户中监视到缓存的连接数。如果它看起来异常高,这可能是影响你表现的原因
如需进一步帮助,请通过以下地址与我们联系:azurecache@microsoft.com“。如果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门户中监视到缓存的连接数。如果它看起来异常高,这可能是影响你表现的原因
如需进一步帮助,请通过以下地址与我们联系:azurecache@microsoft.com’。我最近也遇到了同样的问题 以下几点将改善您的情况: Protobuf net代替二进制格式化程序 我建议使用,因为它会减少要存储在缓存中的值的大小
public interface ICacheDataSerializer
{
byte[] Serialize(object o);
T Deserialize<T>(byte[] stream);
}
public class ProtobufNetSerializer : ICacheDataSerializer
{
public byte[] Serialize(object o)
{
using (var memoryStream = new MemoryStream())
{
Serializer.Serialize(memoryStream, o);
return memoryStream.ToArray();
}
}
public T Deserialize<T>(byte[] stream)
{
var memoryStream = new MemoryStream(stream);
return Serializer.Deserialize<T>(memoryStream);
}
}
检查代码以最小化缓存调用和存储在缓存中的值。通过更有效地存储值,我减少了很多错误
如果这些都没有帮助。移动到更高的缓存我们最终使用C3而不是C1
我最近也有同样的问题 以下几点将改善您的情况: Protobuf net代替二进制格式化程序 我建议使用,因为它会减少要存储在缓存中的值的大小
public interface ICacheDataSerializer
{
byte[] Serialize(object o);
T Deserialize<T>(byte[] stream);
}
public class ProtobufNetSerializer : ICacheDataSerializer
{
public byte[] Serialize(object o)
{
using (var memoryStream = new MemoryStream())
{
Serializer.Serialize(memoryStream, o);
return memoryStream.ToArray();
}
}
public T Deserialize<T>(byte[] stream)
{
var memoryStream = new MemoryStream(stream);
return Serializer.Deserialize<T>(memoryStream);
}
}
检查代码以最小化缓存调用和存储在缓存中的值。通过更有效地存储值,我减少了很多错误
如果这些都没有帮助。移动到更高的缓存我们最终使用C3而不是C1
谢谢你!我认为它确实改进了它,但我仍然在实时环境中遇到一些超时错误。服务器上的负载很少,所以我仍然对超时感到有点困惑。谢谢!我认为它确实改进了它,但我仍然在实时环境中遇到一些超时错误。服务器上的负载很少,所以我仍然对超时感到有点困惑。