Measure DNS Server Performance
This is not an entirely proper way to benchmark a DNS server, but, in a pinch, it should give you some idea of its responsiveness and stability.
The commands below require dig
(provided by the bind-utils
package), and shuf
(provided by the coreutils
package). Pretty standard stuff you should already have installed.
The first step is to grab a large sample of domain names. Here’s one of them:
curl -q -s0 -k https://raw.githubusercontent.com/opendns/public-domain-lists/master/opendns-random-domains.txt > /tmp/opendns-random-domains.txt
In my case, the three internal DNS servers are 192.168.122.2-4
. The shuf -i 2-4 -n 1
command below will pick one of those at random for every lookup. Here we do lookups on three batches of one hundred random domains – one at a time – and measure average response time, while waiting for five minutes between each job. From this you could sort-of calculate a 15-minute average.
c=100 for i in $(seq 1 3) do for i in $(shuf -n ${c} /tmp/opendns-random-domains.txt) do dig ${i} +time=1 +tries=1 -t A @192.168.122.$(shuf -i 2-4 -n 1) +nonssearch 2>/dev/null | grep -oP "(?<=Query time: )[0-9]{1,}(?= msec$)" done | awk -v c="$c" '{sum += $1} END {printf "%.0f ms\n", sum/c}' sleep 300 done
I suppose it may be interesting to see how DNS performance changes if you lookup more than one domain in a single pass. Similar to the previous example, the command below will launch 10 instances of dig
in parallel. If working with external DNS servers, be careful not to get blacklisted.
c=100 for i in $(seq 1 3) do shuf -n ${c} /tmp/opendns-random-domains.txt | \ xargs -n1 -P10 -I% dig % +time=1 +tries=1 -t A @192.168.122.$(shuf -i 2-4 -n 1) +nonssearch 2>/dev/null | \ grep -oP "(?<=Query time: )[0-9]{1,}(?= msec$)" | awk -v c="$c" '{sum += $1} END {printf "%.0f ms\n", sum/c}' sleep 300 done
Here’s a different way of doing the same operation as in the previous example, but without using xargs
. Why? It’s just a clever example of using custom file handles to read multiple lines of input in a single loop iteration and assign each line to a different variable. You should really play with this.
c=100 for i in $(seq 1 3) do tmpfile=$(mktemp) shuf -n ${c} /tmp/opendns-random-domains.txt > ${tmpfile} exec 5<${tmpfile} while read line0 <&5 do read line1 <&5 read line2 <&5 read line3 <&5 read line4 <&5 read line5 <&5 read line6 <&5 read line7 <&5 read line8 <&5 read line9 <&5 dig ${line0} +time=1 +tries=1 -t A @192.168.122.$(shuf -i 2-4 -n 1) +nonssearch 2>/dev/null | grep -oP "(?<=Query time: )[0-9]{1,}(?= msec$)" & dig ${line1} +time=1 +tries=1 -t A @192.168.122.$(shuf -i 2-4 -n 1) +nonssearch 2>/dev/null | grep -oP "(?<=Query time: )[0-9]{1,}(?= msec$)" & dig ${line2} +time=1 +tries=1 -t A @192.168.122.$(shuf -i 2-4 -n 1) +nonssearch 2>/dev/null | grep -oP "(?<=Query time: )[0-9]{1,}(?= msec$)" & dig ${line3} +time=1 +tries=1 -t A @192.168.122.$(shuf -i 2-4 -n 1) +nonssearch 2>/dev/null | grep -oP "(?<=Query time: )[0-9]{1,}(?= msec$)" & dig ${line4} +time=1 +tries=1 -t A @192.168.122.$(shuf -i 2-4 -n 1) +nonssearch 2>/dev/null | grep -oP "(?<=Query time: )[0-9]{1,}(?= msec$)" & dig ${line5} +time=1 +tries=1 -t A @192.168.122.$(shuf -i 2-4 -n 1) +nonssearch 2>/dev/null | grep -oP "(?<=Query time: )[0-9]{1,}(?= msec$)" & dig ${line6} +time=1 +tries=1 -t A @192.168.122.$(shuf -i 2-4 -n 1) +nonssearch 2>/dev/null | grep -oP "(?<=Query time: )[0-9]{1,}(?= msec$)" & dig ${line7} +time=1 +tries=1 -t A @192.168.122.$(shuf -i 2-4 -n 1) +nonssearch 2>/dev/null | grep -oP "(?<=Query time: )[0-9]{1,}(?= msec$)" & dig ${line8} +time=1 +tries=1 -t A @192.168.122.$(shuf -i 2-4 -n 1) +nonssearch 2>/dev/null | grep -oP "(?<=Query time: )[0-9]{1,}(?= msec$)" & dig ${line9} +time=1 +tries=1 -t A @192.168.122.$(shuf -i 2-4 -n 1) +nonssearch 2>/dev/null | grep -oP "(?<=Query time: )[0-9]{1,}(?= msec$)" & done | awk -v c="$c" '{sum += $1} END {printf "%.0f ms\n", sum/c}' exec 5<&- /bin/rm ${tmpfile} sleep 300 done