.. _config-cache-predict:
-Prefetching records
-===================
+Prefetching cache records
+=========================
-Prefetching records helps to keep the cache hot.
-It can utilize two independent mechanisms to select the records which should be refreshed:
-expiring records and prediction.
+Prefetching cache records helps to keep the cache hot.
+You can use two independent mechanisms to select the records which should be refreshed.
Expiring records
----------------
-This mechanism is always active when the prefetching is enabled and it is not configurable.
-
Any time the resolver answers with records that are about to expire,
they get refreshed. Record is expiring if it has less than 1% TTL (or less than 5s).
That improves latency for records which get frequently queried, relatively to their TTL.
+.. code-block:: yaml
+
+ cache:
+ prefetch:
+ # enabling prefetching of expiring records, 'false' is default
+ expiring: true
+
+
Prediction
----------
-The resolver can also learn usage patterns and repetitive queries,
+The resolver can learn usage patterns and repetitive queries,
though this mechanism is a prototype and **not recommended** for use in production or with high traffic.
+.. code-block:: yaml
+
+ cache:
+ prefetch:
+ # this mode is NOT RECOMMENDED for use in production
+ prediction:
+ window: 15m # 15 minutes sampling window
+ period: 24 # track last 6 hours
+
+
+Window length is in minutes, period is a number of windows that can be kept in memory.
+e.g. if a ``window`` is 15 minutes, a ``period`` of "24" means 6 hours (360 minutes, 15*24=360).
+
For example, if it makes a query every day at 18:00,
the resolver expects that it is needed by that time and prefetches it ahead of time.
This is helpful to minimize the perceived latency and keeps the cache hot.
-You can disable prediction by configuring :option:`period <period: <int>>` to ``0``.
-
.. tip::
The tracking window and period length determine memory requirements.
Experiment to get the best results.
-Configuration
--------------
-
-.. option:: cache/prediction: true|false|<options>
-
- :default: false
-
- .. option:: window: <time ms|s|m|h|d>
-
- :default: 15m
-
- .. option:: period: <int>
-
- :default: 24
-
-Reconfigure the predictor to given tracking window and period length. Both parameters are optional.
-Window length is in minutes, period is a number of windows that can be kept in memory.
-e.g. if a ``window`` is 15 minutes, a ``period`` of "24" means 6 hours (360 minutes, 15*24=360).
-
-.. code-block:: yaml
-
- cache:
- # this mode is NOT RECOMMENDED for use in production
- prediction:
- window: 15m # 15 minutes sampling window
- period: 24 # track last 6 hours
-
-It is also possible to enable prediction with defaults for :option:`window <window: <time ms|s|m|h|d>>` and :option:`period <period: <int>>`.
-
-.. code-block:: yaml
-
- cache:
- prediction: true
-
Exported metrics
-----------------
+****************
To visualize the efficiency of the predictions, following statistics are exported.
-from typing import Any, List, Optional, Union
+from typing import List, Optional, Union
from typing_extensions import Literal
"""
window: TimeUnit = TimeUnit("15m")
- period: IntNonNegative = IntNonNegative(24)
+ period: IntPositive = IntPositive(24)
+
+
+class PrefetchSchema(ConfigSchema):
+ """
+ These options help keep the cache hot by prefetching expiring records or learning usage patterns and repetitive queries.
+ ---
+ expiring: Prefetch expiring records.
+ prediction: Prefetch record by predicting based on usage patterns and repetitive queries.
+ """
+
+ expiring: bool = False
+ prediction: Optional[PredictionSchema] = None
class CacheSchema(ConfigSchema):
- class Raw(ConfigSchema):
- """
- DNS resolver cache configuration.
-
- ---
- storage: Cache storage of the DNS resolver.
- size_max: Maximum size of the cache.
- garbage_collector: Use the garbage collector (kres-cache-gc) to periodically clear cache.
- ttl_min: Minimum time-to-live for the cache entries.
- ttl_max: Maximum time-to-live for the cache entries.
- ns_timeout: Time interval for which a nameserver address will be ignored after determining that it does not return (useful) answers.
- prefill: Prefill the cache periodically by importing zone data obtained over HTTP.
- prediction: Helps keep the cache hot by prefetching expiring records and learning usage patterns and repetitive queries.
- """
-
- storage: Dir = lazy_default(Dir, "/var/cache/knot-resolver")
- size_max: SizeUnit = SizeUnit("100M")
- garbage_collector: Union[GarbageCollectorSchema, Literal[False]] = GarbageCollectorSchema()
- ttl_min: TimeUnit = TimeUnit("5s")
- ttl_max: TimeUnit = TimeUnit("1d")
- ns_timeout: TimeUnit = TimeUnit("1000ms")
- prefill: Optional[List[PrefillSchema]] = None
- prediction: Union[bool, PredictionSchema] = False
-
- _LAYER = Raw
-
- storage: Dir
- size_max: SizeUnit
- garbage_collector: Union[GarbageCollectorSchema, Literal[False]]
- ttl_min: TimeUnit
- ttl_max: TimeUnit
- ns_timeout: TimeUnit
- prefill: Optional[List[PrefillSchema]]
- prediction: Union[Literal[False], PredictionSchema]
-
- def _prediction(self, obj: Raw) -> Any:
- if obj.prediction is True:
- return PredictionSchema()
- return obj.prediction
+ """
+ DNS resolver cache configuration.
+
+ ---
+ storage: Cache storage of the DNS resolver.
+ size_max: Maximum size of the cache.
+ garbage_collector: Use the garbage collector (kres-cache-gc) to periodically clear cache.
+ ttl_min: Minimum time-to-live for the cache entries.
+ ttl_max: Maximum time-to-live for the cache entries.
+ ns_timeout: Time interval for which a nameserver address will be ignored after determining that it does not return (useful) answers.
+ prefill: Prefill the cache periodically by importing zone data obtained over HTTP.
+ prefetch: These options help keep the cache hot by prefetching expiring records or learning usage patterns and repetitive queries.
+ """
+
+ storage: Dir = lazy_default(Dir, "/var/cache/knot-resolver")
+ size_max: SizeUnit = SizeUnit("100M")
+ garbage_collector: Union[GarbageCollectorSchema, Literal[False]] = GarbageCollectorSchema()
+ ttl_min: TimeUnit = TimeUnit("5s")
+ ttl_max: TimeUnit = TimeUnit("1d")
+ ns_timeout: TimeUnit = TimeUnit("1000ms")
+ prefill: Optional[List[PrefillSchema]] = None
+ prefetch: PrefetchSchema = PrefetchSchema()
def _validate(self):
if self.ttl_min.seconds() >= self.ttl_max.seconds():