今天我们聊聊DNS系统的解析性能,在详细介绍之前我们先要明确这个解析性能指的是什么?根据DNS系统解析的逻辑,我们从以下几个层面做切分:
本地配置权威区域名的解析性能,我们简称“权威解析性能”。DNS系统接到客户端的递归查询,然后DNS系统到互联网上迭代查询到相关结果,并将结果缓存到本地,然后应答给客户端,后续客户端再次请求此缓存中的域名的性能,我们简称“缓存解析性能”。DNS系统接到客户端的递归查询,然后DNS系统对外做迭代查询的并发性能,我们简称“递归解析性能”可见DNS系统的解析性能还是有很多细节的,上面提到权威解析性能和缓存解析性能在bind系统层面相差不多,也是本文介绍的重点,即每秒能正常处理的域名解析数简称QPS。递归解析性能本文也会简单介绍。
影响DNS解析性能的关键点如下:
影响性能关键点描述CPU核数bind运行时是支持多线程的,可以利用多CPU来提升解析性能。在bind9.14版本之前编译的时候需要–enable-threads来显示开启多线程,而bind9.14版本及以后没有这个显示的参数,因为bind已经默认开启多线程,并开始使用REUSEPORT内核特性来实现更充分的多CPU核数的使用。所以CPU核数绝对是越多越好(当然多到一定阶段,瓶颈不在是CPU而是其他了~)CPU主频CPU的主频的高低是绝对的关键点,否则核数再多而主频较低,那么性能也不能到达一个理想的程度。建议生产环境怎么也弄个2.2GHZ以上的,最好大于3.0GHZ。网卡类型(网络类型)网络是通道,一个千兆网口(1000Mb/s)环境下最高的DNS解析性能也就到45万QPS左右。因为DNS解析请求报文往往是小于应答报文的,例如请求包是70字节(Byte),那么应答包可能是210字节,所以我们按照300字节来作为一个DNS报文的平均值,这么算1000Mb/s大概就是45万的DNS查询和应答。如果要再高,那么就得上万兆光了,且网卡是否支持多队列,也是关键中的关键。Linux内核版本Linux 内核3.9版本后开始支持REUSEPORT特性,这个在这个内核基础上使用bind9.14及以上版本性能明显比bind9.9等低版本的性能高很多。虽然都是多线程,但因为REUSEPORT特性的使用,bind终于可以充分的使用多核CPU。bind软件版本bind9.14及以上版本默认开启多线程并且支持REUSEPORT特性所以性能明显要高于小于bind9.14版本。内存如果单单作为权威DNS,那么内存要求并不是特别的高,但如果作为缓存DNS或者有大量的递归查询,那么内存大小也是关键。bind软件配置bind是否开启日志输出也是影响解析性能的关键。DNS的压力测试工具最常用(或者说最好找)的就是dnsperf和queryperf。其中queryperf是bind软件自带的,dnsperf软件是Nominum提供的一款开源压测软件,下面是简单的安装和使用方法,详细使用方法大家可自己在网上搜索。
软件安装 dnsperf依赖的软件比较多,如果是源码安装那么要注意最好所在的环境安装bind软件。如果使用yum安装则先执行yum install -y epel-release安装epel源,然后执行yum install dnsperf安装dnsperf。编写一个文本文件例如domain.txt内容如下: www.example.com A www.test.com A 执行命令dnsperf -d domain.txt -s 192.168.2.10 -l 120就开始压测了,压测完毕后的截图如下。 -d 用来指定要压测的域名列表文件。 -s 用来指定要压测的DNS服务器IP地址。 -l 120用来指定压测的时间,单位是秒 下图是压测结果,一个dnsperf进程压测缓存应答,在关闭bind日志的情况下是7.8万左右。 下图是压测过程中DNS服务器的top查看截图,可见1个CPU线程已经完全占用,但并没有使用其他的CPU。原因是dnsperf压测的时候,它发出来的请求源IP是固定的,源端口也是固定,那么bind软件接到这个请求后就只能HASH到固定的1个CPU上。 下面是同时启动2个dnsperf压测时DNS服务器的top查看截图,可见这个时候有2个CPU被完全占用,named的进程使用CPU是200% 注意:因为dnsperf这个工具无法发随机源IP的DNS查询包,所以是无法很好的测试bind性能的,尤其是bind的多CPU多线程测试。REUSEPORT特性是基于查询包的四元组来HASH到不同的CPU的,如果源IP固定、源端口也固定,那么因为目的IP和目的端口也是固定,所以无法充分使用多CPU。所以如果要充分测试,还是建议能自己写一个能发随机源IP和源端口的发包工具,并且性能要高。测试环境:
操作系统是centos7,内核版本如下:, Linux localhost.localdomain 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux 网卡是千兆网卡,但不支持多队列,是否支持多队列可以使用ethtool -l 网卡名命令查看。CPU是8个线程(逻辑核)主频3.5GHZ的Intel Xeon系列。发包工具是自己编写的能发随机源IP的压测工具。执行yum install dnstop安装dnstop工具能动态查看DNS包的统计,安装此工具要先按照epel源。安装bind时使用了–enable-threads参数。named.conf配置文件没有开启bind的日志。压测域名为bind本地配置的test.com权威区域名,循环压测。性能测试效果 下面是15万左右QPS时的压测效果: 下面是25万QPS的压测效果。
测试结论 bind9.9在此硬件平台上关闭日志时最高的解析性能大概是15万QPS左右,它最大只能是用4个CPU即400%的占用,虽然此时还有其他的CPU在空闲,但也不会再分配请求给其他的CPU来提升性能,因为bind9.9没使用REUSRPORT特性。
测试环境 测试环境同上,但bind9.14编译安装的时候不需要再使用–enable-threads参数。 性能测试效果 下面是33万左右QPS时的压测效果: 下面是dnsptop工具的统计 测试结论 bind9.14在此硬件平台上关闭日志时最高的解析性能大概是30万QPS左右,它能充分的使用8个CPU(逻辑)来提升性能,并且分配的比较均衡,这是因为bind9.14使用了REUSRPORT特性且当前Linux内核也支持。