代码之家  ›  专栏  ›  技术社区  ›  contactmatt

Redis内存不足异常,但仍有大量内存

  •  0
  • contactmatt  · 技术社区  · 7 年前

    StackeExchange.Redis 在.NET核心C#项目中与Redis交互的项目。

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

    问题是我们的可用内存量太多了。我们使用Elasticache,因此很容易查找:

    enter image description here

    我们还可以通过一个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...
        }
    }
    

    .NET核心2.1 StackExchange.Redis版本2.0.513

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

    2 回复  |  直到 7 年前
        1
  •  3
  •   rainhacker    7 年前

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

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

    如果您在一个写容量非常大的应用程序中使用Redis,那么 磁盘上的RDB文件或重写AOF日志Redis最多可能使用2个 与写入过程中修改的内存页数成比例 (或聚合类型项)在此期间接触。请确定大小 你的记忆力也会相应地提高。