Redis 内存不足异常,但仍然有足够的内存 [英] Redis Out of Memory Exceptions, but still have plenty of memory

查看:55
本文介绍了Redis 内存不足异常,但仍然有足够的内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用

我们也可以通过shell连接到Elasticache,看到有内存可用,并与之交互就好了.

这是我用作连接信息层的代码.

 公共类 RedisTimeConnectionManager : IRedisConnectionManager{//有关 Lazy<> 的更多信息模式 https://stackoverflow.com/questions/28792196/how-does-connectionmultiplexer-deal-with-disconnects//关于多路复用器的附加信息:https://github.com/StackExchange/StackExchange.Redis/blob/master/docs/Basics.mdprivate static Lazy<ConnectionMultiplexer>RedisConnectionMultiplexer = new Lazy(() =>{返回 ConnectionMultiplexer.Connect(ConnectionString);});私有静态字符串 ConnectionString { 获取;放;}公共RedisTimeConnectionManager(字符串连接字符串){连接字符串 = 连接字符串;}公共连接多路复用器 GetConnectionMultiplexer(){返回 RedisConnectionMultiplexer.Value;}公共 IDatabase GetDatabaseConnection(){返回 RedisConnectionMultiplexer.Value.GetDatabase();}}

然后我将这个连接层传递给我的 redis时间"管理器.这是引发 OOM 错误的代码:

公共类 TimeRedisManager : ITimeRedisManager{私有 IRedisConnectionManager RedisConnectionManager { 获取;}公共时间RedisManager(IRedisConnectionManager redisConnectionManager){RedisConnectionManager = redisConnectionManager;}公共异步任务GetValueAsync(string id){string key = $"time:{id}";HashEntry[] 条目 = 等待 RedisConnectionManager.GetDatabaseConnection().HashGetAllAsync(key);//解析并返回值...}}

因为 Elasticache 有超过 7.5GB 的可用内存,而且我可以通过 shell 与它交互,所以我假设它要么是 StackExchange.Redis 库,要么是我的代码中的连接管理问题.

.NET 核心 2.1StackExchange.Redis v 2.0.513

最后一件重要的事情 - 当这个异常发生时,它会一直发生.重新启动与 Redis 交互的服务没有任何作用.只有重新启动 Elasticache 节点才能解决问题.

解决方案

Redis 可能会占用 2 倍于其中存储数据所需的内存.

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

<块引用>

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

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

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.

解决方案

Redis could take 2 times the memory required by data stored in it.

Read more here : https://redis.io/topics/admin

If you are using Redis in a very write-heavy application, while saving an RDB file on disk or rewriting the AOF log Redis may use up to 2 times the memory normally used. The additional memory used is proportional to the number of memory pages modified by writes during the saving process, so it is often proportional to the number of keys (or aggregate types items) touched during this time. Make sure to size your memory accordingly.

So, if the data stored in Redis takes 8 Gb of space, under heavy load Redis may consume 16 Gbs. You may have to tune the memory accordingly if that's the case.

这篇关于Redis 内存不足异常,但仍然有足够的内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆