【问题标题】:PooledRedisClientManager not releasing connectionsPooledRedisClientManager 不释放连接
【发布时间】:2013-01-29 04:49:40
【问题描述】:

我将 json 数据列表存储在 redis 中,并使用 ServiceStack c# 客户端访问它。我本质上是在管理我自己的外键,我在其中存储了一个 zrange 的 ID,并使用我的应用程序内部的一个接口从 zrange 中提取 ID,然后从 Redis 获取底层 json 对象并将它们打包为列表以返回到我的应用程序的其他部分。

我正在使用PooledRedisClientManager,因为我预计 Redis 将托管在与执行代码的服务器不同的服务器上。

我正在使用 MSOpenTech Redis 服务器在 Windows 8 上本地完成我的所有开发工作。目前我最大的挑战是客户端连接没有被关闭。

我的 Redis 持久化器正在注入 IRedisClientManager 的实例(IoC 是 CastleWindsor)。此代码在 azure worker 角色的上下文中执行。

这就是我从 zrange 中获取项目的方式:

public class MyRedisPersister<T> : IResourcePersister<T>
{ 
    IRedisClientManager _mgr;
    public MyRedisPersister(IRedisClientManager mgr)
    {
        _mgr = mgr;
    }

    public IResourceList<T> Get<T>(string key, int offset, int count) where T
    {
        using (var redis = _clientManager.GetClient())
        {
            var itemKeys = redis.GetRangeFromSortedSet(key, offset, offset + count - 1).ToList();
            var totalItems = redis.GetSortedSetCount(key);

            if (itemKeys.Count == 0)
            {
                return new ResourceList<T>
                    {
                        Items = new List<T>(),
                        Offset = 0,
                        PageSize = 0,
                        TotalItems = 0,
                        TotalPages = 0
                    };
            }
            else
            {
                return new ResourceList<T>
                    {
                        Items = itemKeys.Select(k => redis.Get<T>(k)).ToList(),
                        Offset = offset,
                        PageSize = count,
                        TotalItems = totalItems,
                        TotalPages = (int) Math.Ceiling((float) totalItems/count)
                    };
            }
        }
    }
}

这是我用来注册IRedisClientManager的代码

var mgr = new PooledRedisClientManager(100, 10, "localhost:6379");
container.Register(Component.For<IRedisClientsManager>().Instance(mgr).LifeStyle.Singleton);

任何帮助将不胜感激。

【问题讨论】:

    标签: c# redis castle-windsor servicestack


    【解决方案1】:

    目前我最大的挑战是客户端连接没有被关闭。

    您正在使用“PooledRedisClientManager”,所以我的理解是不应关闭客户端连接,只需将其放入池中以供重用。看起来您的池大小是 100 个连接。

    您可以尝试使用 var mgr = new BasicRedisClientManager("localhost:6379") 应该处理客户端。

    【讨论】:

    • 确切地说,“池”的概念是为了重新使用连接并且在到达poolSize之前不会关闭。
    • 呃,你这么一说就明白了。我减少了池中的连接数,一切都按预期工作。不知道为什么我这么挂了....
    【解决方案2】:

    edit 不推荐使用以下方法 - 您应该依赖 IRedisClientsManager 并将所有 redis 客户端调用包装在 using() 块中,否则您将 被小鬼咬了。

    让 Windsor 与 PooledRedisClientsManager 很好地配合时,我遇到了类似的问题,最后这似乎奏效了:

            container.Register(
                Component.For<IRedisClientsManager>()
                         .Instance(redisClients)
                         .LifestyleSingleton(),
    
                Component.For<IRedisClient>()
                         .UsingFactoryMethod(c => c.Resolve<IRedisClientsManager>().GetClient(),
                                            managedExternally: true));
        }
    

    managedExternally 参数告诉 Windsor 不要尝试将停用问题应用到 IRedisClients 并让 PooledRedisClientsManager 处理回收。

    【讨论】:

    • 很好,与依赖 IRedisClientManager 相比,节省了一堆样板代码。
    • 你是救生员,这为我解决了!我整天都在调试我们的 .net => redis 设置问题,都是因为缺少 using() 语句:/
    • @nover,请注意 PooledRedisClientsManager 的一些细微问题。例如。我的存储库返回 IEnumerable 并在我的 using 块中返回 client.As.Sets["someSet"] - 这工作正常,但附加到集合的客户端已被“处理​​”回池中并将抛出当您尝试懒惰地枚举 IEnumerable 时出现奇怪的错误 - 这只会在负载下显示。
    • @DanB Thx 通知我!幸运的是,我目前对 Redis 的使用只是作为消息队列,但如果我们的使用需要扩展,我会记住它:)
    • @nover 顺便说一句,最好的参考/文档是源代码。把它放在手边。
    猜你喜欢
    • 2016-10-24
    • 2015-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    • 2014-08-06
    • 2013-05-01
    相关资源
    最近更新 更多