我正在经历所谓的 Timeout执行HGET公司:产品:设置,inst:1,队列:8,qu = 0,qs = 8,qc = 0,wr = 0/0,in = 79/1 超时异常。
这很奇怪,因为相同的Redis实例和同一台机器存储数据,但它是一个抛出此异常的特定应用程序。 更新:实际上,同一个应用程序,上面一行从Redis接收数据。问题出在HGET
。
此外,我已将多路复用器配置的超时时间增加到6秒,但没有运气。
此外,我已检查IDatabase
实例的IsConnected
值为true
。
如何解释这些错误消息以及整个超时背后的问题是什么?
当某些代码部分获得数据库(即multiplexer.GetDatabase()
)时,我已成功修复了更改的问题。
虽然多路复用器具有每个AppDomain
的实例,如StackExchange.Redis文档中所述,但许多控制组件的反转都在他们自己的代码中创建了许多IDatabase
实例。也就是说,IDatabase
实例不会被共享。
实际代码正在执行ListRightPopLeftPush
,之后,它实例化控件组件的反转,该组件在组件实例化期间读取哈希键。如果在执行所谓的ListRightPopLeftPush
之前实例化整个组件,那么整个HashGet
将不会抛出超时异常。
即使从其他ListRightPopLeftPush
实例执行IDatabase
,它似乎也会在执行读取操作时在下一个IDatabase
实例中产生某种问题。
无论如何,我的修复没有回答这个问题。我刚刚添加了更详细的信息,让我们找到问题所在和自己的解决方案。
无论如何,上面的“修复”不会修复对Redis的进一步读取访问。我在进一步的调用中得到了相同的超时异常。现在in
例程中的60/1
参数在异常消息中显示为{{1}}。
答案 0 :(得分:6)
基于long discussion in chat,以及大量的挖掘,看起来在一些模糊的场景中,当我们做.TrySetResult
之类的事情时,TPL正在劫持专用的读者线程(我们经常这样做) )。如果您进行同步调用,这会导致即时死锁,因为如果忙于等待任务完成(它本身只能完成),它就不可能处理任何套接字数据。我们实际上有code in place specifically to prevent this,但看起来实际上强制的解决方法在其他一些场景中发生。哪个......太可怕了。我会看到我能找到的东西。但基本上,问题是当前,在一些有限的场景中,TaskCompletionSource.TrySetResult
正在赋予TPL运行同步延续的权力。这包括Task.WhenAny
。