|
34 | 34 | #include <platform/timeutils.h> |
35 | 35 | #include <statistics/cbstat_collector.h> |
36 | 36 | #include <utilities/logtags.h> |
37 | | -#include <array> |
38 | 37 | #include <limits> |
39 | 38 | #include <memory> |
40 | 39 | #include <optional> |
41 | | -#include <random> |
42 | 40 | #include <string> |
43 | 41 | #include <utility> |
44 | 42 |
|
@@ -2047,70 +2045,30 @@ uint16_t Warmup::getNumKVStores() { |
2047 | 2045 | } |
2048 | 2046 |
|
2049 | 2047 | void Warmup::populateShardVbStates() { |
2050 | | - uint16_t numKvs = getNumKVStores(); |
2051 | | - |
2052 | | - for (size_t i = 0; i < numKvs; i++) { |
2053 | | - std::vector<vbucket_state*> kvStoreVbStates = |
2054 | | - store.getRWUnderlyingByShard(i)->listPersistedVbuckets(); |
2055 | | - for (uint16_t j = 0; j < kvStoreVbStates.size(); j++) { |
2056 | | - if (!kvStoreVbStates[j]) { |
| 2048 | + const uint16_t numShards = getNumKVStores(); |
| 2049 | + for (uint16_t shardIdx = 0; shardIdx < numShards; ++shardIdx) { |
| 2050 | + const std::vector<vbucket_state*> curShardStates = |
| 2051 | + store.getRWUnderlyingByShard(shardIdx)->listPersistedVbuckets(); |
| 2052 | + auto& statesMap = shardVbStates[shardIdx]; |
| 2053 | + auto& statesVec = shardVbIds[shardIdx]; |
| 2054 | + |
| 2055 | + for (uint16_t vbIdx = 0; vbIdx < curShardStates.size(); ++vbIdx) { |
| 2056 | + if (!curShardStates[vbIdx]) { |
2057 | 2057 | continue; |
2058 | 2058 | } |
2059 | | - auto vb = (j * numKvs) + i; |
2060 | | - std::map<Vbid, vbucket_state>& shardVB = |
2061 | | - shardVbStates[vb % store.vbMap.getNumShards()]; |
2062 | | - shardVB.insert(std::pair<Vbid, vbucket_state>( |
2063 | | - Vbid(vb), *(kvStoreVbStates[j]))); |
| 2059 | + const Vbid vbid(vbIdx * numShards + shardIdx); |
| 2060 | + statesMap.insert({vbid, *curShardStates[vbIdx]}); |
2064 | 2061 | } |
2065 | | - } |
2066 | 2062 |
|
2067 | | - for (size_t i = 0; i < store.vbMap.shards.size(); i++) { |
2068 | | - std::vector<Vbid> activeVBs, otherVBs; |
2069 | | - std::map<Vbid, vbucket_state>::const_iterator it; |
2070 | | - for (auto shardIt : shardVbStates[i]) { |
2071 | | - Vbid vbid = shardIt.first; |
2072 | | - vbucket_state vbs = shardIt.second; |
2073 | | - if (vbs.transition.state == vbucket_state_active) { |
2074 | | - activeVBs.push_back(vbid); |
2075 | | - } else { |
2076 | | - otherVBs.push_back(vbid); |
| 2063 | + // First push all active vbuckets and then the rest |
| 2064 | + for (const auto& item : statesMap) { |
| 2065 | + if (item.second.transition.state == vbucket_state_active) { |
| 2066 | + statesVec.push_back(item.first); |
2077 | 2067 | } |
2078 | 2068 | } |
2079 | | - |
2080 | | - // Push one active VB to the front. |
2081 | | - // When the ratio of RAM to VBucket is poor (big vbuckets) this will |
2082 | | - // ensure we at least bring active data in before replicas eat RAM. |
2083 | | - if (!activeVBs.empty()) { |
2084 | | - shardVbIds[i].push_back(activeVBs.back()); |
2085 | | - activeVBs.pop_back(); |
2086 | | - } |
2087 | | - |
2088 | | - // Now the VB lottery can begin. |
2089 | | - // Generate a psudeo random, weighted list of active/replica vbuckets. |
2090 | | - // The random seed is the shard ID so that re-running warmup |
2091 | | - // for the same shard and vbucket set always gives the same output and keeps |
2092 | | - // nodes of the cluster more equal after a warmup. |
2093 | | - |
2094 | | - std::mt19937 twister(i); |
2095 | | - // Give 'true' (aka active) 60% of the time |
2096 | | - // Give 'false' (aka other) 40% of the time. |
2097 | | - std::bernoulli_distribution distribute(0.6); |
2098 | | - std::array<std::vector<Vbid>*, 2> activeReplicaSource = { |
2099 | | - {&activeVBs, &otherVBs}}; |
2100 | | - |
2101 | | - while (!activeVBs.empty() || !otherVBs.empty()) { |
2102 | | - const bool active = distribute(twister); |
2103 | | - int num = active ? 0 : 1; |
2104 | | - if (!activeReplicaSource[num]->empty()) { |
2105 | | - shardVbIds[i].push_back(activeReplicaSource[num]->back()); |
2106 | | - activeReplicaSource[num]->pop_back(); |
2107 | | - } else { |
2108 | | - // Once active or replica set is empty, just drain the other one. |
2109 | | - num = num ^ 1; |
2110 | | - while (!activeReplicaSource[num]->empty()) { |
2111 | | - shardVbIds[i].push_back(activeReplicaSource[num]->back()); |
2112 | | - activeReplicaSource[num]->pop_back(); |
2113 | | - } |
| 2069 | + for (const auto& item : statesMap) { |
| 2070 | + if (item.second.transition.state != vbucket_state_active) { |
| 2071 | + statesVec.push_back(item.first); |
2114 | 2072 | } |
2115 | 2073 | } |
2116 | 2074 | } |
|
0 commit comments