如何使用ServiceStack最好地管理Redis连接?

时间:2013-09-23 16:01:42

标签: redis servicestack connection-pooling

我在一些.NET Web应用程序上工作,这些应用程序使用Redis进行大量缓存以及ServiceStack的Redis客户端。在所有情况下,我都在同一台机器上运行Redis。我已经使用了 BasicRedisClientManager PooledRedisClientManager (总是以单例形式实现),并且两种方法都存在一些问题。

使用 BasicRedisClientManager ,事情会好一段时间,但最终Redis会开始拒绝连接。使用netstat,我们发现有数千个到默认Redis端口的TCP连接处于TIME_WAIT状态。

然后我们切换到 PooledRedisClientManager ,这似乎可以立即解决问题。但是,不久之后,我们开始注意到偶尔的CPU峰值,我们缩小到由PooledRedisClientManager.GetClient引起的线程等待(System.Threading.Monitor.Wait调用)。

在代码中,我们使用get-in-get-out方法(使用ServiceStack方便的ExecAs快捷方式),因此通常会非常频繁地获取连接,但会尽可能短暂地进行连接。

我们获得了适量的流量,但我们没有StackExchange,我不禁认为ServiceStack客户端能胜任工作,我们只是做错了。 PooledRedisClientManager是正确的方法吗?简单地增加池大小是否可取?或者这可能只是掩盖了我们代码的问题?

在这里寻找一般指导,我目前没有需要帮助的具体代码。提前谢谢。

1 个答案:

答案 0 :(得分:5)

您是否绝对确定所有Redis连接都已被处置?

使用ServiceStack,RedisService上的ViewPageBase属性(如果您使用的是SS Razor)会自行处理,但是只要您自己请求从池中连接,必须自己处理。

然而,尽管如此,我们最近还遇到了问题,我们的游泳池也因为所有连接而耗尽。我的一位同事发现没有正确清理Razor页面并发出拉取请求here - 这意味着自ServiceStack v4.0.21以来,Razor页面上只有正确的处理方式。我没有检查该修复程序是否已经反向移植到v3分支。

我的同事还添加了TrackingRedisClientsManager,可以帮助您找到不当处置方式。见here

您还可以查看PooledRedisClientManager by using this helper method的统计信息。我们把它扔在一个小剃刀页面上,以检查我们认为合适的统计数据)但你可以编写更好的代码来监控特定节点的池健康状况。