我们在 Azure 中有多个 Web 和辅助角色通过 StackExchange.Redis 库连接到我们的 Azure Redis 缓存,并且我们经常收到超时,这使得我们的端到端解决方案陷入停滞。其中之一的示例如下:
System.TimeoutException:执行 GET 流超时:459,实例:4,
mgr:非活动状态,队列:12,qu=0,qs=12,qc=0,wr=0/0,in=65536/0
StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](消息
消息、结果处理器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:行
79 在 StackExchange.Redis.RedisDatabase.StringGet(RedisKey key,
CommandFlags 标志)中
c:\TeamCity\buildAgent\work\58bc9a6df18a3782\StackExchange.Redis\StackExchange\Redis\RedisDatabase.cs:行
1346 于
OptiRTC.Cache.RedisCacheActions.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`1policyStateFactory) at
OptiRTC.Cache.RedisCacheActions.Get[T](字符串键,布尔值
允许脏读)中
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,该 ConnectionMultiplexer 在 Web 或辅助角色启动中注册到我们的 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 调用包装在 Polly 重试块中后,它们会继续发生,该块处理 RedisException 和 System.TimeoutException 并在 500 毫秒后重试一次。
我们就这个问题联系了 Microsoft,他们确认在 Redis 日志中没有看到任何表明 Redis 服务端存在问题的内容。我们的缓存未命中百分比在 Redis 服务器上非常低,但我们仍然遇到这些超时,这极大地阻碍了我们应用程序的功能。
作为对评论的回应,是的,我们总是在 qs 中有一个数字,而在 qc 中从来没有。我们总是在第一部分有一个数字,而在第二部分却没有。
更多附加信息:
当我在较高的 CPU 上运行具有较少实例的服务时,与在较低的 CPU 上运行实例时相比,我收到的超时错误明显更多。更具体地说,我今天早上从我们的服务中提取了一些数据。当它们以大约 30% CPU 运行时,我发现很少有超时问题 - 30 分钟内只有 42 个。当我删除一半实例并且它们开始以大约 60-65% 的 CPU 运行时,速度在 30 分钟内增加了 10 倍,达到 536。