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?

5
  • 3
    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). Commented Apr 23, 2015 at 20:12
  • 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. Commented May 31, 2015 at 17:57
  • Did you figure out how to fix your error ? Commented Jul 16, 2015 at 13:49
  • 1
    Nope :( We've gone back to 1.1 driver. Considering trying again sometime in the feature. Commented Jul 23, 2015 at 15:46
  • 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. Commented Nov 29, 2020 at 17:56

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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.
This is what fixed it for me! Thanks!
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

Comments

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

Comments

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!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.