StackExchange.Redis超时

4nkexdtk  于 2023-01-25  发布在  Redis
关注(0)|答案(5)|浏览(193)

Production environment is on Azure, using Redis Cache Standard 2.5GB .

Example 1

System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> StackExchange.Redis.RedisTimeoutException: Timeout performing SETNX User.313123, inst: 49, mgr: Inactive, err: never, queue: 0, qu: 0, qs: 0, qc: 0, wr: 0, wq: 0, in: 0, ar: 0, clientName: PRD-VM-WEB-2, serverEndpoint: Unspecified/Construct3.redis.cache.windows.net:6380, keyHashSlot: 15649, IOCP: (Busy=0,Free=1000,Min=1,Max=1000), WORKER: (Busy=1,Free=32766,Min=1,Max=32767) (Please take a look at this article for some common client-side issues that can cause timeouts: http://stackexchange.github.io/StackExchange.Redis/Timeouts ) at StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, 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 processor, ServerEndPoint server) in c:\code\StackExchange.Redis\StackExchange.Redis\StackExchange\Redis\RedisBase.cs:line 81

Example 2

StackExchange.Redis.RedisTimeoutException: Timeout performing GET ForumTopic.33831, inst: 1, mgr: Inactive, err: never, queue: 2, qu: 0, qs: 2, qc: 0, wr: 0, wq: 0, in: 0, ar: 0, clientName: PRD-VM-WEB-2, serverEndpoint: Unspecified/Construct3.redis.cache.windows.net:6380, keyHashSlot: 5851, IOCP: (Busy=0,Free=1000,Min=1,Max=1000), WORKER: (Busy=1,Free=32766,Min=1,Max=32767) (Please take a look at this article for some common client-side issues that can cause timeouts: http://stackexchange.github.io/StackExchange.Redis/Timeouts ) at StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, 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 processor, ServerEndPoint server) in c:\code\StackExchange.Redis\StackExchange.Redis\StackExchange\Redis\RedisBase.cs:line 81 at StackExchange.Redis.RedisDatabase.StringGet(RedisKey key, CommandFlags flags) in c:\code\StackExchange.Redis\StackExchange.Redis\StackExchange\Redis\RedisDatabase.cs:line 1647 at C3.Code.Controls.Application.Caching.Distributed.DistributedCacheController.Get[T](String cacheKey) in C:\Construct.net\Source\C3Alpha2\Code\Controls\Application\Caching\Distributed\DistributedCacheController.cs:line 115 at C3.Code.Controls.Application.Caching.Manager.Manager.Get[T](String key, Func`1 getFromExternFunction, Boolean skipLocalCaches) in 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) in C:\Construct.net\Source\C3Alpha2\PageControls\Forums\TopicRender.ascx.cs:line 40 at System.Web.UI.Control.OnLoad(EventArgs e) at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
These errors are sporadic, several times a day.
Is this an Azure network blip, or something I can reduce? Looking at the numbers in the error doesn't seem anything out of the ordinary, and the server load never seems to go above 7% as reported by Azure.

Redis connection

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;
    }
fivyi3re

fivyi3re1#

有3种情况可能会导致超时,很难知道哪种情况在起作用:
1.图书馆正在被绊倒特别是,存在与TLS实现以及如何处理v1.* 版本库中的读取循环相关的已知问题-我们在v2.* 中投入了大量时间(然而:更新到v2并不总是微不足道的,特别是当您将库用作依赖于特定版本的其他代码的一部分时)
1.服务器/网络发生故障;这是一种非常真实的的可能性--如果是服务器端的话,查看“慢日志”可能会有所帮助,但是我没有任何可见性
1.服务器和网络都很好,库正在做它能做的,但是在客户端和服务器之间有一些巨大的斑点在飞行,这延迟了其他操作;这是我正在做的一些更改,以帮助识别 * 现在 *,如果这表明它本身是一个常见问题,我们可能会考虑更好地利用并发连接(这不会增加带宽,但可以减少阻塞操作的延迟)-这将是v2唯一的更改,注意

carvr3hs

carvr3hs2#

惰性连接

作为一个最佳实践,请确保您使用以下模式连接到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"/>
    *在ASP.NET之外,请使用线程池.SetMinThreads()API。
  • 在**.Net Core**中,根据Environment/Registry Configuration Knobs添加环境变量COMPlus_ThreadPool_ForceMinWorkerThreads以覆盖默认MinThreads设置-您也可以使用与上述相同的ThreadPool.SetMinThreads()方法。

来源:

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

os8fio9y3#

我的猜测是,有一个问题,网络稳定性-因此超时。
因为没有人提到responseTimeout的增加,我会尝试一下。默认值是50ms,这很容易达到。我会尝试大约200ms,看看这是否有助于消息。
取自配置选项:

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()

2021年12月14日-更新

在 * 堆栈交换. redis v2.2.4 * 中:下面给出了
"响应超时":警告CS0618 "配置选项响应超时"已过时:'此设置不再有效,不应使用
更新由MX313发送

q43xntqr

q43xntqr4#

我与这个超时错误斗争了一段时间,下面的步骤解决了我的问题:

首先,我使用Lazy<T>进行连接:

private static Lazy<ConnectionMultiplexer> lazyConnection =  new Lazy<ConnectionMultiplexer>(() =>
{
   return ConnectionMultiplexer.Connect(new ConfigurationOptions
          {
               EndPoints = { Url },
               AbortOnConnectFail = false,
               Ssl = UseSsl,
               Password = Password,
           });
});

public static ConnectionMultiplexer Connection => lazyConnection.Value;

其次,我更新了所有异步方法以同步。例如,我使用StringGetAsync,所以我用StringGet替换了它。
第三个,我更改了线程的最小数量:

public static async Task Main(string[] args)
{
   ...
   SetupThreadPool();
}

private static void SetupThreadPool()
{
     ThreadPool.GetMaxThreads(out var workerThreads, out var completionPortThreads);
     ThreadPool.SetMinThreads(workerThreads, completionPortThreads);
}

我用bombardier(-d 10 s-c 125)测试了我的API,下面是基准测试:

正如您所看到的,应用程序成功地处理了所有请求!
希望能有所帮助。祝你好运。

ql3eal8s

ql3eal8s5#

打开网络流量监视器来确认/否认这个问题。有一个简单的解决方案。选项1 -尝试在azure中重新启动托管的redis instamce。

相关问题