【发布时间】:2017-08-08 09:25:42
【问题描述】:
我有一个在 AWS ECS 的 linux 容器中运行的 ASP.Net Core Web API。此 API 主要从 Redis 获取数据,但如果数据库不存在,则会回退到数据库(我们已经设计了 99.99% 的数据在 Redis 缓存中的位置)。我有一个相当高的负载,大约 1-2K RPS(对你们中的一些人来说可能是中到小;-)。
此 API 通过 MGET(从 20 到 60 的任意位置)为每个请求查找多个密钥。一切都是异步的,没有同步代码或等待或其他容易死锁的代码。 RPS 上升得越多,事情就会变得越来越慢。我也试过 PreserveAsyncOrder = false,但这似乎更糟。
我认为我的 Redis 服务器(位于 Elasticache 中)不是问题,指标显示 CPU 利用率只有 1%。此外,我创建的容器实例越多,延迟下降的越多,我不希望看到服务器是否是瓶颈。
我听说 TPL 和 SE.Redis 存在潜在的线程劫持问题(不确定它是否已修复,或者是否适用于 .Net Core),所以我尝试将所有内容移动到同步而不是异步(尽管我的网络api 调用仍然是异步的,但我对 SE.Redis 的调用是同步的)。这导致了实际的超时,而不是仅仅需要一段时间:
执行 MGET 超时,inst: 5, queue: 199, qu: 0, qs: 199, qc: 0, wr: 0, wq: 0, in: 150304, ar: 0, clientName: , serverEndpoint: 10.55。 148.227:6379,keyHashSlot:-2
因为这是 .Net Core,所以超时异常提供的信息似乎比完整堆栈少,我看不到工作线程或 IOCP 线程的数量以查看那里是否存在瓶颈。
随着越来越多的超时发生,queue/qs: number 和 in: number 一样上升。
数量让我相信我只是没有足够快地处理它而得到响应,我会成为线程劫持问题的牺牲品吗?或者我的客户可能是网络绑定的?
我也尝试过为 redis 连接创建一个连接池,如 SE.Redis 超时页面所示。非常小的改进,但仍然面临同样的问题。
任何帮助将不胜感激。
【问题讨论】:
标签: performance redis asp.net-core .net-core stackexchange.redis