summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCheahuychou Mao <cheahuychou.mao@mongodb.com>2020-02-04 12:17:57 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-02-05 19:54:49 +0000
commitc2e39888d052972e897b4dc8c170201e8467f964 (patch)
tree3729d9922ee55a06e7f3b47b0b4f01e1146fc8ae
parentad06b5ffbc39838e92cae0b73f51d3cf5a417116 (diff)
downloadmongo-c2e39888d052972e897b4dc8c170201e8467f964.tar.gz
SERVER-45947 Make hedging server parameters settable at runtime
-rw-r--r--jstests/sharding/hedged_reads_server_parameters.js40
-rw-r--r--src/mongo/s/hedge_options_util.cpp9
-rw-r--r--src/mongo/s/hedge_options_util_test.cpp7
-rw-r--r--src/mongo/s/mongos_server_parameters.cpp32
-rw-r--r--src/mongo/s/mongos_server_parameters.h11
-rw-r--r--src/mongo/s/mongos_server_parameters.idl28
6 files changed, 77 insertions, 50 deletions
diff --git a/jstests/sharding/hedged_reads_server_parameters.js b/jstests/sharding/hedged_reads_server_parameters.js
index dab38ab6013..7cfa9d70c5a 100644
--- a/jstests/sharding/hedged_reads_server_parameters.js
+++ b/jstests/sharding/hedged_reads_server_parameters.js
@@ -8,10 +8,7 @@
*/
(function() {
-const st = new ShardingTest({
- shards: 2,
- mongosOptions: {setParameter: {maxTimeMSThresholdForHedging: 1500, hedgingDelayPercentage: 50}}
-});
+const st = new ShardingTest({shards: 2});
const dbName = "foo";
const collName = "bar";
const ns = dbName + "." + collName;
@@ -21,29 +18,42 @@ assert.commandWorked(st.s.adminCommand({enableSharding: dbName}));
st.ensurePrimaryShard(dbName, st.shard0.shardName);
assert.commandWorked(st.s.adminCommand({shardCollection: ns, key: {x: 1}}));
-// With maxTimeMS.
+assert.commandWorked(st.s.adminCommand(
+ {setParameter: 1, maxTimeMSThresholdForHedging: 1500, hedgingDelayPercentage: 50}));
+
+// With maxTimeMS < maxTimeMSThresholdForHedging, expect hedging.
assert.commandWorked(st.s.getDB(dbName).runCommand(
{query: {find: collName, maxTimeMS: 1000}, $readPreference: {mode: "nearest", hedge: {}}}));
-// Without maxTimeMS.
-st.restartMongos(0, {
- restart: true,
- setParameter: {defaultHedgingDelayMS: 800},
-});
+// With maxTimeMS > maxTimeMSThresholdForHedging, expect no hedging.
+assert.commandWorked(st.s.getDB(dbName).runCommand(
+ {query: {find: collName, maxTimeMS: 1600}, $readPreference: {mode: "nearest", hedge: {}}}));
+
+// Without maxTimeMS, expect hedging.
+assert.commandWorked(st.s.adminCommand({setParameter: 1, defaultHedgingDelayMS: 800}));
assert.commandWorked(st.s.getDB(dbName).runCommand(
{query: {count: collName}, $readPreference: {mode: "secondaryPreferred", hedge: {}}}));
-// readHedgingMode "off".
-st.restartMongos(0, {
- restart: true,
- setParameter: {readHedgingMode: "off"},
-});
+// readHedgingMode "off", expect no hedging.
+st.s.adminCommand({setParameter: 1, readHedgingMode: "off"});
assert.commandWorked(st.s.getDB(dbName).runCommand({
query: {distinct: collName, key: "x"},
$readPreference: {mode: "primaryPreferred", hedge: {}}
}));
+// Test server parameter validation.
+assert.commandFailedWithCode(st.s.adminCommand({setParameter: 1, maxTimeMSThresholdForHedging: -1}),
+ ErrorCodes.BadValue);
+assert.commandFailedWithCode(st.s.adminCommand({setParameter: 1, hedgingDelayPercentage: -1}),
+ ErrorCodes.BadValue);
+assert.commandFailedWithCode(st.s.adminCommand({setParameter: 1, hedgingDelayPercentage: 101}),
+ ErrorCodes.BadValue);
+assert.commandFailedWithCode(st.s.adminCommand({setParameter: 1, defaultHedgingDelayMS: -1}),
+ ErrorCodes.BadValue);
+assert.commandFailedWithCode(st.s.adminCommand({setParameter: 1, readHedgingMode: "invalidMode"}),
+ ErrorCodes.BadValue);
+
st.stop();
})();
diff --git a/src/mongo/s/hedge_options_util.cpp b/src/mongo/s/hedge_options_util.cpp
index 9301a416bcf..d4ffd133f65 100644
--- a/src/mongo/s/hedge_options_util.cpp
+++ b/src/mongo/s/hedge_options_util.cpp
@@ -39,14 +39,15 @@ boost::optional<executor::RemoteCommandRequestOnAny::HedgeOptions> extractHedgeO
OperationContext* opCtx, const BSONObj& cmdObj) {
const auto hedgingMode = ReadPreferenceSetting::get(opCtx).hedgingMode;
- if (gReadHedgingMode == kReadHedgingModeOn && hedgingMode && hedgingMode->getEnabled()) {
+ if (gReadHedgingMode.load() == ReadHedgingMode::kOn && hedgingMode &&
+ hedgingMode->getEnabled()) {
boost::optional<int> maxTimeMS;
if (auto cmdOptionMaxTimeMSField = cmdObj[QueryRequest::cmdOptionMaxTimeMS]) {
maxTimeMS = uassertStatusOK(QueryRequest::parseMaxTimeMS(cmdOptionMaxTimeMSField));
}
// Check if the operation is worth hedging.
- if (maxTimeMS && maxTimeMS > gMaxTimeMSThresholdForHedging) {
+ if (maxTimeMS && maxTimeMS > gMaxTimeMSThresholdForHedging.load()) {
return boost::none;
}
@@ -55,8 +56,8 @@ boost::optional<executor::RemoteCommandRequestOnAny::HedgeOptions> extractHedgeO
bool shouldDelayHedging = hedgingMode->getDelay();
if (shouldDelayHedging) {
- delay = maxTimeMS ? Milliseconds{gHedgingDelayPercentage * maxTimeMS.get() / 100}
- : Milliseconds{gDefaultHedgingDelayMS};
+ delay = maxTimeMS ? Milliseconds{gHedgingDelayPercentage.load() * maxTimeMS.get() / 100}
+ : Milliseconds{gDefaultHedgingDelayMS.load()};
}
return executor::RemoteCommandRequestOnAny::HedgeOptions{1, delay};
diff --git a/src/mongo/s/hedge_options_util_test.cpp b/src/mongo/s/hedge_options_util_test.cpp
index 1fd54e39082..1407caa6e01 100644
--- a/src/mongo/s/hedge_options_util_test.cpp
+++ b/src/mongo/s/hedge_options_util_test.cpp
@@ -112,9 +112,10 @@ protected:
static inline const BSONObj kDefaultParameters =
BSON(kReadHedgingModeFieldName
- << "on" << kMaxTimeMSThresholdForHedgingFieldName << gMaxTimeMSThresholdForHedging
- << kHedgingDelayPercentageFieldName << gHedgingDelayPercentage
- << kDefaultHedgingDelayMSFieldName << gDefaultHedgingDelayMS);
+ << "on" << kMaxTimeMSThresholdForHedgingFieldName
+ << gMaxTimeMSThresholdForHedging.load() << kHedgingDelayPercentageFieldName
+ << gHedgingDelayPercentage.load() << kDefaultHedgingDelayMSFieldName
+ << gDefaultHedgingDelayMS.load());
private:
ServiceContext::UniqueServiceContext _serviceCtx = ServiceContext::make();
diff --git a/src/mongo/s/mongos_server_parameters.cpp b/src/mongo/s/mongos_server_parameters.cpp
index de9d5507598..8adb722635b 100644
--- a/src/mongo/s/mongos_server_parameters.cpp
+++ b/src/mongo/s/mongos_server_parameters.cpp
@@ -29,18 +29,34 @@
#include "mongo/s/mongos_server_parameters.h"
+#include "mongo/base/status.h"
+#include "mongo/s/mongos_server_parameters_gen.h"
#include "mongo/util/str.h"
namespace mongo {
-/**
- * Validation callback for setParameter 'readHedgingMode'.
- */
-Status validateReadHedgingMode(const std::string& mode) {
- if (mode != kReadHedgingModeOn && mode != kReadHedgingModeOff) {
- return {ErrorCodes::BadValue,
- str::stream() << "readHedgingMode must be either \"" << kReadHedgingModeOn
- << "\" or \"" << kReadHedgingModeOff << "\""};
+namespace {
+std::string toReadHedgingModeString(ReadHedgingMode readHedgingMode) {
+ return readHedgingMode == ReadHedgingMode::kOn ? "on" : "off";
+}
+} // namespace
+
+AtomicWord<ReadHedgingMode> gReadHedgingMode{ReadHedgingMode::kOn};
+
+void HedgingModeServerParameter::append(OperationContext*,
+ BSONObjBuilder& builder,
+ const std::string& name) {
+ builder.append(name, toReadHedgingModeString(gReadHedgingMode.load()));
+}
+
+Status HedgingModeServerParameter::setFromString(const std::string& modeStr) {
+ if (modeStr == "on") {
+ gReadHedgingMode.store(ReadHedgingMode::kOn);
+ } else if (modeStr == "off") {
+ gReadHedgingMode.store(ReadHedgingMode::kOff);
+ } else {
+ return Status{ErrorCodes::BadValue,
+ str::stream() << "Unrecognized readHedgingMode '" << modeStr << "'"};
}
return Status::OK();
}
diff --git a/src/mongo/s/mongos_server_parameters.h b/src/mongo/s/mongos_server_parameters.h
index 9c2a580278b..b992e3f214c 100644
--- a/src/mongo/s/mongos_server_parameters.h
+++ b/src/mongo/s/mongos_server_parameters.h
@@ -29,18 +29,13 @@
#pragma once
+#include "mongo/platform/atomic_word.h"
#include "mongo/platform/basic.h"
-#include "mongo/base/status.h"
-
namespace mongo {
-constexpr auto kReadHedgingModeOn = "on";
-constexpr auto kReadHedgingModeOff = "off";
+enum ReadHedgingMode { kOn, kOff };
-/**
- * Validation callback for setParameter 'readHedgingMode'.
- */
-Status validateReadHedgingMode(const std::string& mode);
+extern AtomicWord<ReadHedgingMode> gReadHedgingMode;
} // namespace mongo
diff --git a/src/mongo/s/mongos_server_parameters.idl b/src/mongo/s/mongos_server_parameters.idl
index aaac5f4d2dc..00376d40cf3 100644
--- a/src/mongo/s/mongos_server_parameters.idl
+++ b/src/mongo/s/mongos_server_parameters.idl
@@ -63,35 +63,39 @@ server_parameters:
readHedgingMode:
description: >-
Enables hedged reads.
- set_at: [ startup ]
- cpp_vartype: std::string
- cpp_varname: "gReadHedgingMode"
- default: "on"
- validator:
- callback: "validateReadHedgingMode"
+ set_at: [ startup, runtime ]
+ cpp_class:
+ name: HedgingModeServerParameter
maxTimeMSThresholdForHedging:
description: >-
The upper threshold for the expected running time of an operation (maxTimeMS)
for it to be worth hedging.
- set_at: [ startup ]
- cpp_vartype: int
+ set_at: [ startup, runtime ]
+ cpp_vartype: AtomicWord<int>
cpp_varname: "gMaxTimeMSThresholdForHedging"
+ validator:
+ gte: 0
default: 5000
hedgingDelayPercentage:
description: >-
The percentage of maxTimeMS to wait for before dispatching subsequent reads.
- set_at: [ startup ]
- cpp_vartype: int
+ set_at: [ startup, runtime ]
+ cpp_vartype: AtomicWord<int>
cpp_varname: "gHedgingDelayPercentage"
+ validator:
+ gte: 0
+ lte: 100
default: 25
defaultHedgingDelayMS:
description: >-
The default wait time in milliseconds before dispatching subsequent reads if
maxTimeMS is not given.
- set_at: [ startup ]
- cpp_vartype: int
+ set_at: [ startup, runtime ]
+ cpp_vartype: AtomicWord<int>
cpp_varname: "gDefaultHedgingDelayMS"
+ validator:
+ gte: 0
default: 1250