diff options
-rw-r--r-- | distro/pkg/deb/knot-resolver-core.install | 1 | ||||
-rw-r--r-- | distro/pkg/rpm/knot-resolver.spec | 1 | ||||
-rw-r--r-- | modules/meson.build | 1 | ||||
-rw-r--r-- | modules/prefetch/README.rst | 18 | ||||
-rw-r--r-- | modules/prefetch/prefetch.lua | 21 |
5 files changed, 42 insertions, 0 deletions
diff --git a/distro/pkg/deb/knot-resolver-core.install b/distro/pkg/deb/knot-resolver-core.install index 74ff1c57..1e57ac9b 100644 --- a/distro/pkg/deb/knot-resolver-core.install +++ b/distro/pkg/deb/knot-resolver-core.install @@ -18,6 +18,7 @@ usr/lib/knot-resolver/kres_modules/experimental_dot_auth.lua usr/lib/knot-resolver/kres_modules/graphite.lua usr/lib/knot-resolver/kres_modules/policy.lua usr/lib/knot-resolver/kres_modules/predict.lua +usr/lib/knot-resolver/kres_modules/prefetch.lua usr/lib/knot-resolver/kres_modules/prefill.lua usr/lib/knot-resolver/kres_modules/priming.lua usr/lib/knot-resolver/kres_modules/rebinding.lua diff --git a/distro/pkg/rpm/knot-resolver.spec b/distro/pkg/rpm/knot-resolver.spec index acf313f8..5fd08f8d 100644 --- a/distro/pkg/rpm/knot-resolver.spec +++ b/distro/pkg/rpm/knot-resolver.spec @@ -299,6 +299,7 @@ getent passwd knot-resolver >/dev/null || useradd -r -g knot-resolver -d %{_sysc %{_libdir}/knot-resolver/kres_modules/graphite.lua %{_libdir}/knot-resolver/kres_modules/policy.lua %{_libdir}/knot-resolver/kres_modules/predict.lua +%{_libdir}/knot-resolver/kres_modules/prefetch.lua %{_libdir}/knot-resolver/kres_modules/prefill.lua %{_libdir}/knot-resolver/kres_modules/priming.lua %{_libdir}/knot-resolver/kres_modules/rebinding.lua diff --git a/modules/meson.build b/modules/meson.build index 38612254..73444e99 100644 --- a/modules/meson.build +++ b/modules/meson.build @@ -7,6 +7,7 @@ lua_mod_src = [ # add lua modules without separate meson.build files('dns64/dns64.lua'), files('etcd/etcd.lua'), files('graphite/graphite.lua'), + files('prefetch/prefetch.lua'), files('predict/predict.lua'), files('prefill/prefill.lua'), files('priming/priming.lua'), diff --git a/modules/prefetch/README.rst b/modules/prefetch/README.rst new file mode 100644 index 00000000..4d5a5e3e --- /dev/null +++ b/modules/prefetch/README.rst @@ -0,0 +1,18 @@ +.. SPDX-License-Identifier: GPL-3.0-or-later + +.. _mod-prefetch: + +Expiring records +---------------- + +The ``prefetch`` module helps to keep the cache hot by prefetching expiring records. + +This mechanism is activated when the module is loaded and it is not configurable. + +.. code-block:: lua + + modules.load('prefetch') + + +Any time the resolver answers with records that are about to expire, they get refreshed. (see :c:func:`is_expiring`) +That improves latency for records which get frequently queried, relatively to their TTL. diff --git a/modules/prefetch/prefetch.lua b/modules/prefetch/prefetch.lua new file mode 100644 index 00000000..673cf3e5 --- /dev/null +++ b/modules/prefetch/prefetch.lua @@ -0,0 +1,21 @@ +-- SPDX-License-Identifier: GPL-3.0-or-later +-- Speculative prefetching for repetitive and soon-expiring records to reduce latency. +-- @module prefetch +local prefetch = {} + + +prefetch.layer = { + -- Prefetch all expiring (sub-)queries immediately after the request finishes. + -- Doing that immediately is simplest and avoids creating (new) large bursts of activity. + finish = function (_, req) + local qrys = req.rplan.resolved + for i = 0, (tonumber(qrys.len) - 1) do -- size_t doesn't work for some reason + local qry = qrys.at[i] + if qry.flags.EXPIRING == true then + resolve(kres.dname2str(qry.sname), qry.stype, qry.sclass, {'NO_CACHE'}) + end + end + end +} + +return prefetch |