我正在使用StackeExchange.Redis项目与.NET Core C#项目中的Redis进行交互。
在重负载下,我们的Redis连接将开始失败,并具有以下异常:
StackExchange.Redis.RedisServerException: OOM command not allowed when used memory > 'maxmemory'
问题是我们还有大量的可用内存。我们正在使用Elasticache,因此查找起来很容易:
我们还可以通过外壳连接到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的可用内存,并且因为我可以通过外壳与之交互,所以我认为它是StackExchange.Redis库或代码中的连接管理问题。
.NET CORE 2.1 StackExchange.Redis v 2.0.513
最后一件重要的事情-当此异常发生时,它一直在发生。重新启动与Redis交互的服务不会执行任何操作。仅重新启动Elasticache节点即可解决该问题。
答案 0 :(得分:1)
Redis可能占用存储在其中的数据所需内存的2倍。
在此处了解更多信息:https://redis.io/topics/admin
如果您在写量很大的应用程序中使用Redis,同时保存 磁盘上的RDB文件或重写AOF日志Redis最多可能使用2 倍于通常使用的内存。使用的额外内存是 与在写入过程中写入修改的内存页面数量成正比 保存过程,因此它通常与键的数量成正比 (或汇总类型的项目)在这段时间内接触过。确保尺寸 您的记忆。
因此,如果Redis中存储的数据占用8 Gb的空间,则在重负载下Redis可能会消耗16 Gb。在这种情况下,您可能必须相应地调整内存。
答案 1 :(得分:0)
当已用内存>'maxmemory'时不允许使用OOM命令
根据错误消息,您的Redis实例已达到 maxmemory 限制。
maxmemory 是Redis配置,它限制了Redis可以使用的最大内存。因此,您应该在配置文件中设置更大的 maxmemory 。