From: Aleš Mrázek Date: Mon, 7 Apr 2025 13:09:46 +0000 (+0200) Subject: Revert "datamodel: cache: removed garbage-collector config" X-Git-Tag: v6.0.17~9^2~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=08c5fc59204111c76ecbe5e118111d1bed92160d;p=thirdparty%2Fknot-resolver.git Revert "datamodel: cache: removed garbage-collector config" This reverts commit 4ba9f6e4a9a30195147d2cbb99dbb53fbd9bc017. --- diff --git a/doc/_static/config.schema.json b/doc/_static/config.schema.json index 85335e277..b6d31ce60 100644 --- a/doc/_static/config.schema.json +++ b/doc/_static/config.schema.json @@ -1141,9 +1141,87 @@ "default": "100M" }, "garbage-collector": { - "type": "boolean", + "anyOf": [ + { + "description": "Configuration options of the cache garbage collector (kres-cache-gc).", + "type": "object", + "properties": { + "interval": { + "type": "string", + "pattern": "^(\\d+)(us|ms|s|m|h|d)$", + "description": "Time interval how often the garbage collector will be run.", + "default": "1s" + }, + "threshold": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Cache usage in percent that triggers the garbage collector.", + "default": 80 + }, + "release": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Percent of used cache to be freed by the garbage collector.", + "default": 10 + }, + "temp-keys-space": { + "type": "string", + "pattern": "^(\\d+)(B|K|M|G)$", + "description": "Maximum amount of temporary memory for copied keys (0 = unlimited).", + "default": "0M" + }, + "rw-deletes": { + "type": "integer", + "minimum": 0, + "description": "Maximum number of deleted records per read-write transaction (0 = unlimited).", + "default": 100 + }, + "rw-reads": { + "type": "integer", + "minimum": 0, + "description": "Maximum number of readed records per read-write transaction (0 = unlimited).", + "default": 200 + }, + "rw-duration": { + "type": "string", + "pattern": "^(\\d+)(us|ms|s|m|h|d)$", + "description": "Maximum duration of read-write transaction (0 = unlimited).", + "default": "0us" + }, + "rw-delay": { + "type": "string", + "pattern": "^(\\d+)(us|ms|s|m|h|d)$", + "description": "Wait time between two read-write transactions.", + "default": "0us" + }, + "dry-run": { + "type": "boolean", + "description": "Run the garbage collector in dry-run mode.", + "default": false + } + } + }, + { + "type": "string", + "enum": [ + false + ] + } + ], "description": "Use the garbage collector (kres-cache-gc) to periodically clear cache.", - "default": true + "default": { + "interval": "1s", + "threshold": 80, + "release": 10, + "temp_keys_space": "0M", + "rw_deletes": 100, + "rw_reads": 200, + "rw_duration": "0us", + "rw_delay": "0us", + "dry_run": false + } }, "ttl-min": { "type": "string", @@ -1241,7 +1319,17 @@ "default": { "storage": "/var/cache/knot-resolver", "size_max": "100M", - "garbage_collector": true, + "garbage_collector": { + "interval": "1s", + "threshold": 80, + "release": 10, + "temp_keys_space": "0M", + "rw_deletes": 100, + "rw_reads": 200, + "rw_duration": "0us", + "rw_delay": "0us", + "dry_run": false + }, "ttl_min": "5s", "ttl_max": "1d", "ns_timeout": "1000ms", diff --git a/python/knot_resolver/controller/supervisord/config_file.py b/python/knot_resolver/controller/supervisord/config_file.py index f537e7402..e0ec67701 100644 --- a/python/knot_resolver/controller/supervisord/config_file.py +++ b/python/knot_resolver/controller/supervisord/config_file.py @@ -57,8 +57,22 @@ def kres_cache_gc_args(config: KresConfig) -> str: if config.logging.level == "debug" or (config.logging.groups and "cache-gc" in config.logging.groups): args += " -v" - args += " -d 1000" " -u 80" " -f 10" " -l 100" " -L 200" " -t 0" " -m 0" " -w 0" - return args + gc_config = config.cache.garbage_collector + if gc_config: + args += ( + f" -d {gc_config.interval.millis()}" + f" -u {gc_config.threshold}" + f" -f {gc_config.release}" + f" -l {gc_config.rw_deletes}" + f" -L {gc_config.rw_reads}" + f" -t {gc_config.temp_keys_space.mbytes()}" + f" -m {gc_config.rw_duration.micros()}" + f" -w {gc_config.rw_delay.micros()}" + ) + if gc_config.dry_run: + args += " -n" + return args + raise ValueError("missing configuration for the cache garbage collector") @dataclass diff --git a/python/knot_resolver/datamodel/cache_schema.py b/python/knot_resolver/datamodel/cache_schema.py index 284b3eb60..d40ee2a0f 100644 --- a/python/knot_resolver/datamodel/cache_schema.py +++ b/python/knot_resolver/datamodel/cache_schema.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import List, Literal, Optional, Union from knot_resolver.constants import CACHE_DIR from knot_resolver.datamodel.templates import template_from_str @@ -6,7 +6,9 @@ from knot_resolver.datamodel.types import ( DNSRecordTypeEnum, DomainName, EscapedStr, + IntNonNegative, IntPositive, + Percent, ReadableFile, SizeUnit, TimeUnit, @@ -55,6 +57,33 @@ class PrefillSchema(ConfigSchema): raise ValueError("cache prefilling is not yet supported for non-root zones") +class GarbageCollectorSchema(ConfigSchema): + """ + Configuration options of the cache garbage collector (kres-cache-gc). + + --- + interval: Time interval how often the garbage collector will be run. + threshold: Cache usage in percent that triggers the garbage collector. + release: Percent of used cache to be freed by the garbage collector. + temp_keys_space: Maximum amount of temporary memory for copied keys (0 = unlimited). + rw_deletes: Maximum number of deleted records per read-write transaction (0 = unlimited). + rw_reads: Maximum number of readed records per read-write transaction (0 = unlimited). + rw_duration: Maximum duration of read-write transaction (0 = unlimited). + rw_delay: Wait time between two read-write transactions. + dry_run: Run the garbage collector in dry-run mode. + """ + + interval: TimeUnit = TimeUnit("1s") + threshold: Percent = Percent(80) + release: Percent = Percent(10) + temp_keys_space: SizeUnit = SizeUnit("0M") + rw_deletes: IntNonNegative = IntNonNegative(100) + rw_reads: IntNonNegative = IntNonNegative(200) + rw_duration: TimeUnit = TimeUnit("0us") + rw_delay: TimeUnit = TimeUnit("0us") + dry_run: bool = False + + class PredictionSchema(ConfigSchema): """ Helps keep the cache hot by prefetching expiring records and learning usage patterns and repetitive queries. @@ -97,7 +126,7 @@ class CacheSchema(ConfigSchema): storage: WritableDir = lazy_default(WritableDir, str(CACHE_DIR)) size_max: SizeUnit = SizeUnit("100M") - garbage_collector: bool = True + garbage_collector: Union[GarbageCollectorSchema, Literal[False]] = GarbageCollectorSchema() ttl_min: TimeUnit = TimeUnit("5s") ttl_max: TimeUnit = TimeUnit("1d") ns_timeout: TimeUnit = TimeUnit("1000ms")