StackExchange.Redis超时

时间:2018-08-02 10:51:32

标签: azure redis timeout stackexchange.redis

生产环境使用Redis Cache Standard 2.5GB在Azure上。

示例1

  

System.Web.HttpUnhandledException(0x80004005):类型的异常   引发了“ System.Web.HttpUnhandledException”。 ->   StackExchange.Redis.RedisTimeoutException:执行SETNX的超时   User.313123,inst:49,mgr:无效,err:从不,队列:0,qu:0,qs:   0,qc:0,wr:0,wq:0,in:0,ar:0,clientName:PRD-VM-WEB-2,   serverEndpoint:未指定/Construct3.redis.cache.windows.net:6380,   keyHashSlot:15649,IOCP:(Busy = 0,Free = 1000,Min = 1,Max = 1000),WORKER:   (忙= 1,免费= 32766,最小= 1,最大= 32767)(请看一下   关于可能导致超时的一些常见客户端问题的文章:   http://stackexchange.github.io/StackExchange.Redis/Timeouts)在   StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl [T](消息   消息,ResultProcessor 1 processor, ServerEndPoint server) in c:\code\StackExchange.Redis\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.cs:line 2120 at StackExchange.Redis.RedisBase.ExecuteSync[T](Message message, ResultProcessor 1个处理器,ServerEndPoint服务器)   c:\ code \ StackExchange.Redis \ StackExchange.Redis \ StackExchange \ Redis \ RedisBase.cs:line   81

示例2

  

StackExchange.Redis.RedisTimeoutException:执行GET超时   ForumTopic.33831,inst:1,mgr:无效,err:永不,队列:2,qu:0,   qs:2,qc:0,wr:0,wq:0,in:0,ar:0,clientName:PRD-VM-WEB-2,   serverEndpoint:未指定/Construct3.redis.cache.windows.net:6380,   keyHashSlot:5851,IOCP:(Busy = 0,Free = 1000,Min = 1,Max = 1000),工作人员:   (忙= 1,免费= 32766,最小= 1,最大= 32767)(请看一下   关于可能导致超时的一些常见客户端问题的文章:   http://stackexchange.github.io/StackExchange.Redis/Timeouts)在   StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl [T](消息   消息,ResultProcessor 1 processor, ServerEndPoint server) in c:\code\StackExchange.Redis\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.cs:line 2120 at StackExchange.Redis.RedisBase.ExecuteSync[T](Message message, ResultProcessor 1个处理器,ServerEndPoint服务器)   c:\ code \ StackExchange.Redis \ StackExchange.Redis \ StackExchange \ Redis \ RedisBase.cs:line   81在StackExchange.Redis.RedisDatabase.StringGet(RedisKey键,   CommandFlags标志)   c:\ code \ StackExchange.Redis \ StackExchange.Redis \ StackExchange \ Redis \ RedisDatabase.cs:line   1647年   C3.Code.Controls.Application.Caching.Distributed.DistributedCacheController.Get [T](String   cacheKey)   C:\ Construct.net \ Source \ C3Alpha2 \ Code \ Controls \ Application \ Caching \ Distributed \ DistributedCacheController.cs:line   115时   C3.Code.Controls.Application.Caching.Manager.Manager.Get [T](字符串   键,Func`1 getFromExternFunction,布尔skipLocalCaches)   C:\ Construct.net \ Source \ C3Alpha2 \ Code \ Controls \ Application \ Caching \ Manager \ Manager.cs:line   159 at C3.PageControls.Forums.TopicRender.Page_Load(Object sender,   EventArgs e)在   C:\ Construct.net \ Source \ C3Alpha2 \ PageControls \ Forums \ TopicRender.ascx.cs:line   位于40的System.Web.UI.Control.OnLoad(EventArgs e)   System.Web.UI.Control.LoadRecursive()在   System.Web.UI.Control.LoadRecursive()在   System.Web.UI.Control.LoadRecursive()在   System.Web.UI.Control.LoadRecursive()在   System.Web.UI.Control.LoadRecursive()在   System.Web.UI.Control.LoadRecursive()在   System.Web.UI.Control.LoadRecursive()在   System.Web.UI.Page.ProcessRequestMain(布尔   includeStagesBeforeAsyncPoint,布尔值includeStagesAfterAsyncPoint)

这些错误是偶发的,每天几次。

这是Azure网络故障,还是可以减少的故障?查看错误中的数字似乎并没有什么不同,并且Azure报告服务器负载似乎从未超过7%。

重新连接

internal static class RedisController
{
    private static readonly object GetConnectionLock = new object();
    public static ConnectionMultiplexer GetConnection()
    {
        if (Global.RedisConnection == null)
        {
            lock (GetConnectionLock)
            {
                if (Global.RedisConnection == null)
                {
                    Global.RedisConnection = ConnectionMultiplexer.Connect(
                        Settings.Deployment.RedisConnectionString);
                }
            }
        }
        return Global.RedisConnection;
    }

4 个答案:

答案 0 :(得分:4)

有3种情况可能导致超时,并且很难知道发生了什么:

  1. 图书馆绊倒了;特别是,存在与TLS实施以及我们如何处理库的v1。*版本中的读取循环有关的已知问题-我们花了 lot 的时间为v2工作。 *(但是:更新到v2并非总是很简单,特别是如果您将库用作依赖于特定版本的其他代码的一部分)
  2. 服务器/网络跳闸;这是一种非常现实的可能性-如果在服务器端查看“ slowlog”会有所帮助,但我对此没有任何了解
  3. 服务器和网络都很好,而库正在尽其所能,但是客户端和服务器之间有一些巨大的斑点在传播,这延迟了其他操作;这是我正在进行更改以帮助现在识别 的内容,如果这表明它本身是一个常见问题,我们可能会考虑更好地利用并发连接(这不会增加带宽,但可以减少阻止操作的延迟)-这将是v2的唯一更改,请注意

答案 1 :(得分:3)

惰性连接

作为最佳实践,请确保使用以下模式连接到StackExchange Redis客户端:

private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() => {
    return ConnectionMultiplexer.Connect("cachename.redis.cache.windows.net,ssl=true,abortConnect=false,password=password");
});

public static ConnectionMultiplexer Connection {
    get {
        return lazyConnection.Value;
    }
}

如果上述方法不起作用,则Source 1中描述了更多调试路径,其中涉及区域,带宽和NuGet软件包版本。

IO线程

另一个选择是增加最小IO线程。通常建议将IOCP和WORKER线程的最小配置值设置为大于默认值。对于此值应该是什么,没有一个万能的指南,因为一个应用程序的正确值对于另一应用程序来说太高/太低。一个好的开始是200或300,然后根据需要进行测试和调整。

如何配置此设置:

  • ASP.NET 中,使用machine.config中<processModel>配置元素下的minIoThreads配置设置。根据Microsoft的说法,您无法通过编辑web.config来更改每个站点的值(即使您过去可以这样做),因此此处选择的值是所有.NET网站将使用的值。请注意,如果将autoConfig设置为false,则无需添加每个属性,只需放置autoConfig="false"并覆盖该值即可: <processModel autoConfig="false" minIoThreads="250" />
  

重要说明:在此配置元素中指定的值是每核设置。例如,如果您有4核计算机,并且希望在运行时将minIOThreads设置为200,则可以使用<processModel minIoThreads="50"/>

来源:

  1. Microsoft Azure - Investigating timeout exceptions in StackExchange.Redis for Azure Redis Cache
  2. StackExchange.Redis

答案 2 :(得分:0)

打开网络流量监视器以确认/拒绝该故障。有解决方案,但是很简单。选项1-尝试以天蓝色重新启动托管Redis实例。

答案 3 :(得分:0)

我的猜测是网络稳定性存在问题-超时。

由于没有人提到responseTimeout有所增加,因此我会尝试一下。默认值为 50ms ,可以轻松实现。我会尝试在 200ms 左右进行尝试,以查看这是否对消息有所帮助。

取自configuration options

responseTimeout={int}   ResponseTimeout     SyncTimeout     Time (ms) to decide whether the socket is unhealthy

在github上存在多个问题。全部结合在一起的那个大概是#871 The "network stability" / 2.0 / "pipelines" rollup issue

还有一件事:您是否尝试过使用ConnectionMultiplexer.ConnectAsync()而不是ConnectionMultiplexer.Connect()