stackexchange.redis-无法解释的超时异常问题

drkbr07n  于 2021-06-09  发布在  Redis
关注(0)|答案(2)|浏览(600)

我们在.net core 3.1与azure redis缓存的集成中遇到问题。引发的异常为
执行请求时发生未处理的异常。“,”@l“:”error“,”@x“:”stackexchange.redis.redistimeoutexception:等待响应超时(出站=1403kib,入站=5657kib,已用15000ms,超时为15000ms),command=eval,next:eval,inst:0,qu:0,qs:709,aw:true,rs:readasync,ws:writing,in:0,服务端点:redis-scr-mns-dev.redis.cache.windows。net:6380,mc:1/1/0,mgr:10/10可用,clientname:,iocp:(忙=0,空闲=1000,最小=4,最大=1000),worker:(忙=7,空闲=32760,最小=4,最大=32767),v:2.1.58.34321(请参阅本文,了解一些可能导致超时的常见客户端问题:https://stackexchange.github.io/stackexchange.redis/timeouts)
是的,我已经读过这篇文章了,我们正在使用stackexchange.redis nuget包,最新版本。我们已经采取的步骤是
使用多个值设置最小线程池计数(threadpool.setminthreads(short.maxvalue,short.maxvalue);)
将redis timeout值从默认的5秒增加到15秒(说实话,再高一点也解决不了问题,因为您会读得更深入一些:)
你问的是什么设置?
.net core 3.1 rest api在最新的iis上运行,在具有16gb ram的4核windows服务器上具有3个工作线程设置(在cpu或内存的监控方面没有看到任何极端情况)
已连接到azure redis缓存。目前运行的基本c5具有高网络带宽和23gb内存(以前是较低的,所以我们尝试扩展这个)
最后将请求推送到azure服务总线(没有问题)
一个批处理进程正在运行和处理10000个api调用(几个api),其中的一个在redis缓存上崩溃,出现超时异常。其他api运行正常,没有超时,但当前正在连接到不同的redis缓存(只是为了隔离此api的行为)所有api和/或批处理程序都使用具有缓存实现的自定义nuget包,因此我们确信这不会是该1 api(所有共享代码)中的实现问题。
我们如何使用缓存?好吧,通过依赖注入,我们注入isharedcachestore,这只是我们自己的接口,我们把它放在idistributedcache之上,以确保只有异步调用可用,还有rediscache,这是使用redis实现的(isharedcachestore是为了将来使用其他缓存机制)我们使用microsoft.extensions.caching.stackexchangeredis,版本3.1.5,启动时注册是

services.Configure<CacheConfiguration>(options => configuration?.GetSection("CacheConfiguration").Bind(options))
            .AddStackExchangeRedisCache(s =>
                {
                    s.Configuration = connectionString;
                })
            .AddTransient<IRedisCache, RedisCache>()
            .AddTransient<ISharedCacheStore, SharedCacheStore>();

老实说,我们没有主意了。我们看不到azure中的redis缓存示例有任何问题,因为当我们得到超时时,这个示例甚至还没有接近它的顶部。在较低的定价计划中,服务器负载达到80%左右,而在较高的定价计划中,服务器负载甚至没有达到当前计划的10%。
根据insights的数据,我们在运行时每分钟有4000次缓存命中,导致了大约10%的服务器负载。
更新:值得一提的是,批处理和api现在运行在本地环境中,而不是云环境。移动到云计算是计划在未来几个月。这也适用于其他api连接到redis缓存而不给出问题
比较
另一个azureredis缓存在没有任何问题的情况下(从本地)每分钟获得45k次点击
这一次甚至达到了每分钟10公里的命中率

9o685dep

9o685dep1#

所以,我们发现了这个问题。这个问题存在于我们的类的注册中,如上面的原始代码所示。将其改为addscoped时,性能要快得多。甚至想知道它是否可以是独生子女。奇怪的是addtransient应该增加“connected clients”,事实上确实如此,但是它对可以处理的请求数量的影响更大。因为我们在处理过程中从未达到最大连接数限制。

.AddScoped<IRedisCache, RedisCache>()
        .AddScoped<ISharedCacheStore, SharedCacheStore>();

使用这段代码而不是addtransient,我们在4-5分钟内完成了22万次操作,没有问题,而使用旧代码,由于超时异常,我们甚至没有完成40 000次操作

ujv3wf0j

ujv3wf0j2#

这里有一些可能的事情:
我不知道那是什么 EVAL 正在做;可能是正在执行的lua导致了阻塞;唯一确定的方法就是看 SLOWLOG ,但我不知道这是否在azure redis上公开
这可能是你的有效载荷正在饱和可用带宽-我不知道你在传输什么
它可能只是一个网络/套接字暂停/中断;它们会发生,尤其是在云计算环境下,而且(相对)高的延迟使得这种情况特别痛苦
我们希望启用一个新的可选池(而不是多路复用)模型;从理论上讲(概念验证非常有效)这将避免大量的积压,这意味着即使套接字失败:只影响一个调用,而不是导致一系列失败;限制这一点的因素是我们的时间(而且,这需要与redis提供商的任何许可影响相平衡;例如,并发连接是否有上限)
它可能只是库代码中的一个bug;如果是这样,我们在这里看不到它,但是我们没有使用与您相同的设置;我们尽我们所能,但很难诊断我们看不到的问题,这些问题只出现在别人的成本设置中,我们无法轻易复制;最后:这不是我们的日常工作:(
我不认为这里有一个简单的“添加这一行,一切都会变得很好”的答案。这些都是非常重要的远程场景,需要大量的调查。而且很简单:azure的人不会为我们的时间买单。

相关问题