caching - Azure Redis 缓存 - GET 调用超时

标签 caching azure redis stackexchange.redis

我们在 Azure 中有多个 Web 和辅助角色通过 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, ResultProcessor1 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, ResultProcessor1 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, IEnumerable1 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

所有超时都有不同的队列和 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 调用包装在处理 RedisException 和 System.TimeoutException 的 Polly 重试 block 中并在 500 毫秒后重试一次后,它们会继续发生。

我们就此问题联系了 Microsoft,他们确认在 Redis 日志中没有看到任何表明 Redis 服务端存在问题的内容。我们的缓存未命中百分比在 Redis 服务器上非常低,但我们仍然遇到这些超时,这极大地阻碍了我们应用程序的功能。

针对评论,是的,我们总是在 qs 中有一个数字,而在 qc 中从来没有。我们总是在第一部分有一个数字,而在第二部分却没有。

更多附加信息:

当我在较高的 CPU 上运行具有较少实例的服务时,与在较低的 CPU 上运行实例时相比,我收到的超时错误明显更多。更具体地说,我今天早上从我们的服务中提取了一些数据。当它们以大约 30% CPU 运行时,我发现很少有超时问题 - 30 分钟内只有 42 个。当我删除一半实例并且它们开始以大约 60-65% CPU 运行时,速度在 30 分钟内增加了 10 倍,达到 536。

最佳答案

我知道这个帖子已经有几个月了,但我认为我自己的经验可以在这里增加一些值(value)。我在使用 Azure Redis 缓存时遇到了同样的问题(Get 超时),但我意识到这几乎完全发生在字符串值相对较大(长度> 250K)的 Get 上。我在 Gets 和 Sets 上都实现了 gzip(当字符串值很大时),现在我几乎从未遇到超时。

即使这不能解决您的特定问题,压缩一般值以降低成本并提高性能也可能是一个很好的做法。

关于caching - Azure Redis 缓存 - GET 调用超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26489197/

相关文章:

azure - 使用 Microsoft Fakes 模拟 Azure RoleEnvironment API

azure - Azure 应用服务和 .NET Core 3.1 中长时间运行计算的合适解决方案?

azure - 在 Azure Service Fabric 中实现缓存

android - 为什么 dex 文件存储在我的应用程序的缓存目录中?

java - 在 imageLoader 的子类上调用方法

iphone - iPhone 上异步图像缓存的最佳方法是什么?

python - 收到错误代码 : SubscriptionNotFound Message: The subscription not found when trying to get data about Azure Virtual Machine?

python - 用于 nginx/uwsgi 服务器的持久内存中 Python 对象

kubernetes 上的 Redis 集群

search - 倒排索引集——查询键前缀