我们在 Azure 中有多个 Web 和 worker 角色通过 StackExchange.Redis 库连接到我们的 Azure Redis 缓存,并且我们收到定期超时,这使我们的端到端解决方案陷入停顿。其中之一的示例如下:
System.TimeoutException: Timeout performing GET stream:459, inst: 4, mgr: Inactive, queue: 12, qu=0, qs=12, qc=0, wr=0/0, in=65536/0 at StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, 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 processor, ServerEndPoint server) in c:\TeamCity\buildAgent\work\58bc9a6df18a3782\StackExchange.Redis\StackExchange\Redis\RedisBase.cs:line 79 at StackExchange.Redis.RedisDatabase.StringGet(RedisKey key, CommandFlags flags) in c:\TeamCity\buildAgent\work\58bc9a6df18a3782\StackExchange.Redis\StackExchange\Redis\RedisDatabase.cs:line 1346 at 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`1 policyStateFactory) at OptiRTC.Cache.RedisCacheActions.Get[T](String key, Boolean allowDirtyRead) in c:\dev\OptiRTCAzure\OptiRTC.Cache\RedisCacheActions.cs:line 107 at OptiRTC.Cache.RedisCacheAccess.d__e4.MoveNext() in c:\dev\OptiRTCAzure\OptiRTC.Cache\RedisCacheAccess.cs:line 1196; TraceSource 'WaWorkerHost.exe' event
所有的timeout都有不同的queue和qs numbers,但是其余的消息是一致的。这些 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 个网络和 worker 角色实例通过这个 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 的 Polly 重试 block 中并在 500 毫秒后重试一次后继续发生。
我们就此问题联系了 Microsoft,他们确认他们在 Redis 日志中看不到任何表明 Redis 服务端存在问题的信息。我们的缓存未命中率在 Redis 服务器上非常低,但我们继续遇到这些超时,这极大地阻碍了我们应用程序的功能。
回应评论,是的,我们总是在 qs 中有一个数字,而在 qc 中从来没有。我们总是在 in 的第一部分有一个数字,而在第二部分从来没有。
更多附加信息:
当我在较高 CPU 上运行实例较少的服务时,与实例在较低 CPU 上运行时相比,我得到的这些超时错误要多得多。更具体地说,我今天早上从我们的服务中提取了一些数字。当它们以大约 30% 的 CPU 运行时,我几乎没有看到超时问题——30 分钟内只有 42 个。当我删除一半的实例并且它们开始以大约 60-65% 的 CPU 运行时,速率在 30 分钟内增加了 10 倍,达到 536。
最佳答案
我知道这个帖子已经有几个月了,但我认为我自己的经验可以在这里增加一些值(value)。我在使用 Azure Redis 缓存(Gets 超时)时遇到了同样的问题,但我意识到它几乎只发生在字符串值相对较大(> 250K 长度)的 Gets 上。我在 Gets 和 Sets 上实现了 gzip(当字符串值很大时),现在我几乎从来没有超时过。
即使这不能解决您的特定问题,压缩一般值以降低成本和提高性能可能是一种很好的做法。
关于caching - Azure Redis 缓存 - GET 调用超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26489197/