【发布时间】:2023-03-31 04:20:01
【问题描述】:
我正在使用StackeExchange.Redis 项目与我们的 .NET Core C# 项目中的 Redis 进行交互。
在重负载下,我们的 Redis 连接将开始失败,并出现以下异常:
StackExchange.Redis.RedisServerException: OOM command not allowed when used memory > 'maxmemory'
问题是我们还有大量的可用内存。我们使用的是 Elasticache,因此很容易查找:
我们也可以通过 shell 连接到 Elasticache,看看有没有可用的内存,并与之交互就好了。
这是我用作连接信息层的代码。
public class RedisTimeConnectionManager : IRedisConnectionManager
{
// More info about the Lazy<> pattern https://stackoverflow.com/questions/28792196/how-does-connectionmultiplexer-deal-with-disconnects
// Additional information about the multiplexer: https://github.com/StackExchange/StackExchange.Redis/blob/master/docs/Basics.md
private static Lazy<ConnectionMultiplexer> RedisConnectionMultiplexer = new Lazy<ConnectionMultiplexer>(() =>
{
return ConnectionMultiplexer.Connect(ConnectionString);
});
private static string ConnectionString { get; set; }
public RedisTimeConnectionManager(string connectionString)
{
ConnectionString = connectionString;
}
public ConnectionMultiplexer GetConnectionMultiplexer()
{
return RedisConnectionMultiplexer.Value;
}
public IDatabase GetDatabaseConnection()
{
return RedisConnectionMultiplexer.Value.GetDatabase();
}
}
然后我将此连接层传递给我的 redis“时间”管理器。这是引发 OOM 错误的代码:
public class TimeRedisManager : ITimeRedisManager
{
private IRedisConnectionManager RedisConnectionManager { get; }
public TimeRedisManager(IRedisConnectionManager redisConnectionManager)
{
RedisConnectionManager = redisConnectionManager;
}
public async Task<RedisUserTimelineGetValueDto> GetValueAsync(string id)
{
string key = $"time:{id}";
HashEntry[] entries = await RedisConnectionManager.GetDatabaseConnection().HashGetAllAsync(key);
// Parse and return values...
}
}
因为 Elasticache 有超过 7.5GB 的可用内存,而且我可以通过 shell 与之交互,所以我假设它要么是 StackExchange.Redis 库,要么是我的代码中的连接管理问题。
.NET 核心 2.1 StackExchange.Redis v 2.0.513
最后一件重要的事情 - 当这个异常发生时,它会继续发生。重新启动与 Redis 交互的服务不会执行任何操作。只有重启 Elasticache 节点才能解决问题。
【问题讨论】:
标签: redis .net-core stackexchange.redis amazon-elasticache