为啥与 Azure Redis 缓存的连接如此之高?

Posted

技术标签:

【中文标题】为啥与 Azure Redis 缓存的连接如此之高?【英文标题】:Why are connections to Azure Redis Cache so high?为什么与 Azure Redis 缓存的连接如此之高? 【发布时间】:2014-11-19 22:13:17 【问题描述】:

我在单台机器查询缓存的高负载场景中使用 Azure Redis 缓存。这台机器大约每秒获取和设置大约 20 个项目。白天增加,夜间减少。

到目前为止,一切正常。今天我意识到“连接的客户端”的指标非常高,尽管我只有 1 个客户端经常获取和设置项目。这是我的意思的指标的屏幕截图:

我的代码如下所示:

public class RedisCache<TValue> : ICache<TValue>

    private IDatabase cache;
    private ConnectionMultiplexer connectionMultiplexer;

    public RedisCache()
    
        ConfigurationOptions config = new ConfigurationOptions();
        config.EndPoints.Add(GlobalConfig.Instance.GetConfig("RedisCacheUrl"));
        config.Password = GlobalConfig.Instance.GetConfig("RedisCachePassword");
        config.ConnectRetry = int.MaxValue; // retry connection if broken
        config.KeepAlive = 60; // keep connection alive (ping every minute)
        config.Ssl = true;
        config.SyncTimeout = 8000; // 8 seconds timeout for each get/set/remove operation
        config.ConnectTimeout = 20000; // 20 seconds to connect to the cache

        connectionMultiplexer = ConnectionMultiplexer.Connect(config);
        cache = connectionMultiplexer.GetDatabase();
    

    public virtual bool Add(string key, TValue item)
    
        return cache.StringSet(key, RawSerializationHelper.Serialize(item));
    

我没有创建多个此类的实例,所以这不是问题。也许我误解了连接指标,它们的真正含义是我访问缓存的次数,但是,在我看来,这并没有什么意义。有什么想法,或者有类似问题的人吗?

【问题讨论】:

【参考方案1】:

StackExchange.Redis 存在竞争条件,在某些情况下可能会导致连接泄露。这已在版本 1.0.333 或更新版本中得到修复。

如果您想确认这是您遇到的问题,请获取客户端应用程序的故障转储并在调试器中查看堆上的对象。查找大量 StackExchange.Redis.ServerEndPoint 对象。

此外,一些用户的代码中存在导致连接对象泄漏的错误。这通常是因为他们的代码在看到失败或断开状态时会尝试重新创建 ConnectionMultiplexer 对象。实际上没有必要重新创建 ConnectionMultiplexer,因为它在内部具有根据需要重新创建连接的逻辑。只需确保在连接字符串中将 abortConnect 设置为 false。

如果您决定重新创建连接对象,请确保在释放对旧对象的所有引用之前处置旧对象。

以下是我们推荐的模式:


        private static Lazy lazyConnection = new Lazy(() => 
            return ConnectionMultiplexer.Connect("contoso5.redis.cache.windows.net,abortConnect=false,ssl=true,password=...");
        );

        public static ConnectionMultiplexer Connection 
            get 
                return lazyConnection.Value;
            
        

【讨论】:

谢谢 JonCole,这就是问题所在。 1.0.333 的更新解决了这个问题。 看来问题又出在2.2.4版本了。 我可以确认。它又回到了 2.2.4。知道修复可能是什么吗?

以上是关于为啥与 Azure Redis 缓存的连接如此之高?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Swift 中的铸造成本如此之高,而不是……将其保留为 AnyObject?

Azure Redis 缓存使用注意事项与排查问题文档整理

MemCache 与 Azure 缓存

为啥redis在java是同步缓存,而在nodejs是异步缓存

idea没有配置redis链接为啥还能访问到数据

Azure Redis缓存开发