MongoDB C# 2.0 TimeoutException
Asked Answered
H

4

12

We've recently upgraded our web application to MongoDB C# Driver 2.0 and deployed to production. Below a certain load, the application runs fine. Once the load on the production server exceeds a certain limit, the CPU of the application instantly falls down to 0 and after about 30 seconds, this exception is logged several times:

System.TimeoutException message: A timeout occured after 30000ms selecting a server using CompositeServerSelector{ Selectors = ReadPreferenceServerSelector{ ReadPreference = { Mode = Primary, TagSets = System.Collections.Generic.List`1[MongoDB.Driver.TagSet] } }, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 } }. Client view of cluster state is { ClusterId : "1", Type : "Standalone", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/10.4.0.113:27017" }", EndPoint: "Unspecified/10.4.0.113:27017", State: "Disconnected", Type: "Unknown" }] }.
stack trace:
at MongoDB.Driver.Core.Clusters.Cluster.ThrowTimeoutException(IServerSelector selector, ClusterDescription description)
at MongoDB.Driver.Core.Clusters.Cluster.<WaitForDescriptionChangedAsync>d__18.MoveNext()
--- End of stack trace

We are using a singleton MongoClient object, which is initiated like this:

private static object _syncRoot = new object();

private static MongoClient _client;
private static IMongoDatabase _database;

private IMongoDatabase GetDatabase()
{
    ...

    if (_client == null)
    {
        lock (_syncRoot)
        {
            if (_client == null)
            {
                _client = new MongoClient(
                    new MongoClientSettings
                    {
                        Server = new MongoServerAddress(host, port),
                        Credentials = new[] { credentials },
                    });

                _database = _client.GetDatabase("proddb");
                return _database;
            }
        }
    }
    return _database;
}

public IMongoCollection<T> GetCollection<T>(string name)
{
    return GetDatabase().GetCollection<T>(name);
}

A typical call to database looks like this:

public async Task<MongoItem> GetById(string id)
{
    var collection = _connectionManager.GetCollection<MongoItem>("items");
    var fdb = new FilterDefinitionBuilder<MongoItem>();
    var f = fdb.Eq(mi => mi.Id, id);
    return await collection.Find(f).FirstOrDefaultAsync();
}

How can we discover the reason and fix this issue?

Hollow answered 23/4, 2015 at 19:26 Comment(5)
this is going to take a lot more diagnosis. Can you file a ticket under the CSHARP project at jira.mongodb.org? I can tell you to begin with that the exception tells us that we are no longer connected to the server. Something has happened that caused us to lose connectivity. So, one thing I'd like to see is the logs from the server (it appears as though you only have 1 running in standalone mode).Skidway
I get the same timeout exception every time in my ASP.NET MVC app but using the same library from a console app, I never see it.Luckey
Did you figure out how to fix your error ?Condorcet
Nope :( We've gone back to 1.1 driver. Considering trying again sometime in the feature.Hollow
This was a long time ago, but I'm experiencing the same issue after a driver upgrade. Using a singleton, problem only occurs under load. No issue for years with 1.x but with 2.11 suddenly a log full of timeout errors (that often work when retried) during peak load.Gallous
S
6

This post may help:

I figured it out. This JIRA ticket has the details.

Effectively, we've made a distinction between connecting to a standalone server and connecting directly to a replica set member, where the latter is relatively uncommon. Unfortunately, MongoLab's Single-Node settings are actually a single node replica set and this causes us to not trust it. You can fix this by appending ?connect=replicaSet to your connection string. It will force the driver to move into replica set mode and all will work.

We are going to re-consider CSHARP-1160 in light of this. Thanks so much for reporting and let me know if appending ?connect=replicaSet to your connection string doesn't work.

Slacken answered 21/8, 2015 at 8:20 Comment(2)
This is a case where the issue is consistently occurring and relevant to mongolab since mongolab treats single nodes as replica sets. We host our own mongodb and ours is "not a connecting to mongodb" problem, it is a problem that only occur under heavy load.Hollow
This is what fixed it for me! Thanks!Fechter
M
2

I was experiencing the same issue using driver v2.2.4. After upgrading to v2.3.0, the issue seems to have been resolved

Mitsukomitt answered 9/11, 2016 at 10:17 Comment(0)
M
2

This issue relates to CSHARP-1435, CSHARP-1515 and CSHARP-1538 bug reports, and most likely this has been fixed in the recent C# MongoDB Driver.

This issue could be related to reading number of documents being returned more than one fit in a single batch.source

So possible solutions are:

  • Make sure your MongoDB is up and running.source
  • Check MongoDB logs for any additional details.
  • If connecting to group of mongod processes (see: replication), add ?connect=replicaSet to your connection string. For example:

    mongodb://db1.example.net:27017,db2.example.net:2500/?replicaSet=test&connectTimeoutMS=300000
    

    Example ConnectionStrings.config file:

    <connectionStrings>
          <add name="MongoDB" connectionString="mongodb://10.0.80.231:27017,10.0.108.31:27017/?replicaSet=groupname&amp;connectTimeoutMS=600000&amp;socketTimeoutMS=600000" />
          <add name="RedisCache" connectionString="www-redis.foo.cache.amazonaws.com:6379" />
          <add name="SqlConnection" connectionString="server=api.foo.eu-west-1.rds.amazonaws.com;database=foo;uid=sqlvpc;pwd=somepass;" providerName="System.Data.SqlClient"  />
    </connectionStrings>
    

    Related: CSHARP-1160, How to include ampersand in connection string?

    If above won't work, check: C# MongoDB Driver Ignores timeout options.

  • Try upgrading MongoDB.Driver as per above bug reports.

  • Try increasing connect and socket timeouts.

    Either by appending ?connectTimeoutMS=60000&socketTimeoutMS=60000 to your connection string. See: mongoDB Connection String Options.

    Alternatively changing settings in your code (e.g. connecttimeout, maxpoolsize, waitQueueSize and waitQueueTimeout). See the example here.

  • Check connection string whether you're including the database properly.source
  • Increasing a delay between each query in case of rapid calls to MongoDB.source

Please also check for MongoDB Compatibility for MongoDB C#/.NET drivers:

C#/.NET Driver Version, MongoDB C#/.NET driver compatibility

Mure answered 16/10, 2017 at 16:27 Comment(0)
E
0

I had this same problem when I was using the free (version 2.6) sandbox in MongoLab and the timeout issue went away when I started using a paid-for cluster.

I was going to say that I thought the issue was that only MongoDB version 3.0+ is supported (because I found some docs saying as much, and I swear I went through the 3.0 upgrade process via MongoLab), but when I went to search for the documentation, it now says 2.6 is supported and my paid MongoLab DB still says it's version 2.6.9.

I think I must be going crazy, but at least my code is working now!

Excruciation answered 6/8, 2015 at 0:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.