Skip to content

Commit 0e53767

Browse files
committed
dcompact_etcd: Add load_balance by weight, default is still roundrobin
1. http_worker can have `weight` which is an integer >= 1 * weight is a relative num, default is 100 * if a worker's weight is 50, it will receive 50% compactions of wokers which weight = 100 2. load_balance can be {kRoundRobin, kWeight}, default is kRoundRobin 3. schedule compactions by weight if load_balance is kWeight
1 parent c11a5bb commit 0e53767

1 file changed

Lines changed: 37 additions & 8 deletions

File tree

src/dcompact/dcompact_etcd.cc

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ struct HttpParams {
116116
std::string ca; // ca file
117117
std::string cert; // can be empty
118118
std::string key; // can be empty
119+
unsigned weight = 100;
119120

120121
struct Labour : hash_strmap<gold_hash_set<DcompactEtcdExec*> > {
121122
#if 0
@@ -154,6 +155,8 @@ struct HttpParams {
154155
if (!ca.empty() && !Slice(url).starts_with("https://")) {
155156
THROW_InvalidArgument("{url,ca}.url must be https when ca is set");
156157
}
158+
ROCKSDB_JSON_OPT_PROP(js, weight);
159+
weight = std::max(weight, 1u);
157160
}
158161
else {
159162
THROW_InvalidArgument("json must be a string or object{url,ca}");
@@ -184,12 +187,14 @@ struct HttpParams {
184187
}
185188
json ToJson() const {
186189
json js;
187-
if (ca.empty()) {
190+
if (ca.empty() && 100 == weight) {
188191
js = url;
189192
}
190193
else {
191194
ROCKSDB_JSON_SET_PROP(js, url);
192-
ROCKSDB_JSON_SET_PROP(js, ca);
195+
if (!ca.empty())
196+
ROCKSDB_JSON_SET_PROP(js, ca);
197+
ROCKSDB_JSON_SET_PROP(js, weight);
193198
}
194199
return js;
195200
}
@@ -435,6 +440,8 @@ struct DcompactFeeReport {
435440
}
436441
};
437442

443+
ROCKSDB_ENUM_CLASS(LoadBalanceType, int, kRoundRobin, kWeight);
444+
438445
class DcompactEtcdExecFactory final : public CompactExecFactoryCommon {
439446
public:
440447
Env* m_env = Env::Default();
@@ -456,6 +463,10 @@ class DcompactEtcdExecFactory final : public CompactExecFactoryCommon {
456463
int overall_timeout = 5; // in seconds
457464
int retry_sleep_time = 1; // in seconds
458465
std::shared_ptr<DcompactFeeConfig> fee_conf;
466+
valvec<unsigned> m_weight_vec;
467+
mutable std::mt19937_64 m_rand_gen;
468+
unsigned m_weight_sum = 0;
469+
LoadBalanceType load_balance = LoadBalanceType::kRoundRobin;
459470

460471
#ifdef TOPLING_DCOMPACT_USE_ETCD
461472
etcd::Client* m_etcd = nullptr;
@@ -504,7 +515,15 @@ class DcompactEtcdExecFactory final : public CompactExecFactoryCommon {
504515
else {
505516
http_workers.clear(); // if has defined in template, overwrite it
506517
HttpParams::ParseJsonToVec(js["http_workers"], &http_workers);
518+
m_weight_vec.reserve(http_workers.size());
519+
unsigned sum = 0;
520+
for (auto& x : http_workers) {
521+
sum += x->weight;
522+
m_weight_vec.push_back(sum);
523+
}
524+
m_weight_sum = sum;
507525
}
526+
ROCKSDB_JSON_OPT_ENUM(js, load_balance);
508527
ROCKSDB_JSON_OPT_PROP(js, nfs_type);
509528
ROCKSDB_JSON_OPT_PROP(js, nfs_mnt_src);
510529
ROCKSDB_JSON_OPT_PROP(js, nfs_mnt_opt);
@@ -533,14 +552,27 @@ class DcompactEtcdExecFactory final : public CompactExecFactoryCommon {
533552
}
534553
// m_round_robin_idx - start at a random idx
535554
auto seed = std::chrono::system_clock::now().time_since_epoch().count();
536-
auto rand = std::mt19937_64(seed)();
537-
m_round_robin_idx = rand % http_workers.size();
555+
m_rand_gen = std::mt19937_64(seed);
556+
m_round_robin_idx = m_rand_gen() % http_workers.size();
538557
}
539558
~DcompactEtcdExecFactory() override {
540559
#ifdef TOPLING_DCOMPACT_USE_ETCD
541560
delete m_etcd;
542561
#endif
543562
}
563+
size_t PickWorker() const {
564+
if (LoadBalanceType::kRoundRobin == load_balance) {
565+
return as_atomic(m_round_robin_idx)
566+
.fetch_add(1, std::memory_order_relaxed)
567+
% http_workers.size();
568+
} else {
569+
assert(LoadBalanceType::kWeight == load_balance);
570+
m_stat_map.m_mtx.lock();
571+
auto rand = m_rand_gen();
572+
m_stat_map.m_mtx.unlock();
573+
return lower_bound_a(m_weight_vec, rand % m_weight_sum);
574+
}
575+
}
544576
CompactionExecutor* NewExecutor(const Compaction*) const final;
545577
const char* Name() const final { return "DcompactEtcd"; }
546578
void ToJson(const json& dump_options, json& djs, const SidePluginRepo& repo) const final {
@@ -745,10 +777,7 @@ try
745777
meta.estimate_time_us = estimate_time_us;
746778
std::string meta_jstr = meta.ToJsonStr();
747779
auto t2 = m_env->NowMicros();
748-
size_t nth_http = as_atomic(f->m_round_robin_idx)
749-
.fetch_add(1, std::memory_order_relaxed)
750-
% f->http_workers.size();
751-
780+
size_t nth_http = f->PickWorker();
752781
m_start_ts = t1;
753782
const HttpParams* worker = f->http_workers[nth_http].get();
754783
const std::string old_labour_id = m_labour_id;

0 commit comments

Comments
 (0)