gpt4 book ai didi

azure - Azure 中 Redis 缓存的一致超时

转载 作者:IT王子 更新时间:2023-10-29 06:09:08 24 4
gpt4 key购买 nike

我在一个 azure 的网站中使用 Redis 缓存。缓存托管在 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;
}
}

}

最佳答案

我最近也遇到了同样的问题。

可以改善您的情况的几点:

Protobuf-net 代替 BinaryFormatter

我建议使用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);
}
}

实现重试策略

实现此 RedisCacheTransientErrorDetectionStrategy 来处理超时问题。

using Microsoft.Practices.TransientFaultHandling;

public class RedisCacheTransientErrorDetectionStrategy : ITransientErrorDetectionStrategy
{
/// <summary>
/// Custom Redis Transient Error Detenction Strategy must have been implemented to satisfy Redis exceptions.
/// </summary>
/// <param name="ex"></param>
/// <returns></returns>
public bool IsTransient(Exception ex)
{
if (ex == null) return false;

if (ex is TimeoutException) return true;

if (ex is RedisServerException) return true;

if (ex is RedisException) return true;

if (ex.InnerException != null)
{
return IsTransient(ex.InnerException);
}

return false;
}
}

像这样实例化:

private readonly RetryPolicy _retryPolicy;

// CODE
var retryStrategy = new FixedInterval(3, TimeSpan.FromSeconds(2));
_retryPolicy = new RetryPolicy<RedisCacheTransientErrorDetectionStrategy>(retryStrategy);

像这样使用:

var cachedString = _retryPolicy.ExecuteAction(() => dataCache.StringGet(fullCacheKey));

检查您的代码以最大程度地减少缓存调用和存储在缓存中的值。通过更有效地存储值,我减少了很多错误。

如果这些都没有帮助。移至更高的缓存(我们最终使用 C3 而不是 C1)。

enter image description here

关于azure - Azure 中 Redis 缓存的一致超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26352469/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com