超时问题尝试做以下操作:(StackExchange.Redis.RedisTimeoutException)
增加线程池显示:
ThreadPool.SetMinThreads(100, 100);
在GetDatabase行之前加一个代码:
connection.PreserveAsyncOrder = false;
下面就要介绍StackExchange.Redis两个神器ConnectionCounters和IProfiler
1、ConnectionCounters:通过connection.GetCounters().Interactive获得的对象之后其中有三个属性非常有用
public class ConnectionCounters
{
/// <summary>
/// Operations that have been requested, but which have not yet been sent to the server
/// </summary>
public int PendingUnsentItems { get; }
/// <summary>
/// Operations that have been sent to the server, but which are awaiting a response
/// </summary>
public int SentItemsAwaitingResponse { get; }
/// <summary>
/// Operations for which the response has been processed, but which are awaiting asynchronous completion
/// </summary>
public int ResponsesAwaitingAsyncCompletion { get; }
}
每个属性表示当前redis连接的待完成的命令当前所处的状态。
- PendingUnsentItems表示已经进行待发送队列还未发送出去的命令;
- SentItemsAwaitingResponse表示已经发送出去但还没有收到响应结果的命令;
- ResponsesAwaitingAsyncCompletion则表示已经收到响应的命令,但还没有调用TaskCompletionSource().TrySetResult()的命令。
其中PendingUnsentItems和SentItemsAwaitingResponse过大的原因基本上是因为网络阻塞了,你需要检查一下网络带宽或者redis的value是否很大。
ResponsesAwaitingAsyncCompletion则是因为await之后的代码,如上面示例中的代码,线程占用了很长的同步时间,需要优化代码和将PreserveAsyncOrder设置为false。
2、ConnectionCounters分析的是一个线程的瞬时状态,而IProfiler则可以跟踪一个请求总共执行了多少的redis命令以及他们分别使用了多长时间,具体细节请大家写代码体验。
参考文档(https://stackexchange.github.io/StackExchange.Redis/Profiling)