我在c#wcf应用程序中使用StackExchange.Redis客户端:我只使用synchronous命令来获取和设置值。问题是我对这个好奇的日志超时了:
Timeout performing EXISTS DataKey:50,
inst: 1, queue: 1, qu: 0, qs: 1, qc: 0, wr: 0, wq: 0, in: 0, ar: 0, clientName: Machine1,
serverEndpoint: redis-server:6381, keyHashSlot: 7984,
IOCP: (Busy=1,Free=799,Min=8,Max=800),
WORKER: (Busy=5,Free=795,Min=8,Max=800)
(Please take a look at this article for some common client-side issues that can
cause timeouts: http://stackexchange.github.io/StackExchange.Redis/Timeouts)
如果我理解正确,这意味着我的get值排队,因为有五个工作线程? 使用netstat,我看到我的应用程序打开了两个到服务器的物理连接。 我确保在我的线程池中有线程可用。 在我的连接设置中,我有一个syncTimeout = 3000 ... 如果我使用redis-cli,我可以在0.64 secondes中得到密钥的值。
有人可以帮忙吗?我能做什么?我是否必须在我的代码中一直使用async或者找到另一个redis客户端库?
答案 0 :(得分:3)
有一些解决方案。首先,他们在github回购中写了一篇关于他们提出的解决方案的文章,发现here。
我发现虽然只是尽可能多地使用异步函数,但只有同步函数会超时。在我看来,超时是他们的一个设计决定,基于他们不想在出现问题时阻止你的代码的想法。我不买,所以我使用的工作是使用异步功能,然后等待任务。因此,我只需db.StringGet("thestring")
代替db.StringGetAsync("thestring").Result
。也就是说,如果我因任何原因无法使用等待。
您可能希望尽可能多地使用async / await。如果您认为合适,可能还需要使用FireAndForget。您也可以使用ContinueWith。他们谈论这些解决方案here。
答案 1 :(得分:2)
从“WORKER :( Busy = 5,Free = 795,Min = 8,Max = 800)”,我看到有5个Busy工作线程,最少只有8个工作线程。我怀疑如果你看一下你收到的整个错误集,你可能会发现在某些情况下Busy大于Min计数。这表明threadpool throttling。该链接还提供了一些增加工作线程和IOCP线程的最小线程数的解决方案。
答案 2 :(得分:1)
修复RedisTimeout异常总是一个挑战,有很多因素导致超时异常,
在您的日志中,您可以看到IOCP线程有1
个忙线程,并且您的系统配置为允许8
个最小线程。所以情况并非如此,因为1
不是> 8
一旦我遇到相同的情况,我通过增加连接字符串中的syncTimeout
来修复超时异常,你可以尝试增加它
我也意识到开放连接的数量会影响Redis的性能, 您可以通过运行此命令来查看打开的连接
info clients
在抛出超时异常时我有大约90个打开的连接,我重新启动服务器以重置打开连接并且超时异常消失