【问题标题】:Redis Out of Memory Exceptions, but still have plenty of memoryRedis Out of Memory Exceptions,但仍然有足够的内存
【发布时间】: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


    【解决方案1】:

    Redis 可能占用存储在其中的数据所需内存的 2 倍。

    在此处阅读更多信息:https://redis.io/topics/admin

    如果您在写入量很大的应用程序中使用 Redis,同时保存 磁盘上的 RDB 文件或重写 AOF 日志 Redis 最多可以使用 2 次通常使用的内存。使用的额外内存是 与期间写入修改的内存页数成正比 保存过程,因此它通常与键的数量成正比 (或聚合类型项目)在此期间触及。确保大小 相应地你的记忆。

    因此,如果存储在 Redis 中的数据占用 8 Gb 空间,那么在重负载下,Redis 可能会消耗 16 Gbs。如果是这种情况,您可能需要相应地调整内存。

    【讨论】:

    • 这似乎是正确的答案。 Elasticache 实例是一个写入繁重的实例,在查看了我们的云指标后,在非常重的写入负载之后崩溃开始发生,并且在可用 RAM 开始呈指数下降之后。
    猜你喜欢
    • 2018-02-05
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 2020-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多