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

