我们已经开始在应用程序中使用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
我尝试实现连接池(基于TotalOutstanding属性),尝试减少对Redis的请求数量,依此类推,但这没有帮助。
我执行了SHOW LOG和LATENCY DOCTOR命令,但似乎对我们的Redis实例来说还可以(尽管我们已经按照医生的建议禁用了THP)。
我的假设是,一些非常大的API响应会阻止其他请求完成。我认为是因为高入站流量值。这是对的吗?可以做什么?我需要以某种方式分隔请求吗?
答案 0 :(得分:0)
我在这里看到一个有趣的提示:
The timeout was reached before the message could be written to the output buffer
我认为,基本上,Redis告诉您清除传入的消息,因为它是您的 firehosing 数据。您创建的订阅可能范围很广。
我经历了同样的经历,最终只是将数据推送到订阅lambda上的内存缓存(又名ConcurrentQueue<T>
)中,然后处理了消息,并在一个单独的,受限制的线程中进行处理,该线程将检查排队并处理内容,这是典型的生产者-消费者队列方法。此时,超时错误消失了。