MEDIUM: fwlc: re-enable per-server queuing up to maxqueue

Leastconn has the nice propery of being able to sort servers by their
current usage. It's really a shame to force all requests into the backend
queue when the algo would be able to also consider their current queue.

In order not to change existing behavior but extend it, this patch allows
leastconn to elect servers which are already full if they have an explicitly
configured maxqueue setting above zero and their queue hasn't reached that
threshold. This will significantly reduce the pressure in the backend queue
when queuing a lot with lots of servers.

A test on 8 threads with 100 servers configured with maxconn 1 jumped
from 165krps to 330krps with maxqueue 15 with this patch.

This partially undoes commit 82cd5c13a ("OPTIM: backend: skip LB when we
know the backend is full") but allows to scale much better even by setting
a single-digit maxqueue value. Some better heuristics could be used to
maintain the behavior of the bypass in the patch above, consisting in
keeping it if it's known that there is no server with a configured
maxqueue in the farm (or in the backend).
This commit is contained in:
Willy Tarreau 2020-10-22 17:19:07 +02:00
parent 8c855f6cff
commit 8ae8c48eb0
3 changed files with 9 additions and 5 deletions

View File

@ -13452,9 +13452,13 @@ maxqueue <maxqueue>
will wait in the queue for this server. If this limit is reached, next
requests will be redispatched to other servers instead of indefinitely
waiting to be served. This will break persistence but may allow people to
quickly re-log in when the server they try to connect to is dying. The
default value is "0" which means the queue is unlimited. See also the
"maxconn" and "minconn" parameters.
quickly re-log in when the server they try to connect to is dying. Some load
balancing algorithms such as leastconn take this into account and accept to
add requests into a server's queue up to this value if it is explicitly set
to a value greater than zero, which often allows to better smooth the load
when dealing with single-digit maxconn values. The default value is "0" which
means the queue is unlimited. See also the "maxconn" and "minconn" parameters
and "balance leastconn".
max-reuse <count>
The "max-reuse" argument indicates the HTTP connection processors that they

View File

@ -652,7 +652,7 @@ int assign_server(struct stream *s)
* know it's because all servers are full.
*/
if (s->be->nbpend &&
(((s->be->lbprm.algo & BE_LB_KIND) == BE_LB_KIND_CB) || // conn-based: leastconn & first
(((s->be->lbprm.algo & (BE_LB_KIND|BE_LB_NEED|BE_LB_PARM)) == BE_LB_ALGO_FAS)|| // first
((s->be->lbprm.algo & (BE_LB_KIND|BE_LB_NEED|BE_LB_PARM)) == BE_LB_ALGO_RR) || // roundrobin
((s->be->lbprm.algo & (BE_LB_KIND|BE_LB_NEED|BE_LB_PARM)) == BE_LB_ALGO_SRR))) { // static-rr
err = SRV_STATUS_FULL;

View File

@ -323,7 +323,7 @@ struct server *fwlc_get_next_server(struct proxy *p, struct server *srvtoavoid)
struct server *s;
s = eb32_entry(node, struct server, lb_node);
if (!s->maxconn || (!s->nbpend && s->served < srv_dynamic_maxconn(s))) {
if (!s->maxconn || s->served + s->nbpend < srv_dynamic_maxconn(s) + s->maxqueue) {
if (s != srvtoavoid) {
srv = s;
break;