From 1f65c011d167b5555695b4b728896dbb11aa6756 Mon Sep 17 00:00:00 2001 From: Daniel Salzman Date: Thu, 22 Jul 2021 15:28:24 +0200 Subject: [PATCH] conf: add adaptive lmdb readers setting based on current configuration --- src/knot/conf/base.h | 10 +++++++++- src/knot/conf/conf.c | 15 ++++++++++----- src/knot/conf/conf.h | 22 ++++++++++++++++++++++ src/knot/conf/schema.c | 6 +++--- src/knot/journal/knot_lmdb.c | 7 ++++--- src/knot/server/server.c | 4 ++++ 6 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/knot/conf/base.h b/src/knot/conf/base.h index d87ed12238..9cb1a4c7cf 100644 --- a/src/knot/conf/base.h +++ b/src/knot/conf/base.h @@ -31,8 +31,16 @@ #define CONF_DEFAULT_DBDIR (STORAGE_DIR "/confdb") /*! Maximum depth of nested transactions. */ #define CONF_MAX_TXN_DEPTH 5 + +/*! Maximum number of UDP workers. */ +#define CONF_MAX_UDP_WORKERS 256 +/*! Maximum number of TCP workers. */ +#define CONF_MAX_TCP_WORKERS 256 +/*! Maximum number of background workers. */ +#define CONF_MAX_BG_WORKERS 512 /*! Maximum number of concurrent DB readers. */ -#define CONF_MAX_DB_READERS 630 +#define CONF_MAX_DB_READERS (CONF_MAX_UDP_WORKERS + CONF_MAX_TCP_WORKERS + \ + CONF_MAX_BG_WORKERS + 128 /* XDP workers */) /*! Configuration specific logging. */ #define CONF_LOG(severity, msg, ...) do { \ diff --git a/src/knot/conf/conf.c b/src/knot/conf/conf.c index fb626d28ce..35595bb4b3 100644 --- a/src/knot/conf/conf.c +++ b/src/knot/conf/conf.c @@ -40,8 +40,8 @@ #define DBG_LOG(err) CONF_LOG(LOG_DEBUG, "%s (%s)", __func__, knot_strerror((err))); -#define DFLT_TCP_WORKERS_MIN 10 -#define DFLT_BG_WORKERS_MAX 10 +#define DFLT_MIN_TCP_WORKERS 10 +#define DFLT_MAX_BG_WORKERS 10 #define FALLBACK_MAX_TCP_CLIENTS 100 bool conf_db_exists( @@ -1142,8 +1142,9 @@ size_t conf_udp_threads_txn( { conf_val_t val = conf_get_txn(conf, txn, C_SRV, C_UDP_WORKERS); int64_t workers = conf_int(&val); + assert(workers <= CONF_MAX_UDP_WORKERS); if (workers == YP_NIL) { - return dt_optimal_size(); + return MIN(dt_optimal_size(), CONF_MAX_UDP_WORKERS); } return workers; @@ -1155,8 +1156,10 @@ size_t conf_tcp_threads_txn( { conf_val_t val = conf_get_txn(conf, txn, C_SRV, C_TCP_WORKERS); int64_t workers = conf_int(&val); + assert(workers <= CONF_MAX_TCP_WORKERS); if (workers == YP_NIL) { - return MAX(dt_optimal_size(), DFLT_TCP_WORKERS_MIN); + size_t optimal = MAX(dt_optimal_size(), DFLT_MIN_TCP_WORKERS); + return MIN(optimal, CONF_MAX_TCP_WORKERS); } return workers; @@ -1191,8 +1194,10 @@ size_t conf_bg_threads_txn( { conf_val_t val = conf_get_txn(conf, txn, C_SRV, C_BG_WORKERS); int64_t workers = conf_int(&val); + assert(workers <= CONF_MAX_BG_WORKERS); if (workers == YP_NIL) { - return MIN(dt_optimal_size(), DFLT_BG_WORKERS_MAX); + assert(DFLT_MAX_BG_WORKERS <= CONF_MAX_BG_WORKERS); + return MIN(dt_optimal_size(), DFLT_MAX_BG_WORKERS); } return workers; diff --git a/src/knot/conf/conf.h b/src/knot/conf/conf.h index 9f257e6fd1..68463a10c6 100644 --- a/src/knot/conf/conf.h +++ b/src/knot/conf/conf.h @@ -749,6 +749,28 @@ static inline size_t conf_bg_threads( return conf_bg_threads_txn(conf, &conf->read_txn); } +/*! + * Gets the required LMDB readers limit based on the current configuration. + * + * \note The resulting value is a common limit to journal, kasp, timers, + * and catalog databases. So it's over-estimated for simpicity reasons. + * + * \note This function cannot be used for the configuration database setting :-/ + * + * \param[in] conf Configuration. + * + * \return Number of readers. + */ +static inline size_t conf_lmdb_readers( + conf_t *conf) +{ + if (conf == NULL) { // Return default in tests. + return 126; + } + return conf_udp_threads(conf) + conf_tcp_threads(conf) + + conf_bg_threads(conf) + conf_xdp_threads(conf); +} + /*! * Gets the configured maximum number of TCP clients. * diff --git a/src/knot/conf/schema.c b/src/knot/conf/schema.c index b26ef0a70e..d87548b0de 100644 --- a/src/knot/conf/schema.c +++ b/src/knot/conf/schema.c @@ -184,9 +184,9 @@ static const yp_item_t desc_server[] = { { C_RUNDIR, YP_TSTR, YP_VSTR = { RUN_DIR } }, { C_USER, YP_TSTR, YP_VNONE }, { C_PIDFILE, YP_TSTR, YP_VSTR = { "knot.pid" } }, - { C_UDP_WORKERS, YP_TINT, YP_VINT = { 1, 255, YP_NIL } }, - { C_TCP_WORKERS, YP_TINT, YP_VINT = { 1, 255, YP_NIL } }, - { C_BG_WORKERS, YP_TINT, YP_VINT = { 1, 255, YP_NIL } }, + { C_UDP_WORKERS, YP_TINT, YP_VINT = { 1, CONF_MAX_UDP_WORKERS, YP_NIL } }, + { C_TCP_WORKERS, YP_TINT, YP_VINT = { 1, CONF_MAX_TCP_WORKERS, YP_NIL } }, + { C_BG_WORKERS, YP_TINT, YP_VINT = { 1, CONF_MAX_BG_WORKERS, YP_NIL } }, { C_ASYNC_START, YP_TBOOL, YP_VNONE }, { C_TCP_IDLE_TIMEOUT, YP_TINT, YP_VINT = { 1, INT32_MAX, 10, YP_STIME } }, { C_TCP_IO_TIMEOUT, YP_TINT, YP_VINT = { 0, INT32_MAX, 500 } }, diff --git a/src/knot/journal/knot_lmdb.c b/src/knot/journal/knot_lmdb.c index 0fcc8850ee..4d3e49366f 100644 --- a/src/knot/journal/knot_lmdb.c +++ b/src/knot/journal/knot_lmdb.c @@ -14,14 +14,15 @@ along with this program. If not, see . */ -#include "knot/journal/knot_lmdb.h" - #include #include // snprintf #include #include #include +#include "knot/journal/knot_lmdb.h" + +#include "knot/conf/conf.h" #include "contrib/files.h" #include "contrib/wire_ctx.h" #include "libknot/dname.h" @@ -79,7 +80,7 @@ void knot_lmdb_init(knot_lmdb_db_t *db, const char *path, size_t mapsize, unsign db->dbname = dbname; pthread_mutex_init(&db->opening_mutex, NULL); db->maxdbs = 2; - db->maxreaders = 1278; + db->maxreaders = conf_lmdb_readers(conf()); } static bool lmdb_stat(const char *lmdb_path, struct stat *st) diff --git a/src/knot/server/server.c b/src/knot/server/server.c index d3d031fa45..90973edf8e 100644 --- a/src/knot/server/server.c +++ b/src/knot/server/server.c @@ -1167,6 +1167,10 @@ int server_reconfigure(conf_t *conf, server_t *server) if ((ret = configure_sockets(conf, server)) != KNOT_EOK) { return ret; } + + if (conf_lmdb_readers(conf) > CONF_MAX_DB_READERS) { + log_warning("config, exceeded number of database readers"); + } } /* Reconfigure journal DB. */ -- 2.47.3