"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",
"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",
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
-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
DNSRecordTypeEnum,
DomainName,
EscapedStr,
+ IntNonNegative,
IntPositive,
+ Percent,
ReadableFile,
SizeUnit,
TimeUnit,
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.
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")