Manage number of new connections per cycle (#12178)

There are situations (especially in TLS) in which the engine gets too occupied managing a large number of new connections. Existing connections may time-out while the server is processing the new connections initial TLS handshakes, which may cause cause new connections to be established, perpetuating the problem. To better manage the tradeoff between new connection rate and other workloads, this change adds a new config to manage maximum number of new connections per event loop cycle, instead of using a predetermined number (currently 1000).

This change introduces two new configurations, max-new-connections-per-cycle and max-new-tls-connections-per-cycle. The default value of the tcp connections is 10 per cycle and the default value of tls connections per cycle is 1.
---------

Co-authored-by: Madelyn Olson <madelyneolson@gmail.com>
This commit is contained in:
AshMosh 2024-01-03 01:15:03 +02:00 committed by GitHub
parent 9d0158bf89
commit c3f8b542ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 30 additions and 4 deletions

View File

@ -2200,6 +2200,26 @@ rdb-save-incremental-fsync yes
# lfu-log-factor 10
# lfu-decay-time 1
# The maximum number of new client connections accepted per event-loop cycle. This configuration
# is set independently for TLS connections.
#
# By default, up to 10 new connection will be accepted per event-loop cycle for normal connections
# and up to 1 new connection per event-loop cycle for TLS connections.
#
# Adjusting this to a larger number can slightly improve efficiency for new connections
# at the risk of causing timeouts for regular commands on established connections. It is
# not advised to change this without ensuring that all clients have limited connection
# pools and exponential backoff in the case of command/connection timeouts.
#
# If your application is establishing a large number of new connections per second you should
# also consider tuning the value of tcp-backlog, which allows the kernel to buffer more
# pending connections before dropping or rejecting connections.
#
# max-new-connections-per-cycle 10
# max-new-tls-connections-per-cycle 1
########################### ACTIVE DEFRAGMENTATION #######################
#
# What is active defragmentation?

View File

@ -3198,6 +3198,8 @@ standardConfig static_configs[] = {
createUIntConfig("maxclients", NULL, MODIFIABLE_CONFIG, 1, UINT_MAX, server.maxclients, 10000, INTEGER_CONFIG, NULL, updateMaxclients),
createUIntConfig("unixsocketperm", NULL, IMMUTABLE_CONFIG, 0, 0777, server.unixsocketperm, 0, OCTAL_CONFIG, NULL, NULL),
createUIntConfig("socket-mark-id", NULL, IMMUTABLE_CONFIG, 0, UINT_MAX, server.socket_mark_id, 0, INTEGER_CONFIG, NULL, NULL),
createUIntConfig("max-new-connections-per-cycle", NULL, MODIFIABLE_CONFIG, 1, 1000, server.max_new_conns_per_cycle, 10, INTEGER_CONFIG, NULL, NULL),
createUIntConfig("max-new-tls-connections-per-cycle", NULL, MODIFIABLE_CONFIG, 1, 1000, server.max_new_tls_conns_per_cycle, 1, INTEGER_CONFIG, NULL, NULL),
#ifdef LOG_REQ_RES
createUIntConfig("client-default-resp", NULL, IMMUTABLE_CONFIG | HIDDEN_CONFIG, 2, 3, server.client_default_resp, 2, INTEGER_CONFIG, NULL, NULL),
#endif

View File

@ -40,7 +40,6 @@
#define CONN_INFO_LEN 32
#define CONN_ADDR_STR_LEN 128 /* Similar to INET6_ADDRSTRLEN, hoping to handle other protocols. */
#define MAX_ACCEPTS_PER_CALL 1000
struct aeEventLoop;
typedef struct connection connection;

View File

@ -1774,6 +1774,8 @@ struct redisServer {
int latency_tracking_enabled; /* 1 if extended latency tracking is enabled, 0 otherwise. */
double *latency_tracking_info_percentiles; /* Extended latency tracking info output percentile list configuration. */
int latency_tracking_info_percentiles_len;
unsigned int max_new_tls_conns_per_cycle; /* The maximum number of tls connections that will be accepted during each invocation of the event loop. */
unsigned int max_new_conns_per_cycle; /* The maximum number of tcp connections that will be accepted during each invocation of the event loop. */
/* AOF persistence */
int aof_enabled; /* AOF configuration */
int aof_state; /* AOF_(ON|OFF|WAIT_REWRITE) */

View File

@ -309,7 +309,8 @@ static void connSocketEventHandler(struct aeEventLoop *el, int fd, void *clientD
}
static void connSocketAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
int cport, cfd, max = MAX_ACCEPTS_PER_CALL;
int cport, cfd;
int max = server.max_new_conns_per_cycle;
char cip[NET_IP_STR_LEN];
UNUSED(el);
UNUSED(mask);

View File

@ -766,7 +766,8 @@ static void tlsEventHandler(struct aeEventLoop *el, int fd, void *clientData, in
}
static void tlsAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
int cport, cfd, max = MAX_ACCEPTS_PER_CALL;
int cport, cfd;
int max = server.max_new_tls_conns_per_cycle;
char cip[NET_IP_STR_LEN];
UNUSED(el);
UNUSED(mask);

View File

@ -92,7 +92,8 @@ static connection *connCreateAcceptedUnix(int fd, void *priv) {
}
static void connUnixAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
int cfd, max = MAX_ACCEPTS_PER_CALL;
int cfd;
int max = server.max_new_conns_per_cycle;
UNUSED(el);
UNUSED(mask);
UNUSED(privdata);