【问题标题】:Couchbase NodeUnavailableException in .NET SDK.NET SDK 中的 Couchbase NodeUnavailableException
【发布时间】:2015-09-30 16:22:26
【问题描述】:

我们在生产代码中经常遇到这个异常,而对 Couchbase 的请求数量没有增加,服务器本身的内存压力也没有增加。 该节点已分配 30GB 的 RAM,最大使用量为 3GB,但时不时会抛出此异常。每个应用程序生命周期只打开一次存储桶,之后只执行 get 和 upsert 操作。连接初始化如下:

Config = new ClientConfiguration()
{
    Servers = serverList,

    UseSsl = false,
    DefaultOperationLifespan = 2500,
    BucketConfigs = new Dictionary<string, BucketConfiguration>
    {
        { bucketName, new BucketConfiguration
        {
            BucketName = bucketName,
            UseSsl = false,
            DefaultOperationLifespan = 2500,
            PoolConfiguration = new PoolConfiguration
            {
            MaxSize = 2000,
            MinSize = 200,
            SendTimeout = (int)Configuration.Config.Instance.CouchbaseConfig.Timeout
            }
    }}
    }
};

Cluster = new Cluster(Config);
Bucket = Cluster.OpenBucket();

您能否让我知道这个初始化是否正确,更重要的是要在 Couchbase 服务器上检查什么来找出这个问题的原因?我检查了服务器上的所有日志,但在抛出这些错误时找不到任何特别之处。

谢谢,

堆栈跟踪:

System.Exception.Couchbase exception
at ###.DataLayer.Couchbase.CouchbaseUserOperations.Get()
at ###.API.Services.BaseService`1.SetUserID()
at ###.API.Services.EventsService+<GetResponse>d__0.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start()
at ###.API.Services.EventsService.GetResponse()
at ###.API.Services.BaseService`1+<Any>d__28.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start()
at ###.API.Services.BaseService`1.Any()
at lambda_method()
at ServiceStack.Host.ServiceRunner`1.Execute()
at ServiceStack.Host.ServiceRunner`1.Process()
at ServiceStack.Host.ServiceExec`1.Execute()
at ServiceStack.Host.ServiceRequestExec`2.Execute()
at ServiceStack.Host.ServiceController.ManagedServiceExec()
at ServiceStack.Host.ServiceController+<>c__DisplayClass11.<RegisterServiceExecutor>b__f()
at ServiceStack.Host.ServiceController.Execute()
at ServiceStack.HostContext.ExecuteService()
at ServiceStack.Host.RestHandler.ProcessRequestAsync()
at ServiceStack.Host.Handlers.HttpAsyncTaskHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest()
at System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep()
at System.Web.HttpApplication+PipelineStepManager.ResumeSteps()
at System.Web.HttpApplication.BeginProcessRequestNotification()
at System.Web.HttpRuntime.ProcessRequestNotificationPrivate()
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper()
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification()
at System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion()
at System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion()
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper()
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification()
Caused by: System.Exception : Couchbase.Core.NodeUnavailableException: The node 172.31.34.105:11210 that the key was mapped to is either down or unreachable. The SDK will continue to try to connect every 1000ms. Until it can connect every operation routed to it will fail with this exception.
at ###.DataLayer.Couchbase.CouchbaseUserOperations.Get()
at ###.API.Services.BaseService`1.SetUserID()
at ###.API.Services.EventsService+<GetResponse>d__0.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start()
at ###.API.Services.EventsService.GetResponse()
at ###.API.Services.BaseService`1+<Any>d__28.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start()
at ###.API.Services.BaseService`1.Any()
at lambda_method()
at ServiceStack.Host.ServiceRunner`1.Execute()
at ServiceStack.Host.ServiceRunner`1.Process()
at ServiceStack.Host.ServiceExec`1.Execute()
at ServiceStack.Host.ServiceRequestExec`2.Execute()
at ServiceStack.Host.ServiceController.ManagedServiceExec()
at ServiceStack.Host.ServiceController+<>c__DisplayClass11.<RegisterServiceExecutor>b__f()
at ServiceStack.Host.ServiceController.Execute()
at ServiceStack.HostContext.ExecuteService()
at ServiceStack.Host.RestHandler.ProcessRequestAsync()
at ServiceStack.Host.Handlers.HttpAsyncTaskHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest()
at System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep()
at System.Web.HttpApplication+PipelineStepManager.ResumeSteps()
at System.Web.HttpApplication.BeginProcessRequestNotification()
at System.Web.HttpRuntime.ProcessRequestNotificationPrivate()
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper()
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification()
at System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion()
at System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion()
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper()
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification()

【问题讨论】:

  • 你有堆栈跟踪吗?
  • 嗨@rene。我现在用堆栈跟踪更新了这个问题。谢谢
  • 我不是 couchbase 用户,但我希望您需要查看网络连接,因此您的客户端代码或服务器端设置没有太大问题,而是您之间的网络组件之一客户端和服务器暂时拒绝连接。
  • 嗨@rene。该服务器托管在 AWS 上的一个大型实例上,具有非常高的网络吞吐量,所以我看不出这可能是什么问题,平均 ops/sec 仅为 300 左右。

标签: c# .net couchbase


【解决方案1】:

尽管问题没有完全解决,因为我们仍然遇到超时但速度较低,我们通过使用 ClusterHelper 单例实例来提高性能,如下所示:

 ClusterHelper.Initialize(
            new ClientConfiguration
            {
                Servers = serverList,
                UseSsl = false,
                DefaultOperationLifespan = 2500,
                EnableTcpKeepAlives = true,
                TcpKeepAliveTime = 1000*60*60,
                TcpKeepAliveInterval = 5000,
                BucketConfigs = new Dictionary<string, BucketConfiguration>
                {
                    {
                        "default",
                        new BucketConfiguration
                        {
                            BucketName = "default",
                            UseSsl = false,
                            Password = "",
                            PoolConfiguration = new PoolConfiguration
                            {
                                MaxSize = 50,
                                MinSize = 10
                            }
                        }
                    }
                }
            });

【讨论】:

    【解决方案2】:

    可能会针对任意数量的网络相关问题返回 NodeUnavailableException...但是,由于您提到您在 AWS 上运行,因此很可能需要在客户端上调整 TCP 保持活动设置。

    您的 MinSize 连接 (200) 如此之大,以至于您不可能全部使用它们,并且它们闲置,直到 AWS LB 决定关闭它们。发生这种情况时,SDK 会暂时将失败的节点(1000 毫秒)置于关闭状态,然后尝试重新连接。在此期间,任何映射到它的键都会因该异常而失败。

    这篇博文介绍了如何设置 TCP keep-alives 时间和间隔:http://blog.couchbase.com/introducing-couchbase-.net-sdk-2.1.0-the-asynchronous-couchbase-.net-client

    var config = new ClientConfiguration
    {
        EnableTcpKeepAlives = true, //default it true
        TcpKeepAliveTime = 1000*60*60, //set to 60mins
        TcpKeepAliveInterval = 5000 //KEEP ALIVE will be sent every 5 seconds  after 1hr
    };
    var cluster = new Cluster(config);
    var bucket = cluster.OpenBucket();
    

    假设您使用的是 2.1.0 或更高版本的客户端。如果不是,可以通过 ServicePointManager 来完成:

    //setting keep-alive time to 200 seconds
    ServicePointManager.SetTcpKeepAlive(true, 200000, 1000); 
    

    您必须将其设置为小于 AWS LB 设置的值(我相信是 60 秒)。

    您还应该将连接池的最小值和最大值设置得稍低一些,例如 5 和 10。

    【讨论】:

    • 你好@jeffrymorris。感谢您的回答,但不幸的是,您建议的更改并没有解决问题。 couchbase 服务器不在 AWS 负载均衡器下,因此不能作为源。我们还减少了连接数量,但仍然没有运气。 couchbase 服务器安装在 Ubuntu 实例上。您知道我们是否需要修改操作系统上的任何内容吗?
    • 我们监控了 TCP 连接,最少 5 个连接,最多 20 个连接,我们看到只有 3 个端口打开 (dropbox.com/s/fkw0rika8a8wtv1/…)。几分钟前有 4 个端口,当发生异常时,其中一个消失了。主要问题是它们也不会重生,当发生这种情况时,我们的数据库响应非常慢。你怎么看?
    • @RaduCotofana - 您使用的是什么版本的服务器?此外,如果您启用客户端日志记录 (docs.couchbase.com/developer/dotnet-2.1/setting-up-logging.html),您应该能够记录引发引发 NodeUnavailableException 的实际异常。响应缓慢可能是连接超时和失败,然后自行重建......大约需要 15-20 秒。
    • 我发现了这个问题,它依赖于 couchbase .NET 客户端。 SendTimeout 之前设置为 50 毫秒,而不是设置为 500 毫秒,但仍然存在问题。抛出的异常是:“操作正在进行时连接超时”。一旦发生这种情况,.NET 客户端会将连接标记为死连接,并且不会重新打开另一个连接。当前池设置为 20 分钟和 200 最大值,但应用程序开始时打开了 20 个 TCP 连接,每次发生此异常时,连接数都会减少并且永远不会回到最小值。你有这方面的知识吗?
    • 首先,我不明白为什么它会在 500 毫秒时超时,然后我不明白为什么没有重建连接
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-13
    • 1970-01-01
    • 1970-01-01
    • 2015-06-09
    • 1970-01-01
    相关资源
    最近更新 更多