]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
modules: prefetch: new module for prefetching expiring records
authorAleš Mrázek <ales.mrazek@nic.cz>
Wed, 17 Apr 2024 13:55:02 +0000 (15:55 +0200)
committerAleš Mrázek <ales.mrazek@nic.cz>
Mon, 22 Apr 2024 10:43:52 +0000 (12:43 +0200)
distro/pkg/deb/knot-resolver-core.install
distro/pkg/rpm/knot-resolver.spec
modules/meson.build
modules/prefetch/README.rst [new file with mode: 0644]
modules/prefetch/prefetch.lua [new file with mode: 0644]

index 74ff1c57057da9aa9798e2a99dc61824165b4883..1e57ac9bd1f0ccfd65fc41ebda3104eca4014ab3 100644 (file)
@@ -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
index acf313f8ab08ceb716ee67ba86a974a34ffbabba..5fd08f8ddc9addb351bc2864907febd54fa79dfc 100644 (file)
@@ -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
index 38612254afcb4e27f7a54cbc578c7ad7fb99e8fc..73444e997d78f1f914f7e0a5788818295bc42d82 100644 (file)
@@ -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 (file)
index 0000000..4d5a5e3
--- /dev/null
@@ -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 (file)
index 0000000..673cf3e
--- /dev/null
@@ -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