我们在 Azure 中有多个 Web 和辅助角色通过 StackExchange.Redis 库连接到我们的 Azure Redis 缓存,并且我们定期收到超时,这使我们的端到端解决方案陷入停顿。其中之一的示例如下:
System.TimeoutException:执行 GET 流超时:459,inst:4,mgr:不活动,队列:12,qu=0,qs=12,qc=0,wr=0/0,in=65536/0 在 StackExchange.Redis .ConnectionMultiplexer.ExecuteSyncImpl[T](消息消息,ResultProcessor
1 processor, ServerEndPoint server) in c:\TeamCity\buildAgent\work\58bc9a6df18a3782\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.cs:line 1785 at StackExchange.Redis.RedisBase.ExecuteSync[T](Message message, ResultProcessor
1 处理器,ServerEndPoint 服务器)在 c:\TeamCity\buildAgent\work\58bc9a6df18a3782\StackExchange.Redis\StackExchange\Redis\RedisBase.cs:StackExchange.Redis.RedisDatabase 的第 79 行.StringGet(RedisKey key, CommandFlags flags) in c:\TeamCity\buildAgent\work\58bc9a6df18a3782\StackExchange.Redis\StackExchange\Redis\RedisDatabase.cs:OptiRTC.Cache.RedisCacheActions 的第 1346 行。<>c__DisplayClass41.<Get>b__3() in c:\dev\OptiRTCAzure\OptiRTC.Cache\RedisCacheActions.cs:line 104 at Polly.Retry.RetryPolicy.Implementation(Action action, IEnumerable
1 shouldRetryPredicates, Func`1 policyStateFactory) at OptiRTC.Cache.RedisCacheActions.Get[T](String key, Boolean allowDirtyRead) in c:\dev\OptiRTCAzure\OptiRTC.Cache\RedisCacheActions.cs: 第 107 行 OptiRTC.Cache.RedisCacheAccess .d__e4.MoveNext() 在 c:\dev\OptiRTCAzure\OptiRTC.Cache\RedisCacheAccess.cs:1196 行;TraceSource 'WaWorkerHost.exe' 事件
所有超时都有不同的队列和 qs 编号,但其余消息是一致的。这些 StringGet 调用跨越缓存中的不同键。在我们的每个服务中,我们使用一个带有单个 ConnectionMultiplexer 的单例缓存访问类,该类在 web 或 worker 角色启动中注册到我们的 IoC 容器:
container.RegisterInstance<ICacheAccess>(cacheAccess);
在我们的 ICacheAccess 实现中,我们正在创建多路复用器,如下所示:
ConfigurationOptions options = new ConfigurationOptions();
options.EndPoints.Add(serverAddress);
options.Ssl = true;
options.Password = accessKey;
options.ConnectTimeout = 1000;
options.SyncTimeout = 2500;
redis = ConnectionMultiplexer.Connect(options);
在整个实例中使用 redis 对象。我们有大约 20 个 Web 和辅助角色实例通过这个 ICacheAccess 实现连接到缓存,但管理控制台显示平均有 200 个并发连接到缓存。
我已经看到其他使用 StackExchange.Redis 版本 1.0.333 引用的帖子,我们正在通过 NuGet 执行此操作,但是当我查看添加的 StackExchange.Redis.dll 参考的实际版本时,它显示为 1.0.316.0。我们已经尝试添加和删除 NuGet 引用以及将其添加到新项目中,但我们总是得到版本差异。
任何见解将不胜感激。谢谢。
附加信息:
我们已经升级到 1.0.371。我们有两个服务,每个服务以不同的时间间隔访问同一个缓存对象,一个用于编辑和偶尔读取,另一个每秒读取该对象多次。两种服务都使用相同的缓存代码和 StackExchange.Redis 库版本进行部署。我几乎从未在编辑对象的服务中看到超时,但我在读取它的服务上的超时时间在 50% 到 75% 之间。超时具有与上述相同的格式,并且在将 db.StringGet 调用包装在处理 RedisException 和 System.TimeoutException 并在 500 毫秒后重试一次的 Polly 重试块中后继续发生。
我们就这个问题联系了 Microsoft,他们确认他们在 Redis 日志中没有看到任何表明 Redis 服务端存在问题的内容。我们的缓存未命中率在 Redis 服务器上非常低,但我们继续收到这些超时,这严重阻碍了我们应用程序的功能。
回应评论,是的,我们在 qs 中总是有一个数字,而在 qc 中从来没有。我们总是在 in 的第一部分有一个数字,而在第二部分从来没有。
更多附加信息:
当我在较高 CPU 上运行具有较少实例的服务时,与在较低 CPU 上运行实例时相比,我得到的这些超时错误要多得多。更具体地说,我今天早上从我们的服务中提取了一些数字。当它们以大约 30% 的 CPU 运行时,我看到的超时问题很少——30 分钟内只有 42 个。当我删除了一半的实例并且它们开始以大约 60-65% 的 CPU 运行时,30 分钟内速度增加了 10 倍,达到 536。