Redis内存不足异常,但仍有足够的内存

时间:2018-10-25 15:28:13

标签: redis .net-core stackexchange.redis amazon-elasticache

我正在使用StackeExchange.Redis项目与.NET Core C#项目中的Redis进行交互。

在重负载下,我们的Redis连接将开始失败,并具有以下异常:

StackExchange.Redis.RedisServerException: OOM command not allowed when used memory > 'maxmemory'

问题是我们还有大量的可用内存。我们正在使用Elasticache,因此查找起来很容易:

enter image description here

我们还可以通过外壳连接到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节点即可解决该问题。

2 个答案:

答案 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