I'm using the StackeExchange.Redis project to interact with Redis in our .NET Core C# project.
Under heavy load, our Redis connections will begin to fail with the following exception:
StackExchange.Redis.RedisServerException: OOM command not allowed when used memory > 'maxmemory'
The problem is that we have a ridiculous amount of free memory left. We're using Elasticache, so it's easy to lookup:
We can also connect to Elasticache through a shell, and see that there is memory avaialable, and interact with it just fine.
This is the code I used as a layer over the Connection information.
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();
}
}
I then pass this Connection layer to my redis "time" manager. This is the code that is throwing the OOM error:
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...
}
}
Because Elasticache has over 7.5GB free of memory, and because I can interact with it through a shell, I'm assuming it's either the StackExchange.Redis library, or an issue with connection management in my code.
.NET CORE 2.1 StackExchange.Redis v 2.0.513
One last important thing - when this exception happens, it keeps happening. Restarting the services that interact with Redis does nothing. Only restarting the Elasticache nodes solve the problem.