rajvarun77 commented on code in PR #3526:
URL: https://github.com/apache/brpc/pull/3526#discussion_r3952907494
##########
src/brpc/load_balancer.cpp:
##########
@@ -30,7 +33,60 @@ DEFINE_int32(default_weight_of_wlb, 0, "Default weight value
of Weighted LoadBal
"problems when user is using wlb but forgot to set the weights of
some of their "
"downstream instances. Then these instances will be set
default_weight_of_wlb as "
"their weights. wlb policy degradation is not enabled by
default.");
+DEFINE_int64(lb_warmup_ms, 0,
+ "When positive, a server newly added to a LoadBalancer gets "
+ "lb_warmup_min_weight of its normal traffic share at first and "
+ "ramps up to 100% over this period(ms). 0 disables the warm-up");
+DEFINE_double(lb_warmup_curve, 1.0,
+ "Shape of the warm-up ramp: the weight multiplier is "
+ "max(lb_warmup_min_weight, progress^lb_warmup_curve) where
progress rises "
+ "linearly from 0 to 1 over lb_warmup_ms. Must be positive: 1
ramps "
+ "linearly, larger values keep a new server colder for longer");
BRPC_VALIDATE_GFLAG(show_lb_in_vars, PassValidate);
+BRPC_VALIDATE_GFLAG(lb_warmup_ms, PassValidate);
+DEFINE_double(lb_warmup_min_weight, 0.1,
+ "Floor of the warm-up multiplier, in (0, 1]: the share of "
+ "normal traffic a server gets right after joining, so that "
+ "it still receives a trickle and latency-based policies keep "
+ "observing it");
+static bool ValidateWarmupCurve(const char*, double v) {
+ return v > 0.0;
+}
+static bool ValidateWarmupMinWeight(const char*, double v) {
+ return v > 0.0 && v <= 1.0;
+}
+BRPC_VALIDATE_GFLAG(lb_warmup_curve, ValidateWarmupCurve);
+BRPC_VALIDATE_GFLAG(lb_warmup_min_weight, ValidateWarmupMinWeight);
+
+
+double WarmupMultiplierImpl(int64_t join_time_us, int64_t now_us) {
+ const int64_t warmup_us = FLAGS_lb_warmup_ms * 1000L;
+ if (warmup_us <= 0 || join_time_us <= 0) {
+ return 1.0;
+ }
Review Comment:
Done in ee137b27: `ValidateWarmupMs` rejects values outside [0,
INT64_MAX/1000]; covered in `flag_validation`.
##########
src/brpc/policy/weighted_round_robin_load_balancer.cpp:
##########
@@ -182,8 +183,15 @@ int WeightedRoundRobinLoadBalancer::SelectServer(const
SelectIn& in, SelectOut*
size_t remain_servers = s->server_list.size();
while (remain_servers > 0) {
SocketId server_id = GetServerInNextStride(s->server_list, filter,
tls_temp);
+ bool warmup_pass = true;
+ if (remain_servers > 1 && FLAGS_lb_warmup_ms > 0) {
+ warmup_pass = WarmupAccept(
+ s->server_list[s->server_map.at(server_id)].join_time_us,
+ in.begin_time_us);
+ }
Review Comment:
Done in ee137b27: `GetServerInNextStride` now returns the selected index via
an out-param; both `server_map.at()` lookups in `SelectServer` are gone.
##########
src/brpc/policy/consistent_hashing_load_balancer.h:
##########
@@ -47,6 +47,10 @@ class ConsistentHashingLoadBalancer : public LoadBalancer {
uint32_t hash;
ServerId server_sock;
butil::EndPoint server_addr; // To make sorting stable among all
clients
+ // Time when the server was added, for the warm-up ramp. Not part
+ // of ordering/equality so that re-adding an existing server keeps
+ // its original stamp.
Review Comment:
Done in ee137b27: comment now states that `AddBatch` merges with
`std::set_union`, so a duplicate `AddServer` keeps the existing node and its
stamp, while remove + add rebuilds the nodes with a fresh stamp.
##########
docs/cn/client.md:
##########
@@ -290,6 +290,14 @@ locality-aware,优先选择延时低的下游,直到其延时高于其他机
channel.Init("http://...", "random:min_working_instances=6 hold_seconds=10",
&options);
```
+### 慢启动(预热)
+
+新加入集群或刚重启的server往往是“冷”的(缓存未命中、JIT未编译、连接池未建立),立即承担全量流量会推高其延时甚至过载。设置-lb_warmup_ms大于0(默认为0,即关闭)后,新加入负载均衡器的server先获得一小部分正常流量份额(-lb_warmup_min_weight,默认0.1),并在该时间窗口内线性爬升到100%。该机制对rr、wrr、random、la、p2c和一致性哈希均生效:la和p2c把爬升系数乘入权重,与延时评分自然叠加而不会互相干扰;其余算法按该系数概率性地把请求转给其他server(一致性哈希转给环上的下一个节点,预热期间会有部分请求偏离原有的哈希亲和性)。
Review Comment:
Done in ee137b27: 改为“逐步爬升”。
##########
src/brpc/load_balancer.h:
##########
@@ -113,6 +113,31 @@ class LoadBalancer : public NonConstDescribable, public
Destroyable {
DECLARE_bool(show_lb_in_vars);
DECLARE_int32(default_weight_of_wlb);
+DECLARE_int64(lb_warmup_ms);
+
+double WarmupMultiplierImpl(int64_t join_time_us, int64_t now_us);
+bool WarmupAcceptImpl(int64_t join_time_us, int64_t now_us);
+
+// Slow start: while -lb_warmup_ms is positive, a server newly added to a
+// LoadBalancer serves a ramping fraction of its normal traffic share, from
+// about 10% right after joining to 100% at the end of the window. The ramp
+// restarts when a removed server is added back(naming service flap); a
+// transiently disconnected server does not change LB membership and keeps
+// its ramp. Servers added together(e.g. at channel init) ramp together and
+// keep their relative shares.
+// Returns the weight multiplier in (0, 1] for a server that joined the
+// LoadBalancer at `join_time_us'(gettimeofday_us). `now_us' <= 0 makes the
+// function read the clock itself.
+inline double WarmupMultiplier(int64_t join_time_us, int64_t now_us) {
+ return FLAGS_lb_warmup_ms <= 0 ?
+ 1.0 : WarmupMultiplierImpl(join_time_us, now_us);
+}
+
+// Probabilistic form of WarmupMultiplier for policies without changable
+// weights: returns true with probability WarmupMultiplier(...).
Review Comment:
Done in ee137b27.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]