使用StackExchange.Redis库时对Redis的超时和缓慢请求

时间:2018-12-03 20:17:08

标签: c# asp.net-core redis timeout stackexchange.redis

我们已经开始在应用程序中使用Redis来保留API响应。我选择使用StackExchange.Redis进行处理,并且在实现了保存响应的整个逻辑之后,压力测试的结果令人非常失望。该应用程序的总吞吐量降低了3-4倍!大约是550-600rps,现在大约是180rps(甚至可能更慢)。

有时在压力测试过程中根本没有例外,但有时会发生超时例外,如下所示:

Timeout awaiting response (5094ms elapsed, timeout is 5000ms), inst: 0, qs: 10, in: 65536, mgr: 10 of 10 available, IOCP: (Busy=26,Free=974,Min=8,Max=1000), WORKER: (Busy=3,Free=32764,Min=8,Max=32767), v: 2.0.513.63329 
Timeout awaiting response (5063ms elapsed, timeout is 5000ms), inst: 0, qs: 4, in: 47355, mgr: 10 of 10 available, IOCP: (Busy=40,Free=960,Min=8,Max=1000), WORKER: (Busy=34,Free=32733,Min=8,Max=32767), v: 2.0.513.63329 
The timeout was reached before the message could be written to the output buffer, and it was not sent (5000ms, inst=3, qs=3, in=10, active=HMSET), inst: 3, qs: 3, in: 10, mgr: 10 of 10 available, IOCP: (Busy=36,Free=964,Min=8,Max=1000), WORKER: (Busy=34,Free=32733,Min=8,Max=32767), v: 2.0.513.63329 

这是上一次压力测试期间发生的所有超时异常的总概览图: Statistics

我尝试实现连接池(基于TotalOutstanding属性),尝试减少对Redis的请求数量,依此类推,但这没有帮助。

我执行了SHOW LOG和LATENCY DOCTOR命令,但似乎对我们的Redis实例来说还可以(尽管我们已经按照医生的建议禁用了THP)。

我的假设是,一些非常大的API响应会阻止其他请求完成。我认为是因为高入站流量值。这是对的吗?可以做什么?我需要以某种方式分隔请求吗?

1 个答案:

答案 0 :(得分:0)

我在这里看到一个有趣的提示:

The timeout was reached before the message could be written to the output buffer

我认为,基本上,Redis告诉您清除传入的消息,因为它是您的 firehosing 数据。您创建的订阅可能范围很广。

我经历了同样的经历,最终只是将数据推送到订阅lambda上的内存缓存(又名ConcurrentQueue<T>)中,然后处理了消息,并在一个单独的,受限制的线程中进行处理,该线程将检查排队并处理内容,这是典型的生产者-消费者队列方法。此时,超时错误消失了。