summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mongo/s/SConscript2
-rw-r--r--src/mongo/s/mongos_options.idl16
-rw-r--r--src/mongo/s/pre_warm_connection_pool_impl.cpp37
-rw-r--r--src/mongo/s/pre_warm_connection_pool_impl.h41
-rw-r--r--src/mongo/s/server.cpp5
-rw-r--r--src/mongo/s/sharding_initialization.cpp85
-rw-r--r--src/mongo/s/sharding_initialization.h6
7 files changed, 192 insertions, 0 deletions
diff --git a/src/mongo/s/SConscript b/src/mongo/s/SConscript
index 0376952c50e..8e71a31c4db 100644
--- a/src/mongo/s/SConscript
+++ b/src/mongo/s/SConscript
@@ -105,11 +105,13 @@ env.Library(
source=[
'sharding_initialization.cpp',
'sharding_task_executor_pool_controller.cpp',
+ 'pre_warm_connection_pool_impl.cpp',
env.Idlc('sharding_task_executor_pool.idl')[0],
'client/sharding_connection_hook.cpp',
'client/sharding_network_connection_hook.cpp',
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/executor/async_multicaster',
'$BUILD_DIR/mongo/s/catalog/dist_lock_catalog_impl',
'$BUILD_DIR/mongo/s/catalog/replset_dist_lock_manager',
'$BUILD_DIR/mongo/s/catalog/sharding_catalog_client_impl',
diff --git a/src/mongo/s/mongos_options.idl b/src/mongo/s/mongos_options.idl
index f92d2474fad..5c8033a24b0 100644
--- a/src/mongo/s/mongos_options.idl
+++ b/src/mongo/s/mongos_options.idl
@@ -31,10 +31,26 @@ global:
cpp_namespace: "mongo"
cpp_includes:
- "mongo/s/mongos_options.h"
+ - "mongo/s/pre_warm_connection_pool_impl.h"
configs:
section: "Sharding options"
source: [ yaml, cli, ini ]
+server_parameters:
+ warmMinConnectionsInShardingTaskExecutorPoolOnStartup:
+ description: <-
+ Enables prewarming of the connection pool.
+ set_at: [ startup ]
+ cpp_varname: "gWarmMinConnectionsInShardingTaskExecutorPoolOnStartup"
+ default: true
+
+ warmMinConnectionsInShardingTaskExecutorPoolOnStartupWaitMS:
+ description: <-
+ How long to wait for all hosts to have at least one connection.
+ set_at: [ startup ]
+ cpp_varname: "gWarmMinConnectionsInShardingTaskExecutorPoolOnStartupWaitMS"
+ default: 2000 # 2secs
+
configs:
"sharding.configDB":
description: >-
diff --git a/src/mongo/s/pre_warm_connection_pool_impl.cpp b/src/mongo/s/pre_warm_connection_pool_impl.cpp
new file mode 100644
index 00000000000..4721498be63
--- /dev/null
+++ b/src/mongo/s/pre_warm_connection_pool_impl.cpp
@@ -0,0 +1,37 @@
+/**
+ * Copyright (C) 2019-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/s/pre_warm_connection_pool_impl.h"
+
+namespace mongo {
+
+bool gWarmMinConnectionsInShardingTaskExecutorPoolOnStartup = true;
+int gWarmMinConnectionsInShardingTaskExecutorPoolOnStartupWaitMS = 2000;
+
+} // namespace mongo
diff --git a/src/mongo/s/pre_warm_connection_pool_impl.h b/src/mongo/s/pre_warm_connection_pool_impl.h
new file mode 100644
index 00000000000..f5b4a5dfbe0
--- /dev/null
+++ b/src/mongo/s/pre_warm_connection_pool_impl.h
@@ -0,0 +1,41 @@
+/**
+ * Copyright (C) 2019-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#pragma once
+
+namespace mongo {
+/**
+ * Set parameters used to control whether or not the mongos attempts to warm up the connection
+ * pool on start up and for how long it should try.
+ */
+
+extern bool gWarmMinConnectionsInShardingTaskExecutorPoolOnStartup;
+extern int gWarmMinConnectionsInShardingTaskExecutorPoolOnStartupWaitMS;
+
+} // namespace mongo
diff --git a/src/mongo/s/server.cpp b/src/mongo/s/server.cpp
index c43f6528798..3ac128f4794 100644
--- a/src/mongo/s/server.cpp
+++ b/src/mongo/s/server.cpp
@@ -426,6 +426,11 @@ Status initializeSharding(OperationContext* opCtx) {
return status;
}
+ status = preWarmConnectionPool(opCtx);
+ if (!status.isOK()) {
+ return status;
+ }
+
Grid::get(opCtx)->setShardingInitialized();
return Status::OK();
diff --git a/src/mongo/s/sharding_initialization.cpp b/src/mongo/s/sharding_initialization.cpp
index 29da54a9a30..4dc7372960e 100644
--- a/src/mongo/s/sharding_initialization.cpp
+++ b/src/mongo/s/sharding_initialization.cpp
@@ -44,9 +44,12 @@
#include "mongo/db/server_options.h"
#include "mongo/db/service_context.h"
#include "mongo/db/time_proof_service.h"
+#include "mongo/executor/async_multicaster.h"
#include "mongo/executor/connection_pool.h"
+#include "mongo/executor/connection_pool_stats.h"
#include "mongo/executor/network_interface_factory.h"
#include "mongo/executor/network_interface_thread_pool.h"
+#include "mongo/executor/scoped_task_executor.h"
#include "mongo/executor/task_executor.h"
#include "mongo/executor/task_executor_pool.h"
#include "mongo/executor/thread_pool_task_executor.h"
@@ -56,12 +59,14 @@
#include "mongo/s/catalog/dist_lock_catalog_impl.h"
#include "mongo/s/catalog/replset_dist_lock_manager.h"
#include "mongo/s/catalog/sharding_catalog_client_impl.h"
+#include "mongo/s/catalog/type_shard.h"
#include "mongo/s/catalog_cache.h"
#include "mongo/s/client/num_hosts_targeted_metrics.h"
#include "mongo/s/client/shard_factory.h"
#include "mongo/s/client/sharding_network_connection_hook.h"
#include "mongo/s/cluster_identity_loader.h"
#include "mongo/s/grid.h"
+#include "mongo/s/pre_warm_connection_pool_impl.h"
#include "mongo/s/query/cluster_cursor_manager.h"
#include "mongo/s/sharding_task_executor.h"
#include "mongo/s/sharding_task_executor_pool_controller.h"
@@ -141,6 +146,26 @@ std::unique_ptr<TaskExecutorPool> makeShardingTaskExecutorPool(
return executorPool;
}
+/**
+ * Uses an AsyncMulticaster to ping all of the hosts in order to establish
+ * ShardingTaskExecutorPoolMinSize connections. This does not wait
+ * for the connections to be established nor does it check how many were established.
+ */
+void preWarmConnections(OperationContext* opCtx, std::vector<HostAndPort> allHosts) {
+ auto const grid = Grid::get(opCtx);
+ auto arbi = grid->getExecutorPool()->getArbitraryExecutor();
+ auto executor = executor::ScopedTaskExecutor(arbi);
+ executor::AsyncMulticaster::Options options;
+
+ auto results =
+ executor::AsyncMulticaster(*executor, options)
+ .multicast(allHosts,
+ "admin",
+ BSON("ping" << 1),
+ opCtx,
+ Milliseconds(gWarmMinConnectionsInShardingTaskExecutorPoolOnStartupWaitMS));
+}
+
} // namespace
std::unique_ptr<executor::TaskExecutor> makeShardingTaskExecutor(
@@ -245,4 +270,64 @@ Status waitForShardRegistryReload(OperationContext* opCtx) {
return {ErrorCodes::ShutdownInProgress, "aborting shard loading attempt"};
}
+Status preWarmConnectionPool(OperationContext* opCtx) {
+ if (!gWarmMinConnectionsInShardingTaskExecutorPoolOnStartup) {
+ return Status::OK();
+ }
+
+ if (serverGlobalParams.clusterRole == ClusterRole::ConfigServer) {
+ log() << "Pre-warming pooled connections for config server is disabled";
+ return Status::OK();
+ }
+
+ // Should not be called by mongod
+ invariant(serverGlobalParams.clusterRole != ClusterRole::ShardServer);
+
+ Timer timer;
+ std::vector<HostAndPort> allHosts;
+ auto const grid = Grid::get(opCtx);
+ auto allShardsStatus =
+ grid->catalogClient()->getAllShards(opCtx, repl::ReadConcernLevel::kMajorityReadConcern);
+ if (!allShardsStatus.isOK()) {
+ return allShardsStatus.getStatus();
+ }
+ auto allShards = allShardsStatus.getValue().value;
+
+ for (auto& shard : allShards) {
+ auto connStrStatus = ConnectionString::parse(shard.getHost());
+ if (!connStrStatus.isOK()) {
+ return connStrStatus.getStatus();
+ }
+ auto connStr = connStrStatus.getValue();
+ for (const auto& hostEntry : connStr.getServers()) {
+ allHosts.push_back(hostEntry);
+ }
+ }
+
+ if (allHosts.empty()) {
+ log() << "No hosts found to pre-warm connections to";
+ return Status::OK();
+ }
+ log() << "Pre-warming connections to " << allHosts.size() << " hosts";
+
+ try {
+ opCtx->runWithDeadline(
+ opCtx->getServiceContext()->getPreciseClockSource()->now() +
+ Milliseconds(gWarmMinConnectionsInShardingTaskExecutorPoolOnStartupWaitMS),
+ ErrorCodes::ExceededTimeLimit,
+ [&] { preWarmConnections(opCtx, allHosts); });
+ } catch (const ExceptionFor<ErrorCodes::ExceededTimeLimit>&) {
+ // if we've timed out, eat the exception and continue
+ } catch (const DBException& ex) {
+ warning() << "Connection pool pre-warm failure " << causedBy(ex.toStatus()) << ", timeMs "
+ << timer.millis();
+ return ex.toStatus();
+ }
+
+ if (timer.millis() > gWarmMinConnectionsInShardingTaskExecutorPoolOnStartupWaitMS / 2) {
+ log() << "Slow connection pool pre-warm, timeMs " << timer.millis();
+ }
+ return Status::OK();
+}
+
} // namespace mongo
diff --git a/src/mongo/s/sharding_initialization.h b/src/mongo/s/sharding_initialization.h
index 8f306dbde9a..56c5f652ddd 100644
--- a/src/mongo/s/sharding_initialization.h
+++ b/src/mongo/s/sharding_initialization.h
@@ -89,4 +89,10 @@ Status initializeGlobalShardingState(OperationContext* opCtx,
Status waitForShardRegistryReload(OperationContext* opCtx);
+/**
+ * Warms up connections to shards with best effort strategy.
+ */
+
+Status preWarmConnectionPool(OperationContext* opCtx);
+
} // namespace mongo