Skip to content

Commit 3758eab

Browse files
Olivier Houcharda-denoyelle
authored andcommitted
MEDIUM: lb_fwrr: Use one ebtree per thread group.
When using the round-robin load balancer, the major source of contention is the lbprm lock, that has to be held every time we pick a server. To mitigate that, make it so there are one tree per thread-group, and one lock per thread-group. That means we now have a lb_fwrr_per_tgrp structure that will contain the two lb_fwrr_groups (active and backup) as well as the lock to protect them in the per-thread lbprm struct, and all fields in the struct server are now moved to the per-thread structure too. Those changes are mostly mechanical, and brings good performances improvment, on a 64-cores AMD CPU, with 64 servers configured, we could process about 620000 requests par second, and we now can process around 1400000 requests per second.
1 parent f36f6cf commit 3758eab

4 files changed

Lines changed: 170 additions & 135 deletions

File tree

include/haproxy/backend-t.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
/* LB parameters for all algorithms, with one instance per thread-group */
148148
struct lbprm_per_tgrp {
149149
union {
150+
struct lb_fwrr_per_tgrp fwrr;
150151
};
151152
};
152153
/* LB parameters for all algorithms */

include/haproxy/lb_fwrr-t.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define _HAPROXY_LB_FWRR_T_H
2424

2525
#include <import/ebtree-t.h>
26+
#include <haproxy/thread-t.h>
2627

2728
/* This structure is used to apply fast weighted round robin on a server group */
2829
struct fwrr_group {
@@ -34,9 +35,13 @@ struct fwrr_group {
3435
int curr_weight; /* total weight of the current time range */
3536
};
3637

37-
struct lb_fwrr {
38+
struct lb_fwrr_per_tgrp {
3839
struct fwrr_group act; /* weighted round robin on the active servers */
3940
struct fwrr_group bck; /* weighted round robin on the backup servers */
41+
__decl_thread(HA_RWLOCK_T lock);
42+
};
43+
44+
struct lb_fwrr {
4045
int next_weight_act; /* total weight of the next time range on active servers, for all trees */
4146
int next_weight_bck; /* total weight of the next time range on backup servers, for all trees */
4247
};

include/haproxy/server-t.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,15 @@ struct srv_per_thread {
275275
struct srv_per_tgroup {
276276
struct queue queue; /* pending connections */
277277
struct server *server; /* pointer to the corresponding server */
278+
struct eb32_node lb_node; /* node used for tree-based load balancing */
279+
struct server *next_full; /* next server in the temporary full list */
278280
unsigned int last_other_tgrp_served; /* Last other tgrp we dequeued from */
279281
unsigned int self_served; /* Number of connection we dequeued from our own queue */
280282
unsigned int dequeuing; /* non-zero = dequeuing in progress (atomic) */
281283
unsigned int next_takeover; /* thread ID to try to steal connections from next time */
284+
struct eb_root *lb_tree; /* For LB algos with split between thread groups, the tree to be used, for each group */
285+
unsigned npos, lpos; /* next and last positions in the LB tree, protected by LB lock */
286+
unsigned rweight; /* remainder of weight in the current LB tree */
282287
} THREAD_ALIGNED(64);
283288

284289
/* Configure the protocol selection for websocket */
@@ -348,7 +353,6 @@ struct server {
348353
unsigned iweight,uweight, cur_eweight; /* initial weight, user-specified weight, and effective weight */
349354
unsigned wscore; /* weight score, used during srv map computation */
350355
unsigned next_eweight; /* next pending eweight to commit */
351-
unsigned rweight; /* remainder of weight in the current LB tree */
352356
unsigned cumulative_weight; /* weight of servers prior to this one in the same group, for chash balancing */
353357
int maxqueue; /* maximum number of pending connections allowed */
354358
unsigned int queueslength; /* Sum of the length of each queue */
@@ -381,7 +385,6 @@ struct server {
381385
*/
382386
THREAD_PAD(63);
383387
__decl_thread(HA_SPINLOCK_T lock); /* may enclose the proxy's lock, must not be taken under */
384-
unsigned npos, lpos; /* next and last positions in the LB tree, protected by LB lock */
385388
union {
386389
struct eb32_node lb_node; /* node used for tree-based load balancing */
387390
struct list lb_list; /* elem used for list-based load balancing */
@@ -392,7 +395,6 @@ struct server {
392395
int lb_lock; /* make sure we are the only one updating the server */
393396
};
394397
};
395-
struct server *next_full; /* next server in the temporary full list */
396398

397399
/* usually atomically updated by any thread during parsing or on end of request */
398400
THREAD_PAD(63);

0 commit comments

Comments
 (0)