9

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

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

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

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

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

只是在这里寻找一般指导,此时我没有需要帮助的特定代码。提前致谢。

4

1 回答 1

5

你确定所有 Redis 连接都被处理了吗?

使用 ServiceStack,和(如果您使用的是 SS Razor)Redis上的属性会自行处理,但任何时候您自己从池中请求连接时,您必须自己处理它。ServiceViewPageBase

然而,尽管如此,我们最近也遇到了池中所有连接都耗尽的问题。我的一位同事发现没有对 Razor 页面进行适当的清理,并在此处提出了拉取请求——这意味着自 ServiceStack v4.0.21 以来,仅对 Razor 页面进行了正确的处理。我尚未检查该修复程序是否已向后移植到 v3 分支。

我的同事还补充说TrackingRedisClientsManager,这可能会帮助您追查不当处置。看这里

您还可以PooledRedisClientManager 使用此辅助方法检查 a 的统计信息。我们把它放在一个小剃刀页面上,以检查我们认为合适的统计信息),但您也可以围绕它编写更好的代码来监控特定节点的池运行状况。

于 2014-06-30T23:10:10.247 回答