Mongodb driver query replica set very slow

hi,

I use this driver https://github.com/zookzook/elixir-mongodb-driver
to connect to my replica set including 3 nodes across the Internet. The connection string is

mongodb://<auth-info>@localhost:27017/<db>?authSource=<db>&w=1

As you see the connection is only to localhost. But the query is very slow:

Mongo.find(:mongo_conn_pool, <collection-name>, %{_id: <doc-string-id>})

took on average 170ms to complete! The collection contains only few hundred of small documents.

To test, I connect the data set using mongo client with same connection string above, and here is the query explain:

<dataset-name>:SECONDARY> db.<collection>.find({_id: <doc-string-id>}).explain("executionStats")
{
	"queryPlanner" : {
		"plannerVersion" : 1,
		"namespace" : "<db>.<collection>",
		"indexFilterSet" : false,
		"parsedQuery" : {
			"_id" : {
				"$eq" : <doc-string-id>
			}
		},
		"winningPlan" : {
			"stage" : "IDHACK"
		},
		"rejectedPlans" : [ ]
	},
	"executionStats" : {
		"executionSuccess" : true,
		"nReturned" : 1,
		"executionTimeMillis" : 0,
		"totalKeysExamined" : 1,
		"totalDocsExamined" : 1,
		"executionStages" : {
			"stage" : "IDHACK",
			"nReturned" : 1,
			"executionTimeMillisEstimate" : 0,
			"works" : 2,
			"advanced" : 1,
			"needTime" : 0,
			"needYield" : 0,
			"saveState" : 0,
			"restoreState" : 0,
			"isEOF" : 1,
			"keysExamined" : 1,
			"docsExamined" : 1
		}
	},
	"serverInfo" : {
		"host" : <host-name>,
		"port" : 27017,
		"version" : "4.4.1",
	},
	"ok" : 1,
	"$clusterTime" : {
		"clusterTime" : Timestamp(1607619155, 1),
		"signature" : {
			"hash" : BinData(0,"/FCwtvQs6sJq6q/3pwRZU3oBv04="),
			"keyId" : NumberLong("6886352401205297154")
		}
	},
	"operationTime" : Timestamp(1607619155, 1)
}

which is much much faster than via the mongodb driver.

To test further, I connected my app to the replica set, using the same above connection string, but this time on the primary node. The same query (via mongodb-driver), to my surprise, took only ~2ms.

My guess is, somehow the driver does not force query on the current local node? That is, when I make a query not on a primary node, the driver still contact the primary (which is about 170ms ping round trip away) to perform the query?

1 Like