diff options
author | Cheahuychou Mao <cheahuychou.mao@mongodb.com> | 2020-01-22 14:40:36 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2020-01-22 14:40:36 +0000 |
commit | 66ebefff6097f3122b121c73d034d1bcae5cf13e (patch) | |
tree | 5b02f0c2e109bbe7ac2a51f4f4bed4eb8d97bae9 | |
parent | ef35c34b92e50e0438abeb2ffc83ff1472dd7d64 (diff) | |
download | mongo-66ebefff6097f3122b121c73d034d1bcae5cf13e.tar.gz |
SERVER-45438 Create serverStatus section for hedging metrics
-rw-r--r-- | jstests/sharding/hedging_metrics_server_status.js | 64 | ||||
-rw-r--r-- | src/mongo/s/client/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/s/client/hedging_metrics.cpp | 80 | ||||
-rw-r--r-- | src/mongo/s/client/hedging_metrics.h | 73 | ||||
-rw-r--r-- | src/mongo/s/s_sharding_server_status.cpp | 18 |
5 files changed, 236 insertions, 0 deletions
diff --git a/jstests/sharding/hedging_metrics_server_status.js b/jstests/sharding/hedging_metrics_server_status.js new file mode 100644 index 00000000000..7010316f6d4 --- /dev/null +++ b/jstests/sharding/hedging_metrics_server_status.js @@ -0,0 +1,64 @@ +/* + * Tests hedging metrics in the serverStatus output. + * @tags: [requires_fcv_44] + */ +(function() { +"use strict"; + +/* + * Verifies that the server status response has the hegingMetrics fields that we expect. + */ +function verifyServerStatusFields(serverStatusResponse) { + assert(serverStatusResponse.hasOwnProperty("hedgingMetrics"), + "Expected the serverStatus response to have a 'hedgingMetrics' field\n" + + tojson(serverStatusResponse)); + assert( + serverStatusResponse.hedgingMetrics.hasOwnProperty("numTotalOperations"), + "The 'hedgingMetrics' field in serverStatus did not have the 'numTotalOperations' field\n" + + tojson(serverStatusResponse.hedgingMetrics)); + assert( + serverStatusResponse.hedgingMetrics.hasOwnProperty("numTotalHedgedOperations"), + "The 'hedgingMetrics' field in serverStatus did not have the 'numTotalHedgedOperations' field\n" + + tojson(serverStatusResponse.hedgingMetrics)); + assert( + serverStatusResponse.hedgingMetrics.hasOwnProperty("numAdvantageouslyHedgedOperations"), + "The 'hedgingMetrics' field in serverStatus did not have the 'numAdvantageouslyHedgedOperations' field\n" + + tojson(serverStatusResponse.hedgingMetrics)); +} + +/* + * Verifies that the hedgingMetrics in the server status response is equal to the expected + * hedgingMetrics. + */ +function checkServerStatusHedgingMetrics(mongosConn, expectedHedgingMetrics) { + const serverStatus = assert.commandWorked(mongosConn.adminCommand({serverStatus: 1})); + verifyServerStatusFields(serverStatus); + + assert.eq(expectedHedgingMetrics.numTotalOperations, + serverStatus.hedgingMetrics.numTotalOperations); + assert.eq(expectedHedgingMetrics.numTotalHedgedOperations, + serverStatus.hedgingMetrics.numTotalHedgedOperations); +} + +const st = new ShardingTest({shards: 2}); +const dbName = "foo"; +const collName = "bar"; +const ns = dbName + "." + collName; +const testDB = st.s.getDB(dbName); + +assert.commandWorked(st.s.adminCommand({enableSharding: dbName})); +st.ensurePrimaryShard(dbName, st.shard0.shardName); +assert.commandWorked(st.s.adminCommand({shardCollection: ns, key: {x: 1}})); + +let expectedHedgingMetrics = {numTotalOperations: 0, numTotalHedgedOperations: 0}; + +assert.commandWorked( + testDB.runCommand({query: {find: collName}, $readPreference: {mode: "primary"}})); +checkServerStatusHedgingMetrics(testDB, expectedHedgingMetrics); + +assert.commandWorked( + testDB.runCommand({query: {find: collName}, $readPreference: {mode: "nearest", hedge: {}}})); +checkServerStatusHedgingMetrics(testDB, expectedHedgingMetrics); + +st.stop(); +}()); diff --git a/src/mongo/s/client/SConscript b/src/mongo/s/client/SConscript index e11419eb79f..126545f850c 100644 --- a/src/mongo/s/client/SConscript +++ b/src/mongo/s/client/SConscript @@ -8,6 +8,7 @@ env.Library( target='sharding_client', source=[ 'shard_remote.cpp', + 'hedging_metrics.cpp', 'num_hosts_targeted_metrics.cpp', env.Idlc('shard_remote.idl')[0], ], diff --git a/src/mongo/s/client/hedging_metrics.cpp b/src/mongo/s/client/hedging_metrics.cpp new file mode 100644 index 00000000000..227e8a98e12 --- /dev/null +++ b/src/mongo/s/client/hedging_metrics.cpp @@ -0,0 +1,80 @@ +/** + * Copyright (C) 2020-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/client/hedging_metrics.h" + +namespace mongo { + +namespace { +const auto HedgingMetricsDecoration = ServiceContext::declareDecoration<HedgingMetrics>(); +} // namespace + +HedgingMetrics* HedgingMetrics::get(ServiceContext* service) { + return &HedgingMetricsDecoration(service); +} + +HedgingMetrics* HedgingMetrics::get(OperationContext* opCtx) { + return get(opCtx->getServiceContext()); +} + +long long HedgingMetrics::getNumTotalOperations() const { + return _numTotalOperations.load(); +} + +void HedgingMetrics::incrementNumTotalOperations() { + _numTotalOperations.fetchAndAdd(1); +} + +long long HedgingMetrics::getNumTotalHedgedOperations() const { + return _numTotalHedgedOperations.load(); +} + +void HedgingMetrics::incrementNumTotalHedgedOperations() { + _numTotalHedgedOperations.fetchAndAdd(1); +} + +long long HedgingMetrics::getNumAdvantageouslyHedgedOperations() const { + return _numAdvantageouslyHedgedOperations.load(); +} + +void HedgingMetrics::incrementNumAdvantageouslyHedgedOperations() { + _numAdvantageouslyHedgedOperations.fetchAndAdd(1); +} + +BSONObj HedgingMetrics::toBSON() const { + BSONObjBuilder builder; + + builder.append("numTotalOperations", _numTotalOperations.load()); + builder.append("numTotalHedgedOperations", _numTotalHedgedOperations.load()); + builder.append("numAdvantageouslyHedgedOperations", _numAdvantageouslyHedgedOperations.load()); + + return builder.obj(); +} + +} // namespace mongo diff --git a/src/mongo/s/client/hedging_metrics.h b/src/mongo/s/client/hedging_metrics.h new file mode 100644 index 00000000000..fae226f342a --- /dev/null +++ b/src/mongo/s/client/hedging_metrics.h @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2020-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 + +#include "mongo/db/operation_context.h" +#include "mongo/db/service_context.h" + +namespace mongo { + +/** + * Container for server-wide hedging metrics. + */ +class HedgingMetrics { + HedgingMetrics(const HedgingMetrics&) = delete; + HedgingMetrics& operator=(const HedgingMetrics&) = delete; + +public: + HedgingMetrics() = default; + + static HedgingMetrics* get(ServiceContext* service); + static HedgingMetrics* get(OperationContext* opCtx); + + long long getNumTotalOperations() const; + void incrementNumTotalOperations(); + + long long getNumTotalHedgedOperations() const; + void incrementNumTotalHedgedOperations(); + + long long getNumAdvantageouslyHedgedOperations() const; + void incrementNumAdvantageouslyHedgedOperations(); + + BSONObj toBSON() const; + +private: + // The number of all operations with readPreference options such that they could be hedged. + AtomicWord<long long> _numTotalOperations{0}; + + // The number of all operations that actually dispatched an additional rpc. + AtomicWord<long long> _numTotalHedgedOperations{0}; + + // The number of all operations where a rpc other than the first one fulfilled the client + // request. + AtomicWord<long long> _numAdvantageouslyHedgedOperations{0}; +}; + +} // namespace mongo diff --git a/src/mongo/s/s_sharding_server_status.cpp b/src/mongo/s/s_sharding_server_status.cpp index 0bb94bc5775..6029439d28d 100644 --- a/src/mongo/s/s_sharding_server_status.cpp +++ b/src/mongo/s/s_sharding_server_status.cpp @@ -33,6 +33,7 @@ #include "mongo/db/commands/server_status.h" #include "mongo/s/balancer_configuration.h" #include "mongo/s/catalog_cache.h" +#include "mongo/s/client/hedging_metrics.h" #include "mongo/s/client/num_hosts_targeted_metrics.h" #include "mongo/s/client/shard_registry.h" #include "mongo/s/grid.h" @@ -92,5 +93,22 @@ public: } shardingStatisticsServerStatus; +class HedgingMetricsServerStatus : public ServerStatusSection { +public: + HedgingMetricsServerStatus() : ServerStatusSection("hedgingMetrics") {} + + ~HedgingMetricsServerStatus() override = default; + + bool includeByDefault() const override { + return true; + } + + BSONObj generateSection(OperationContext* opCtx, + const BSONElement& configElement) const override { + return HedgingMetrics::get(opCtx)->toBSON(); + } + +} hedgingMetricsServerStatus; + } // namespace } // namespace mongo |