AmazonLinuxでDNSキャッシュを試してみた

2014.11.12

はじめに

AWSチームのすずきです。

AWSにより提供されるサービス、可用性を確保するためエンドポイントはFQDNで提供されており、 その利用時にはDNSによる名前解決を必要とします。

Amazon Linuxを始めとする、昨今主要なLinuxディストリビューションでは、 標準状態ではDNSによる名前解決の結果がキャッシュされず、都度DNSサーバへの問合せが行われます。

コネクションプールの採用が難しい環境で、RDS、ElastiCache(Redis、Memcached)などを利用する場合に、 名前解決に伴う負荷が高まる事が懸念されました。

その対策としてDNSのローカルキャッシュの有効性について評価した所、性能向上効果が確認できました。その結果について展開させて頂きます。

検証環境

RDS

  • Instance Class:db.t2.micro
  • Engine:MySQL (5.6.19a)
  • Availability Zone:ap-northeast-1a

EC2

  • インスタンスタイプ:t2.micro
  • OS:Amazon Linux AMI 2014.09.1 (HVM)
  • Availability Zone:ap-northeast-1a

nscd

DNSのローカルキャッシュとしてnscd(ネームサービスキャッシュデーモン)を利用しました。

インストール

yumコマンドを利用、OS標準レポジトリよりインストールを行いました。

$ sudo yum install nscd

設定(nscd.conf )

キャッシュに伴う副作用を抑制する為「paranoia」モードを有効とし、 60秒毎にnscdの定期的に再起動とキャッシュデータの消去を実施する設定としました。

/etc/nscd.conf 差分

$ diff -c  nscd.conf.org nscd.conf
*** nscd.conf.org       2014-11-12 11:24:11.590574033 +0000
--- nscd.conf   2014-11-12 11:22:44.292500147 +0000
***************
*** 37,44 ****
  #     stat-user               somebody
        debug-level             0
  #     reload-count            5
!       paranoia                no
! #     restart-interval        3600
  
        enable-cache            passwd          yes
        positive-time-to-live   passwd          600
--- 37,44 ----
  #     stat-user               somebody
        debug-level             0
  #     reload-count            5
!       paranoia                yes
!       restart-interval        60
  
        enable-cache            passwd          yes
        positive-time-to-live   passwd          600

検証手順

nscdサービスの有効、無効状態で以下の確認を行いました。

  • mysqlコマンド1万回の実行所要時間
  • tcpdumpによる、DNSサーバ通信件数の取得

結果と考察

nscdサービス DNSサーバ通信数 RDS(mysql)所要時間
nscd無効 20012回 70.636s
nscd有効 10回 39.412s

nscdによるDNSキャッシュを有効化した事で、DNSサーバ通信数は0.05%まで減少、 1万回のRDS(mysql)接続の所要時間も56%と、明確な効果が認められました。

nscd有効化に伴う副作用について、NIS、LDAPを導入した環境では特に注意が必要ですが、 フェイルオーバ時の切替遅延については「paranoia」モードの採用により抑制する事が可能と考えます。

また、RDS、DB用途以外だけでなく、監視などでAWSのAPIを大量に実行される様なケースでも、 DNSキャッシュ導入の効果が期待できる可能性があると思われます。

参考資料

検証利用スクリプト(sql-10000.sh)

#!/bin/bash

RDS_ENDPOINT="XXXXX.ap-northeast-1.rds.amazonaws.com"
RDS_USER="YYYYY"
RDS_PASS="ZZZZZ"
RDS_DB="mydb"

for i in {1..10000}
  do
   mysql -h ${RDS_ENDPOINT} -u ${RDS_USER} -p${RDS_PASS} ${RDS_DB} -e "select now()" > /dev/null
  done

操作結果(nscd無効時)

# nscd 停止
$ sudo service nscd stop
Stopping nscd:                                             [  OK  ]

# tcpdump 実行(ポート53対象)
$ sudo tcpdump -c 30000 dst port 53 -w nscd_off.dmp &

# スクリプト実行(msql 1万回実行)
$ time bash sql-10000.sh

real    1m10.636s
user    0m0.984s
sys     0m0.820s

# tcpdump停止
$ sudo killall tcpdump

# tcpdump 結果確認
$  tcpdump -r nscd_off.dmp -q -n  | wc -l
reading from file nscd_off.dmp, link-type EN10MB (Ethernet)
20012

$ tcpdump -r nscd_off.dmp -q -n  | head -n 6 
reading from file nscd_off.dmp, link-type EN10MB (Ethernet)
11:40:59.561433 IP 172.31.24.155.57740 > 172.31.0.2.domain: UDP, length 76
11:40:59.561444 IP 172.31.24.155.57740 > 172.31.0.2.domain: UDP, length 76
11:40:59.572847 IP 172.31.24.155.53883 > 172.31.0.2.domain: UDP, length 76
11:40:59.572857 IP 172.31.24.155.53883 > 172.31.0.2.domain: UDP, length 76

操作結果(nscd有効時)

# nscd 開始
$ sudo service nscd start
Starting nscd:                                             [  OK  ]

# tcpdump 実行(ポート53対象)
$ sudo tcpdump -c 30000 dst port 53 -w nscd_on.dmp &

# スクリプト実行(msql 1万回実行)
$ time bash sql-10000.sh

real    0m39.412s
user    0m0.924s
sys     0m0.844s


# tcpdump停止
$ sudo killall tcpdump

# tcpdump 結果確認
$ tcpdump -r nscd_on.dmp -q -n  | wc -l
reading from file nscd_on.dmp, link-type EN10MB (Ethernet)
10


$ tcpdump -r nscd_on.dmp -q -n
reading from file nscd_on.dmp, link-type EN10MB (Ethernet)
11:50:06.641553 IP 172.31.24.155.60563 > 172.31.0.2.domain: UDP, length 76
11:50:06.641564 IP 172.31.24.155.60563 > 172.31.0.2.domain: UDP, length 76
11:50:14.236830 IP 172.31.24.155.50762 > 172.31.0.2.domain: UDP, length 76
11:50:14.236839 IP 172.31.24.155.50762 > 172.31.0.2.domain: UDP, length 76
11:50:29.243341 IP 172.31.24.155.39756 > 172.31.0.2.domain: UDP, length 76
11:50:29.243351 IP 172.31.24.155.39756 > 172.31.0.2.domain: UDP, length 76
11:50:37.238696 IP 172.31.24.155.53606 > 172.31.0.2.domain: UDP, length 44
11:50:37.238707 IP 172.31.24.155.53606 > 172.31.0.2.domain: UDP, length 44
11:50:44.250303 IP 172.31.24.155.36777 > 172.31.0.2.domain: UDP, length 76
11:50:44.250315 IP 172.31.24.155.36777 > 172.31.0.2.domain: UDP, length 76