summaryrefslogtreecommitdiff
path: root/src/mongo/s/chunk_manager_refresh_bm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/s/chunk_manager_refresh_bm.cpp')
-rw-r--r--src/mongo/s/chunk_manager_refresh_bm.cpp165
1 files changed, 133 insertions, 32 deletions
diff --git a/src/mongo/s/chunk_manager_refresh_bm.cpp b/src/mongo/s/chunk_manager_refresh_bm.cpp
index 3c7f3adb6b3..c3577944fab 100644
--- a/src/mongo/s/chunk_manager_refresh_bm.cpp
+++ b/src/mongo/s/chunk_manager_refresh_bm.cpp
@@ -50,17 +50,17 @@ RoutingTableHistoryValueHandle makeStandaloneRoutingTableHistory(RoutingTableHis
ComparableChunkVersion::makeComparableChunkVersion(version));
}
+ShardId getShardId(int i) {
+ return {std::string(str::stream() << "shard_" << i)};
+}
+
ChunkRange getRangeForChunk(int i, int nChunks) {
invariant(i >= 0);
invariant(nChunks > 0);
invariant(i < nChunks);
- if (i == 0) {
- return {BSON("_id" << MINKEY), BSON("_id" << 0)};
- }
- if (i + 1 == nChunks) {
- return {BSON("_id" << (i - 1) * 100), BSON("_id" << MAXKEY)};
- }
- return {BSON("_id" << (i - 1) * 100), BSON("_id" << i * 100)};
+ auto min = (i == 0) ? BSON("_id" << MINKEY) : BSON("_id" << (i - 1) * 100);
+ auto max = (i == nChunks - 1) ? BSON("_id" << MAXKEY) : BSON("_id" << i * 100);
+ return {std::move(min), std::move(max)};
}
template <typename ShardSelectorFn>
@@ -93,21 +93,21 @@ CollectionMetadata makeChunkManagerWithShardSelector(int nShards,
boost::none /* chunkSizeBytes */,
true,
chunks);
- return CollectionMetadata(ChunkManager(ShardId("Shard0"),
+ return CollectionMetadata(ChunkManager(getShardId(0),
DatabaseVersion(UUID::gen(), Timestamp(1, 0)),
makeStandaloneRoutingTableHistory(std::move(rt)),
boost::none),
- ShardId("shard0"));
+ getShardId(0));
}
ShardId pessimalShardSelector(int i, int nShards, int nChunks) {
- return ShardId(str::stream() << "shard" << (i % nShards));
+ return getShardId(i % nShards);
}
ShardId optimalShardSelector(int i, int nShards, int nChunks) {
invariant(nShards <= nChunks);
const auto shardNum = (int64_t(i) * nShards / nChunks) % nShards;
- return ShardId(str::stream() << "shard" << shardNum);
+ return getShardId(shardNum);
}
MONGO_COMPILER_NOINLINE auto makeChunkManagerWithPessimalBalancedDistribution(int nShards,
@@ -124,35 +124,133 @@ MONGO_COMPILER_NOINLINE auto runIncrementalUpdate(const CollectionMetadata& cm,
const std::vector<ChunkType>& newChunks) {
auto rt = cm.getChunkManager()->getRoutingTableHistory_ForTest().makeUpdated(
boost::none /* timeseriesFields */, boost::none, boost::none, true, newChunks);
- return CollectionMetadata(ChunkManager(ShardId("shard0"),
+ return CollectionMetadata(ChunkManager(getShardId(0),
DatabaseVersion(UUID::gen(), Timestamp(1, 0)),
makeStandaloneRoutingTableHistory(std::move(rt)),
boost::none),
- ShardId("shard0"));
+ getShardId(0));
}
-void BM_IncrementalRefreshOfPessimalBalancedDistribution(benchmark::State& state) {
+/*
+ * Simulate a refresh of the ChunkManager where a number of chunks is migrated from one shard to
+ * another.
+ *
+ * The chunks modified in the routing table are equally spaced.
+ */
+void BM_IncrementalSpacedRefreshMoveChunks(benchmark::State& state) {
const int nShards = state.range(0);
const int nChunks = state.range(1);
+ const int nUpdates = state.range(2);
auto metadata = makeChunkManagerWithPessimalBalancedDistribution(nShards, nChunks);
- auto postMoveVersion = metadata.getChunkManager()->getVersion();
- const UUID uuid = metadata.getUUID();
+ auto lastVersion = metadata.getCollVersion();
+
std::vector<ChunkType> newChunks;
- postMoveVersion.incMajor();
- newChunks.emplace_back(uuid, getRangeForChunk(1, nChunks), postMoveVersion, ShardId("shard0"));
- postMoveVersion.incMajor();
- newChunks.emplace_back(uuid, getRangeForChunk(3, nChunks), postMoveVersion, ShardId("shard1"));
+ newChunks.reserve(nUpdates);
+ const auto updateSpacing = nChunks / nUpdates;
+ for (int i = 0; i < nUpdates; i++) {
+ const auto idx = i * updateSpacing;
+ lastVersion.incMajor();
+ newChunks.emplace_back(metadata.getUUID(),
+ getRangeForChunk(idx, nChunks),
+ lastVersion,
+ pessimalShardSelector(idx, nShards, nChunks));
+ }
- for (auto keepRunning : state) {
+ std::mt19937 g;
+ g.seed(456);
+ std::shuffle(newChunks.begin(), newChunks.end(), g);
+
+ for (auto _ : state) {
benchmark::DoNotOptimize(runIncrementalUpdate(metadata, newChunks));
}
}
-BENCHMARK(BM_IncrementalRefreshOfPessimalBalancedDistribution)
- ->Args({2, 50000})
- ->Args({2, 250000})
- ->Args({2, 500000});
+BENCHMARK(BM_IncrementalSpacedRefreshMoveChunks)
+ ->Args({4, 1, 1})
+ ->Args({4, 10, 1})
+ ->Args({4, 100, 1})
+ ->Args({4, 1000, 1})
+ ->Args({4, 10000, 1})
+ ->Args({4, 100000, 1})
+ ->Args({4, 10000, 10})
+ ->Args({4, 10000, 100})
+ ->Args({4, 10000, 1000})
+ ->Args({4, 10000, 10000});
+
+/*
+ * Simulate a refresh of the ChunkManager where a number of chunks is merged together.
+ */
+void BM_IncrementalSpacedRefreshMergeChunks(benchmark::State& state) {
+ const int nShards = state.range(0);
+ const int nChunks = state.range(1);
+ const int nUpdates = state.range(2);
+ auto metadata = makeChunkManagerWithOptimalBalancedDistribution(nShards, nChunks);
+
+ auto lastVersion = metadata.getCollVersion();
+
+ std::vector<ChunkType> newChunks;
+ newChunks.reserve(nUpdates);
+ invariant(nUpdates <= nShards);
+ const auto shardSpacing = nShards / (nUpdates + 1);
+ std::set<ShardId> shardsToMerge;
+ for (int i = 0; i < nUpdates; i++) {
+ invariant(i * shardSpacing <= nShards);
+ shardsToMerge.emplace(getShardId(i * shardSpacing));
+ }
+
+ ShardId shardId;
+ std::vector<ChunkRange> rangesToMerge;
+
+ const auto flushRanges = [&] {
+ if (rangesToMerge.empty()) {
+ return;
+ }
+
+ lastVersion.incMajor();
+ newChunks.emplace_back(
+ metadata.getUUID(),
+ ChunkRange(rangesToMerge.front().getMin(), rangesToMerge.back().getMax()),
+ lastVersion,
+ shardId);
+ rangesToMerge.clear();
+ };
+
+ for (int i = 0; i < nChunks; i++) {
+ auto nextShardId = pessimalShardSelector(i, nShards, nChunks);
+ if (nextShardId != shardId) {
+ flushRanges();
+ shardId = nextShardId;
+ }
+ if (shardsToMerge.count(shardId) == 1) {
+ rangesToMerge.emplace_back(getRangeForChunk(i, nChunks));
+ }
+ }
+ flushRanges();
+
+ std::mt19937 g;
+ g.seed(456);
+ std::shuffle(newChunks.begin(), newChunks.end(), g);
+
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(runIncrementalUpdate(metadata, newChunks));
+ }
+}
+
+/*
+ * Simulate chunks merge on a routing table of 10000 chunks partitioned among 4 shards.
+ *
+ * [ 0, 2500) -> shard0
+ * [2500, 5000) -> shard1
+ * [5000, 7500) -> shard2
+ * [7500, 10000) -> shard3
+ */
+
+BENCHMARK(BM_IncrementalSpacedRefreshMergeChunks)
+ ->Args({4, 10000, 1}) // merge all chunks on shard2
+ ->Args({4, 10000, 2}) // merge all chunks on shard2 and shard3
+ ->Args({4, 10000, 3}) // merge all chunks on shard1, shard2 and shard3
+ ->Args({4, 10000, 4}); // merge all chunks on shard1, shard2, shard3 and shard4
template <typename ShardSelectorFn>
auto BM_FullBuildOfChunkManager(benchmark::State& state, ShardSelectorFn selectShard) {
@@ -187,11 +285,11 @@ auto BM_FullBuildOfChunkManager(benchmark::State& state, ShardSelectorFn selectS
true,
chunks);
benchmark::DoNotOptimize(
- CollectionMetadata(ChunkManager(ShardId("shard0"),
+ CollectionMetadata(ChunkManager(getShardId(0),
DatabaseVersion(UUID::gen(), Timestamp(1, 0)),
makeStandaloneRoutingTableHistory(std::move(rt)),
boost::none),
- ShardId("shard0")));
+ getShardId(0)));
}
}
@@ -413,11 +511,14 @@ MONGO_INITIALIZER(RegisterBenchmarks)(InitializerContext* context) {
};
for (auto bmCase : bmCases) {
- bmCase->Args({2, 50000})
- ->Args({10, 50000})
- ->Args({100, 50000})
- ->Args({1000, 50000})
- ->Args({2, 2});
+ bmCase->Args({2, 2})
+ ->Args({1, 10000})
+ ->Args({10, 10000})
+ ->Args({100, 10000})
+ ->Args({1000, 10000})
+ ->Args({10, 10})
+ ->Args({10, 100})
+ ->Args({10, 1000});
}
}