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

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

问题描述

我正在使用



我们还可以通过外壳连接到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.md
private static Lazy< ConnectionMultiplexer> RedisConnectionMultiplexer =新的Lazy< ConnectionMultiplexer>(()=>
{
return ConnectionMultiplexer.Connect(ConnectionString);
});

私有静态字符串ConnectionString {get;组; }

public RedisTimeConnectionManager(string connectionString)
{
ConnectionString = connectionString;
}

public ConnectionMultiplexer GetConnectionMultiplexer()
{
return RedisConnectionMultiplexer.Value;
}

public IDatabase GetDatabaseConnection()
{
return RedisConnectionMultiplexer.Value.GetDatabase();
}
}

然后我将此连接层传递给我的redis时间 经理。这是引发OOM错误的代码:

 公共类TimeRedisManager:ITimeRedisManager 
{
private IRedisConnectionManager RedisConnectionManager {get; }

public TimeRedisManager(IRedisConnectionManager redisConnectionManager)
{
RedisConnectionManager = redisConnectionManager;
}

公共异步任务< RedisUserTimelineGetValueDto> GetValueAsync(string id)
{
string key = $ time:{id};

HashEntry []项=等待RedisConnectionManager.GetDatabaseConnection()。HashGetAllAsync(key);

//解析并返回值...
}
}

因为Elasticache拥有超过7.5GB的可用内存,并且由于我可以通过外壳与之交互,所以我假设它是StackExchange.Redis库或代码中的连接管理问题。 / p>

.NET CORE 2.1
StackExchange.Redis v 2.0.513



最后一个重要事-当此异常发生时,它一直在发生。重新启动与Redis交互的服务不会执行任何操作。仅重新启动Elasticache节点即可解决该问题。

解决方案

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

p>

此处了解更多: https://redis.io/topics / admin


如果您在需要大量写入的应用程序中使用Redis,同时将
保存为RDB文件在磁盘上或重写AOF日志Redis最多可能使用2倍
倍于通常使用的内存。
所使用的额外内存与
保存过程中写入修改的内存页数成正比,因此,它通常与
(或聚合类型项)在此过程中接触的键数成正比这次。确保相应地调整
的内存大小。


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


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天全站免登陆