Networking

Unix and Linux network configuration. Multiple network interfaces. Bridged NICs. High-availability network configurations.

Applications

Reviews of latest Unix and Linux software. Helpful tips for application support admins. Automating application support.

Data

Disk partitioning, filesystems, directories, and files. Volume management, logical volumes, HA filesystems. Backups and disaster recovery.

Monitoring

Distributed server monitoring. Server performance and capacity planning. Monitoring applications, network status and user activity.

Commands & Shells

Cool Unix shell commands and options. Command-line tools and application. Things every Unix sysadmin needs to know.

Home » Networking, Performance

Measure DNS Server Performance

Submitted by on March 25, 2019 – 4:04 pm

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

 

Print Friendly, PDF & Email

Leave a Reply