I have tested unbound memory consumption after each reload: CU200, single rpz list loaded (malware), single client in the network (reduce numbers of dns queries). Test machine is PCEngines APU2D4, red-green config, single LAN client connected to green.
Default config test: how much RAM is consumed after restart (not reload, because reload does not release the memory)
/etc/init.d/unbound stop; sleep 5; /etc/init.d/unbound start; sleep 10; ~/check_unbound.sh
Stopping Unbound DNS Proxy⦠[ OK ]
Starting Unbound DNS Proxy⦠[ OK ]--- RSS MEMORY ---
PID RSS COMMAND
4442 51592 /usr/sbin/unbound
--- SLABS & THREADS ---
msg-cache-slabs : 4
rrset-cache-slabs : 4
infra-cache-slabs : 4
key-cache-slabs : 4
num-threads : 4
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
--- INTERNAL CACHE USAGE ---
mem.cache.rrset : 75722
mem.cache.message : 69419
mem.mod.validator : 70838
[root@silver-x86-64 ~]# ~/check_unbound.sh
--- RSS MEMORY ---
PID RSS COMMAND
4442 51616 /usr/sbin/unbound
--- SLABS & THREADS ---
msg-cache-slabs : 4
rrset-cache-slabs : 4
infra-cache-slabs : 4
key-cache-slabs : 4
num-threads : 4
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
--- INTERNAL CACHE USAGE ---
mem.cache.rrset : 80349
mem.cache.message : 72656
mem.mod.validator : 71959
Then 10 times reload followed by report of memory consumed and cache:
for i in {1..10}; do echo ββ Iteration: ${i}β β; unbound-control reload && sleep 5 && ~/check_unbound.sh; done
β Iteration: 1 β
ok
β RSS MEMORY β
PID RSS COMMAND
4442 51656 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 4
rrset-cache-slabs : 4
infra-cache-slabs : 4
key-cache-slabs : 4
num-threads : 4
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 73006
mem.cache.message : 68294
mem.mod.validator : 70104
β Iteration: 2 β
ok
β RSS MEMORY β
PID RSS COMMAND
4442 51772 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 4
rrset-cache-slabs : 4
infra-cache-slabs : 4
key-cache-slabs : 4
num-threads : 4
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 73006
mem.cache.message : 68294
mem.mod.validator : 70104
β Iteration: 3 β
ok
β RSS MEMORY β
PID RSS COMMAND
4442 52032 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 4
rrset-cache-slabs : 4
infra-cache-slabs : 4
key-cache-slabs : 4
num-threads : 4
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 78568
mem.cache.message : 71144
mem.mod.validator : 71578
β Iteration: 4 β
ok
β RSS MEMORY β
PID RSS COMMAND
4442 52048 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 4
rrset-cache-slabs : 4
infra-cache-slabs : 4
key-cache-slabs : 4
num-threads : 4
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 73006
mem.cache.message : 68294
mem.mod.validator : 70104
β Iteration: 5 β
ok
β RSS MEMORY β
PID RSS COMMAND
4442 52072 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 4
rrset-cache-slabs : 4
infra-cache-slabs : 4
key-cache-slabs : 4
num-threads : 4
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 73006
mem.cache.message : 68294
mem.mod.validator : 70104
β Iteration: 6 β
ok
β RSS MEMORY β
PID RSS COMMAND
4442 52100 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 4
rrset-cache-slabs : 4
infra-cache-slabs : 4
key-cache-slabs : 4
num-threads : 4
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 73006
mem.cache.message : 68294
mem.mod.validator : 70104
β Iteration: 7 β
ok
β RSS MEMORY β
PID RSS COMMAND
4442 52100 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 4
rrset-cache-slabs : 4
infra-cache-slabs : 4
key-cache-slabs : 4
num-threads : 4
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 73006
mem.cache.message : 68294
mem.mod.validator : 70104
β Iteration: 8 β
ok
β RSS MEMORY β
PID RSS COMMAND
4442 52112 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 4
rrset-cache-slabs : 4
infra-cache-slabs : 4
key-cache-slabs : 4
num-threads : 4
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 73006
mem.cache.message : 68294
mem.mod.validator : 70104
β Iteration: 9 β
ok
β RSS MEMORY β
PID RSS COMMAND
4442 52112 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 4
rrset-cache-slabs : 4
infra-cache-slabs : 4
key-cache-slabs : 4
num-threads : 4
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 73006
mem.cache.message : 68294
mem.mod.validator : 70104
β Iteration: 10 β
ok
β RSS MEMORY β
PID RSS COMMAND
4442 52124 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 4
rrset-cache-slabs : 4
infra-cache-slabs : 4
key-cache-slabs : 4
num-threads : 4
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 73006
mem.cache.message : 68294
mem.mod.validator : 70104
So in default config the system had 1 MB gained after 10 reloads for 51 MB initial memory consumption
Test 2: custom config added in /etc/unbound/local.d/
cat memory-fix.conf
server:
num-threads: 1
msg-cache-slabs: 1
rrset-cache-slabs: 1
infra-cache-slabs: 1
key-cache-slabs: 1
Memory consumed after restart with the custom config
/etc/init.d/unbound stop; sleep 5; /etc/init.d/unbound start; sleep 10; ~/check_unbound.sh
Stopping Unbound DNS Proxy⦠[ OK ]
Starting Unbound DNS Proxy⦠[ OK ]
β RSS MEMORY β
PID RSS COMMAND
5150 17264 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 1
rrset-cache-slabs : 1
infra-cache-slabs : 1
key-cache-slabs : 1
num-threads : 1
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 23446
mem.cache.message : 18734
mem.mod.validator : 20544
So the initial memory dropped from 51 MB to 17 MB!
Now the reload iterations:
for i in {1..10}; do echo ββ Iteration: ${i}β β; unbound-control reload && sleep 5 && ~/check_unbound.sh; done
β Iteration: 1 β
ok
β RSS MEMORY β
PID RSS COMMAND
5150 19660 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 1
rrset-cache-slabs : 1
infra-cache-slabs : 1
key-cache-slabs : 1
num-threads : 1
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 23446
mem.cache.message : 18734
mem.mod.validator : 20544
β Iteration: 2 β
ok
β RSS MEMORY β
PID RSS COMMAND
5150 19940 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 1
rrset-cache-slabs : 1
infra-cache-slabs : 1
key-cache-slabs : 1
num-threads : 1
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 23446
mem.cache.message : 18734
mem.mod.validator : 20544
β Iteration: 3 β
ok
β RSS MEMORY β
PID RSS COMMAND
5150 19948 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 1
rrset-cache-slabs : 1
infra-cache-slabs : 1
key-cache-slabs : 1
num-threads : 1
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 23446
mem.cache.message : 18734
mem.mod.validator : 20544
β Iteration: 4 β
ok
β RSS MEMORY β
PID RSS COMMAND
5150 20076 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 1
rrset-cache-slabs : 1
infra-cache-slabs : 1
key-cache-slabs : 1
num-threads : 1
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 23446
mem.cache.message : 18734
mem.mod.validator : 20544
β Iteration: 5 β
ok
β RSS MEMORY β
PID RSS COMMAND
5150 20576 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 1
rrset-cache-slabs : 1
infra-cache-slabs : 1
key-cache-slabs : 1
num-threads : 1
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 29008
mem.cache.message : 21584
mem.mod.validator : 22018
β Iteration: 6 β
ok
β RSS MEMORY β
PID RSS COMMAND
5150 20576 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 1
rrset-cache-slabs : 1
infra-cache-slabs : 1
key-cache-slabs : 1
num-threads : 1
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 23446
mem.cache.message : 18734
mem.mod.validator : 20544
β Iteration: 7 β
ok
β RSS MEMORY β
PID RSS COMMAND
5150 20580 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 1
rrset-cache-slabs : 1
infra-cache-slabs : 1
key-cache-slabs : 1
num-threads : 1
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 23446
mem.cache.message : 18734
mem.mod.validator : 20544
β Iteration: 8 β
ok
β RSS MEMORY β
PID RSS COMMAND
5150 20580 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 1
rrset-cache-slabs : 1
infra-cache-slabs : 1
key-cache-slabs : 1
num-threads : 1
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 23446
mem.cache.message : 18734
mem.mod.validator : 20544
β Iteration: 9 β
ok
β RSS MEMORY β
PID RSS COMMAND
5150 20588 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 1
rrset-cache-slabs : 1
infra-cache-slabs : 1
key-cache-slabs : 1
num-threads : 1
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 26162
mem.cache.message : 19859
mem.mod.validator : 21278
β Iteration: 10 β
ok
β RSS MEMORY β
PID RSS COMMAND
5150 20588 /usr/sbin/unbound
β SLABS & THREADS β
msg-cache-slabs : 1
rrset-cache-slabs : 1
infra-cache-slabs : 1
key-cache-slabs : 1
num-threads : 1
infra-cache-numhosts : 10000
interface-automatic : yes
interface : 0.0.0.0
β INTERNAL CACHE USAGE β
mem.cache.rrset : 23446
mem.cache.message : 18734
mem.mod.validator : 20544
Unbound ended up with 20,5 MB memory consumed after 10 reload iterations from an initial 17 MB amount.
First reload added the biggest memory consumption
From above test I see that num-threads and *-cache-slabs play a role only to the initial memory allocation but does not stop the memory leakage. Percentage wise, the custom config seems worse: the memory increase was >15% while default config added ~0,5% memory increase (same numbers of reloads, same rpz list loaded).
The internal cache stays pretty much the same in my test - but the test machine had only one Linux client connected (and in Linux was started just ssh to ipfire and Firefox toward this webpage)
Note: custom config with num-threads and *-cache-slabs set to 1 reduces the overall response capacity of the dns. It is not recommended for systems that need to resolve a large amount of queries. Find your suitable config based on your network demands.