query perf와perftcpdns 기반 DNS 압력 테스트

최근 AWS에 PPTP 설치××× 대리, 핸드폰,pad도 틈이 없을 수 있다×××,매우 기쁘다.요즘 일이 그리 바쁘지 않으니 캐시 가속 조절을 연구해 보자.시스템에 설치된 nscd 파일급 캐시와 dnsmasq, cpu급 dns 캐시입니다.왜 nscd는 파일급 캐시라고 말합니까? 일은 먼저 dnsmasq에서 시작해야 합니다. 모두가 nscd-g가hosts에 대한 캐시 명중률을 볼 수 있다는 것을 알고 있습니다.
[root@shanker:~06:24]#nscd -g
nscd configuration:
              1  server debug level
         3m 55s  server runtime
              4  current number of threads
             32  maximum number of threads
              0  number of times clients had to wait
             no  paranoia mode enabled
           3600  restart internal
              5  reload count
passwd cache:
             no  cache is enabled
            yes  cache is persistent
            yes  cache is shared
              0  suggested size
              0  total data pool size
              0  used data pool size
            600  seconds time to live for positive entries
             20  seconds time to live for negative entries
              0  cache hits on positive entries
              0  cache hits on negative entries
              0  cache misses on positive entries
              0  cache misses on negative entries
              0% cache hit rate
              0  current number of cached values
              0  maximum number of cached values
              0  maximum chain length searched
              0  number of delays on rdlock
              0  number of delays on wrlock
              0  memory allocations failed
            yes  check /etc/passwd for changes
group cache:
             no  cache is enabled
            yes  cache is persistent
            yes  cache is shared
              0  suggested size
              0  total data pool size
              0  used data pool size
           3600  seconds time to live for positive entries
             60  seconds time to live for negative entries
              0  cache hits on positive entries
              0  cache hits on negative entries
              0  cache misses on positive entries
              0  cache misses on negative entries
              0% cache hit rate
              0  current number of cached values
              0  maximum number of cached values
              0  maximum chain length searched
              0  number of delays on rdlock
              0  number of delays on wrlock
              0  memory allocations failed
            yes  check /etc/group for changes
hosts cache:
            yes  cache is enabled
            yes  cache is persistent
            yes  cache is shared
            211  suggested size
         216064  total data pool size
            120  used data pool size
           3600  seconds time to live for positive entries
             20  seconds time to live for negative entries
            361  cache hits on positive entries
              0  cache hits on negative entries
            239  cache misses on positive entries
            151  cache misses on negative entries
             48% cache hit rate
              1  current number of cached values
             80  maximum number of cached values
              2  maximum chain length searched
              0  number of delays on rdlock
              0  number of delays on wrlock
              0  memory allocations failed
            yes  check /etc/hosts for changes
services cache:
            yes  cache is enabled
            yes  cache is persistent
            yes  cache is shared
            211  suggested size
         216064  total data pool size
            416  used data pool size
          28800  seconds time to live for positive entries
             20  seconds time to live for negative entries
              0  cache hits on positive entries
              0  cache hits on negative entries
              3  cache misses on positive entries
              1  cache misses on negative entries
              0% cache hit rate
              3  current number of cached values
              3  maximum number of cached values
              1  maximum chain length searched
              0  number of delays on rdlock
              0  number of delays on wrlock
              0  memory allocations failed
            yes  check /etc/services for changes
netgroup cache:
             no  cache is enabled
            yes  cache is persistent
            yes  cache is shared
              0  suggested size
              0  total data pool size
              0  used data pool size
          28800  seconds time to live for positive entries
             20  seconds time to live for negative entries
              0  cache hits on positive entries
              0  cache hits on negative entries
              0  cache misses on positive entries
              0  cache misses on negative entries
              0% cache hit rate
              0  current number of cached values
              0  maximum number of cached values
              0  maximum chain length searched
              0  number of delays on rdlock
              0  number of delays on wrlock
              0  memory allocations failed
            yes  check /etc/netgroup for changes

그리고 nscd의 캐시 파일은/var/cache/nscd 디렉터리에 저장되며 lsof로 볼 수 있습니다.dnsmasq의 캐시 효과를 보고 싶었을 때 캐시된 파일이 모두 socket인 것을 발견했기 때문에 나는 그의 캐시가varnish와 유사하게 메모리에 존재한다고 판단했다.
[root@shanker:~06:25]#cd /proc/`pidof dnsmasq`/
[root@shanker:/proc/2662406:26]#cd fd
[root@shanker:/proc/26624/fd06:26]#ll
total 0
lrwx------ 1 root root 64 Jan 14 12:59 9 -> socket:[211546]
lrwx------ 1 root root 64 Jan 14 12:59 8 -> socket:[211545]
lrwx------ 1 root root 64 Jan 14 12:59 7 -> socket:[211544]
lrwx------ 1 root root 64 Jan 14 12:59 6 -> socket:[211543]
lrwx------ 1 root root 64 Jan 14 12:59 5 -> socket:[211542]
lrwx------ 1 root root 64 Jan 14 12:59 4 -> socket:[211541]
lrwx------ 1 root root 64 Jan 14 12:59 3 -> socket:[211539]
lrwx------ 1 root root 64 Jan 14 12:59 2 -> /dev/null
l-wx------ 1 root root 64 Jan 14 12:59 14 -> /var/log/dnsmasq.log
l-wx------ 1 root root 64 Jan 14 12:59 13 -> pipe:[211553]
lr-x------ 1 root root 64 Jan 14 12:59 12 -> pipe:[211553]
lrwx------ 1 root root 64 Jan 14 12:59 11 -> socket:[211548]
lrwx------ 1 root root 64 Jan 14 12:59 10 -> socket:[211547]
lrwx------ 1 root root 64 Jan 14 12:59 1 -> /dev/null
lrwx------ 1 root root 64 Jan 14 12:59 0 -> /dev/null

그리고 dnsmasq 조회의 효율이 어떠한지 측정해 봅시다. bind 그 도구 중에는 DNS 성능 테스트 도구가 있습니다. 홈페이지에 가서 최신bind를 다운로드하세요.
wget https://www.isc.org/downloads/file/bind-9-10-3-p2/?version=tar-gz

압축을 풀고queryperf 디렉터리로 가기
cd bind-9.10.3-P2/contrib/queryperf/
./configure
make
cp queryperf /usr/bin/

그리고perftcpdns도 마찬가지입니다.make 후perftcpdnscp를/usr/bin 아래로 내려갑니다.
queryperf 사용 형식
queryperf [-d datafile] [-s server_addr] [-p port] [-q num_queries]
 
-d: 뒤에 파일을 연결합니다. 파일의 내용은 사용자가 DNS에 대한 요청입니다. 한 행동에 한 가지 요청이 있기 때문에 테스트를 위해 우리는 수천수만 개의 파일을 쓸 수 있습니다.
-s: DNS 서버 주소
-p: DNS 서버 포트
-q: 요청 횟수
나는 인터넷에서 도메인 이름 주소를 아무렇게나 찾아서 dnsrecord에 저장했다.
ns.bta.net.cn A
ns.spt.net.cn A
ns.cn.net A
gjjline.bta.net.cn A
linedns.bta.net.cn A
ns.guangzhou.gd.cn A
dns.guangzhou.gd.cn A
ns.sta.net.cn A
ns-pd.online.sh.cn A
ns.wuhan.net.cn A
ns1.hbwhptt.net.cn A
dns.zj.cninfo.net A
ns.wuhan.net.cn A
ns.zjnbptt.net.cn A
ns.snnic.com A
ns1.xaonline.com A
ns.tpt.net.cn A
ns.dcb.ln.cn A
ns.lnpta.net.cn A
dns.dl.lnpta.net.cn A

그리고 9999 줄로 복사해서 먼저 본기로 테스트합니다
queryperf -d query.txt  -s 127.0.0.1

결과는 다음과 같다.
Statistics:
  Parse input file:     once
  Ended due to:         reaching end of file
  Queries sent:         9999 queries
  Queries completed:    9999 queries
  Queries lost:         0 queries
  Queries delayed(?):   0 queries
  RTT max:              0.329734 sec
  RTT min:              0.000003 sec
  RTT average:          0.002490 sec
  RTT std deviation:    0.011374 sec
  RTT out of range:     0 queries
  Percentage completed: 100.00%
  Percentage lost:        0.00%
  Started at:           Thu Jan 14 12:02:52 2016
  Finished at:          Thu Jan 14 12:03:18 2016
  Ran for:              26.355231 seconds
  Queries per second:   379.393374 qps

초당 379.393374개의 쿼리를 수행한 후 Google의 공지 도메인 이름 서버로 테스트한 결과
queryperf -d query.txt  -s 8.8.8.8
Statistics:
  Parse input file:     once
  Ended due to:         reaching end of file
  Queries sent:         9999 queries
  Queries completed:    9999 queries
  Queries lost:         0 queries
  Queries delayed(?):   0 queries
  RTT max:              0.262356 sec
  RTT min:              0.001734 sec
  RTT average:          0.005838 sec
  RTT std deviation:    0.020113 sec
  RTT out of range:     0 queries
  Percentage completed: 100.00%
  Percentage lost:        0.00%
  Started at:           Thu Jan 14 12:04:22 2016
  Finished at:          Thu Jan 14 12:16:18 2016
  Ran for:              715.830576 seconds

  Queries per second:   13.968389 qps
그 결과 초당 불쌍한 13.96번의 조회만 있었다. 즉, 본 컴퓨터가 서버로서 dnsmasq 캐시가 없는 상황에서 DNS 조회 효율이 낮은 것이 불쌍하다는 것이다.
perftcpdns의 사용
한참 동안 Google에서 유용한 정보를 찾지 못했습니다.
[root@shanker:~/bind-9.10.3-P2/contrib/perftcpdns06:56]#perftcpdns 
server is required
perftcpdns [-huvX0] [-4|-6] [-r] [-t] [-p]
    [-n]* [-d]* [-D]* [-T]
    [-l] [-L]* [-a] [-s]
    [-M] [-x] [-P] server
The server argument is the name/address of the DNS server to contact.
Options:
-0: Add EDNS0 option with DO flag.
-4: TCP/IPv4 operation (default). This is incompatible with the -6 option.
-6: TCP/IPv6 operation. This is incompatible with the -4 option.
-a: When the target sending rate is not yet reached,
    control how many connections are initiated before the next pause.
-d: Specify the time after which a connection or a query is
    treated as having been lost. The value is given in seconds and
    may contain a fractional component. The default is 1 second.
-h: Print this help.
-l: Specify the local hostname/address to use when
    communicating with the server.
-L: Specify the (minimal and maximal) local port number
-M: Size of the tables (default 60000)
-P: Specify an alternate (i.e., not 53) port
-r: Initiate  TCP DNS connections per second.  A periodic
    report is generated showing the number of exchanges which were not
    completed, as well as the average response latency.  The program
    continues until interrupted, at which point a final report is
    generated.
-s: Specify the seed for randomization, making it repeatable.
-t: Delay in seconds between two periodic reports.
-T: The name of a file containing the template to use
    as a stream of hexadecimal digits.
-u: Use UDP in place of TCP.
-v: Report the version number of this program.
-X: change default template to get NXDOMAIN responses.
-x: Include extended diagnostics in the output.
     is a string of single-keywords specifying
    the operations for which verbose output is desired.  The selector
    keyletters are:
   * 'a': print the decoded command line arguments
   * 'e': print the exit reason
   * 'i': print rate processing details
   * 'T': when finished, print templates
Stopping conditions:
-D: Abort the test if more than  connections or
   queries have been lost.  If  includes the suffix '%', it
   specifies a maximum percentage of losses before stopping.
   In this case, testing of the threshold begins after 10
   connections/responses have been expected to be accepted/received.
-n: Initiate  transactions.  No report is
    generated until all transactions have been initiated/waited-for,
    after which a report is generated and the program terminates.
-p: Send requests for the given test period, which is
    specified in the same manner as -d.  This can be used as an
    alternative to -n, or both options can be given, in which case the
    testing is completed when either limit is reached.
Errors:
- locallimit: reached to local system limits when sending a message.
- badconn: connection failed (from getsockopt(SO_ERROR))
- collconn: connect() timed out
- badsent: send() failed
- callsent: timed out waiting from a response
- recverr: recv() system call failed
- tooshort: received a too short message
- badid: the id mismatches between the query and the response
- notresp: doesn't receive a response
Rate stats:
- loops: number of thread loop iterations
- shortwait: no direct activity in a thread iteration
- compconn: computed number of connect() calls
- lateconn: connect() already dued when computing delay to the next one
Exit status:
The exit status is:
0 on complete success.
1 for a general error.
2 if an error is found in the command line arguments.
3 if there are no general failures in operation, but one or more
  exchanges are not successfully completed.

이 명령을 사용하는 전제는 서버가 캐시 서버가 아니라 진정한 DNS 서버라는 것이다.
perftcpdns -x aeiT -r 40000  8.8.8.8
connect: 117669, sent: 117667, received: 60393
embryonics: 2 (0.0%)
drops: 57274 (48.7%)
total losses: 57276 (48.7%)
local limits: 0, bad connects: 0, connect timeouts: 2
bad sends: 0, bad recvs: 0, recv timeouts: 57090
too shorts: 13, bad IDs: 0, not responses: 0
rcode counters:
 noerror: 1572, formerr: 0, servfail: 58821
 nxdomain: 0, noimp: 0, refused: 0, others: 0
rates: 241,241,124 (target 250)
loops: 436434,117670,474085,462908
shortwait: 0,356509,402606
compconn: 117669, lateconn: 1
badconn: 0, collconn: 2, recverr: 0, collsent: 57090
memory: used(246) / allocated(60000)
RTT: min/avg/max/stddev:  1.798/9.197/523.429/22.042 ms
length = 0x1c
content:
00 00 01 00 00 01 00 00 00 00 00 00 05 69 63 61
6e 6e 04 6c 69 6e 6b 00 00 01 00 01

내가 파라미터를 사용해서 테스트를 진행할 때 시스템은 too many files are open, ulimit가 열린 파일 수를 65535로 바꾸어 테스트를 계속한다고 알렸다. 잠시 후에 전에 열린 ssh 창이 왠지 모르게 닫혔고 이름을 두드리는 반응이 끊겼다.perftcpdns를 강제로 끄고 로그를 보니 익숙한 장면이 나타났다.
 Jan 15 03:00:59 shanker kernel: [223099.654142] nf_conntrack: table full, dropping packet
Jan 15 03:00:59 shanker kernel: [223099.654144] nf_conntrack: table full, dropping packet
Jan 15 03:01:05 shanker kernel: [223104.992102] net_ratelimit: 29728 callbacks suppressed  
Jan 15 03:01:05 shanker kernel: [223104.992128] nf_conntrack: table full, dropping packet
Jan 15 03:01:05 shanker kernel: [223104.992135] nf_conntrack: table full, dropping packet
Jan 15 03:01:05 shanker kernel: [223105.152351] nf_conntrack: table full, dropping packet

예전에 처리했던 비상케이스가 생각나, nfconntrack table full, 가장 직접적인 처리 방식은 conntrack table과 bucket의 값을 늘리는 것입니다.
net.netfilter.nf_conntrack_max = 196608
net.netfilter.nf_conntrack_buckets = 65534
만약 서버 메모리가 충분하고 네트워크 요청만 처리한다면, 이 수치를 확대하는 것은 당연한 것이다.Google은 다른 루트 치료법은 iptable raw 테이블을 사용하고 기록을 건너뛰며, iptables에 의존하지 않으면 커널 파라미터를 변경하는 방법도 가능하다고 생각합니다.

좋은 웹페이지 즐겨찾기