StackExchange.Redis.RedisTimeoutException: 等待响应超时
StackExchange.Redis.RedisTimeoutException: Timeout awaiting response
我有一个包含 6 个实例、3 个主节点和 3 个从节点的 Redis 集群。我的 ASP .NET Core 应用程序将其用作缓存。有时我会得到这样的错误:
StackExchange.Redis.RedisTimeoutException: Timeout awaiting response (outbound=0KiB, inbound=5KiB, 5504ms elapsed, timeout is 5000ms), command=GET, next: GET CRM.UsersMainService.GetUserInfoAsync.vvs1@domain.org, inst: 0, qu: 0, qs: 6, aw: False, rs: DequeueResult, ws: Idle, in: 0, in-pipe: 5831, out-pipe: 0, serverEndpoint: 5.178.85.30:7002, mgr: 9 of 10 available, clientName: f0b7b81f5ce5, PerfCounterHelperkeyHashSlot: 9236, IOCP: (Busy=0,Free=1000,Min=2,Max=1000), WORKER: (Busy=10,Free=32757,Min=2,Max=32767), v: 2.0.601.3402 (Please take a look at this article for some common client-side issues that can cause timeouts: https://stackexchange.github.io/StackExchange.Redis/Timeouts) (Most recent call last)
正如我从您的异常消息中看到的那样,您的最小工作进程数对于您的流量来说太低了。
WORKER: (Busy=10,Free=32757,Min=2,Max=32767)
发生此异常时您有 10 个繁忙的工作线程,而您有 2 个工作线程用于启动。
当您的应用程序用完可用线程来完成一项操作时,.NET 会启动一个新线程(当然,直到达到最大值)。稍等片刻,看看是否需要额外的工作线程。如果您的应用程序仍然需要工作线程,那么 .NET 会启动另一个。然后另一个,然后另一个……但这需要时间。它不会在 0 毫秒内发生。通过查看您的异常消息,我们可以看到 .NET 已经创建了 8 个额外的工作线程 (10 - 2 = 8)。在创建过程中,这个特定的 Redis 操作等待并最终超时。
您可以在应用程序开始时使用 ThreadPool.SetMinThreads(Int32, Int32)
方法来设置最小线程数。我建议您从 ThreadPool.SetMinThreads(10, 10)
开始,并在测试时对其进行调整。
补充阅读:
https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool.setminthreads
https://stackexchange.github.io/StackExchange.Redis/Timeouts.html
我有一个包含 6 个实例、3 个主节点和 3 个从节点的 Redis 集群。我的 ASP .NET Core 应用程序将其用作缓存。有时我会得到这样的错误:
StackExchange.Redis.RedisTimeoutException: Timeout awaiting response (outbound=0KiB, inbound=5KiB, 5504ms elapsed, timeout is 5000ms), command=GET, next: GET CRM.UsersMainService.GetUserInfoAsync.vvs1@domain.org, inst: 0, qu: 0, qs: 6, aw: False, rs: DequeueResult, ws: Idle, in: 0, in-pipe: 5831, out-pipe: 0, serverEndpoint: 5.178.85.30:7002, mgr: 9 of 10 available, clientName: f0b7b81f5ce5, PerfCounterHelperkeyHashSlot: 9236, IOCP: (Busy=0,Free=1000,Min=2,Max=1000), WORKER: (Busy=10,Free=32757,Min=2,Max=32767), v: 2.0.601.3402 (Please take a look at this article for some common client-side issues that can cause timeouts: https://stackexchange.github.io/StackExchange.Redis/Timeouts) (Most recent call last)
正如我从您的异常消息中看到的那样,您的最小工作进程数对于您的流量来说太低了。
WORKER: (Busy=10,Free=32757,Min=2,Max=32767)
发生此异常时您有 10 个繁忙的工作线程,而您有 2 个工作线程用于启动。
当您的应用程序用完可用线程来完成一项操作时,.NET 会启动一个新线程(当然,直到达到最大值)。稍等片刻,看看是否需要额外的工作线程。如果您的应用程序仍然需要工作线程,那么 .NET 会启动另一个。然后另一个,然后另一个……但这需要时间。它不会在 0 毫秒内发生。通过查看您的异常消息,我们可以看到 .NET 已经创建了 8 个额外的工作线程 (10 - 2 = 8)。在创建过程中,这个特定的 Redis 操作等待并最终超时。
您可以在应用程序开始时使用 ThreadPool.SetMinThreads(Int32, Int32)
方法来设置最小线程数。我建议您从 ThreadPool.SetMinThreads(10, 10)
开始,并在测试时对其进行调整。
补充阅读:
https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool.setminthreads https://stackexchange.github.io/StackExchange.Redis/Timeouts.html