Improve prefetch (#483)

* Add prefetch-cache-size option

* Update and clarify documentation for prefetch including new prefetch-cache-size option
This commit is contained in:
xnoreq
2026-01-17 14:20:04 +01:00
committed by GitHub
parent 1f44b0bfac
commit 4dcd40ca7f
5 changed files with 16 additions and 7 deletions

View File

@@ -194,6 +194,7 @@ type group struct {
// Prefetch options
PrefetchWindow time.Duration `toml:"prefetch-window"` // Time period to track queries for prefetching, default 1h
PrefetchThreshold uint64 `toml:"prefetch-threshold"` // Minimum number of queries per window to enable prefetching, default 5
PrefetchCacheSize int `toml:"prefetch-cache-size"` // Maximum number of items to cache
PrefetchMaxItems int `toml:"prefetch-max-items"` // Maximum number of items to track prefetch, default (0) unlimited
}

View File

@@ -10,8 +10,9 @@ resolvers = ["cloudflare-dot"]
type = "prefetch"
resolvers = ["cloudflare-cached"]
prefetch-window = "15m" # Minimum time between queries to remain eligible for prefetch
prefetch-threshold = 3 # Min number of queries to enable prefetch
prefetch-max-items = 100 # Max number of items to track for prefetch
prefetch-threshold = 3 # Min number of queries required to enable prefetch
prefetch-cache-size = 150 # Max number of queries to track for prefetch
prefetch-max-items = 50 # Max number of items to prefetch
[listeners.local-udp]
address = "127.0.0.1:53"

View File

@@ -699,6 +699,7 @@ func instantiateGroup(id string, g group, resolvers map[string]rdns.Resolver) er
opt := rdns.PrefetchOptions{
PrefetchWindow: g.PrefetchWindow,
PrefetchThreshold: g.PrefetchThreshold,
PrefetchCacheSize: g.PrefetchCacheSize,
PrefetchMaxItems: g.PrefetchMaxItems,
}
resolvers[id] = rdns.NewPrefetch(id, gr[0], opt)

View File

@@ -442,7 +442,7 @@ Example config files: [cache.toml](../cmd/routedns/example-config/cache.toml), [
### Prefetch
While [Cache](#cache) has built-in prefetch capabilities, a the dedicated `prefetch` group may be more appropriate for some use cases. Its tracks the number of queries made and actively prefetches frequenty requested records. While it actively sends queries in order to refresh a cache, it does not cache responses itself and relies on a cache upstream from it.
While [Cache](#cache) has built-in prefetch capabilities, a the dedicated `prefetch` group may be more appropriate for some use cases. Its tracks the number of queries made within a time window and actively prefetches frequenty requested records. While it actively sends queries in order to refresh a cache, it does not cache responses itself and relies on a cache upstream from it.
#### Configuration
@@ -452,8 +452,9 @@ Options:
- `resolvers` - Array of upstream resolvers, only one is supported.
- `prefetch-window` - Minimum time between queries to remain eligible for prefetching. Supports time units `s`, `m`, and `h`. Default: 1h.
- `prefetch-threshold` - Minimum number of queries for a name to enable prefetch. Default: 5.
- `prefetch-max-items` - Maximum number of items to track for prefetch. Values that are too large can cause memory issues. Prefetch is disabled if 0 or not set.
- `prefetch-threshold` - Minimum number of queries required for a name to enable prefetch. Default: 5.
- `prefetch-cache-size` - Maximum number of queries to track for prefetch. Values that are too large can cause memory issues. Prefetch is disabled if 0. Default: `prefetch-max-items * 3`.
- `prefetch-max-items` - Maximum number of items to prefetch. Values that are too large can cause memory issues. Prefetch is disabled if 0 or not set.
#### Examples
@@ -469,7 +470,8 @@ type = "prefetch"
resolvers = ["cloudflare-cached"]
prefetch-window = "15m"
prefetch-threshold = 3
prefetch-max-items = 100
prefetch-cache-size = 150
prefetch-max-items = 50
```
Example config files: [prefetch.toml](../cmd/routedns/example-config/prefetch.toml)

View File

@@ -25,6 +25,7 @@ var _ Resolver = &RoundRobin{}
type PrefetchOptions struct {
PrefetchWindow time.Duration
PrefetchThreshold uint64
PrefetchCacheSize int
PrefetchMaxItems int
}
@@ -35,6 +36,9 @@ func NewPrefetch(id string, resolver Resolver, opt PrefetchOptions) *Prefetch {
if opt.PrefetchThreshold == 0 {
opt.PrefetchThreshold = 5
}
if opt.PrefetchCacheSize == 0 {
opt.PrefetchCacheSize = opt.PrefetchMaxItems * 3
}
r := &Prefetch{
id: id,
@@ -42,7 +46,7 @@ func NewPrefetch(id string, resolver Resolver, opt PrefetchOptions) *Prefetch {
options: opt,
}
r.nameCache = expirationcache.NewCache[atomic.Uint64](context.Background(), expirationcache.Options{
MaxSize: uint(opt.PrefetchMaxItems),
MaxSize: uint(opt.PrefetchCacheSize),
})
r.queryCache = expirationcache.NewCacheWithOnExpired(context.Background(), expirationcache.Options{
MaxSize: uint(opt.PrefetchMaxItems),