比較的アクセスのあるウェブサーバがあって、そのウェブサーバから結構な回数で Web API をたたいています。ご存じのとおり、Linux では DNS をキャッシュしてくれないので、Web API をたたくために毎回 DNS へのアクセスが発生して、DNS の負荷がすこし上がってきたので、ウェブサーバに DNS キャッシュを入れてみることにしました。
今回の用件は、次のとおりです。
- Web API でたたくときにドメインを、それぞれのウェブサーバでキャッシュしたい
- おもに外部ドメインをキャッシュするので、DNS ラウンドロビンにはできれば対応したい
ということで、いろいろと調査したり、友人からアドバイスをもらったところ、Unbound、Dnsmasq、caching-server、の三つの選択肢があることが分かりました。それぞれ、CentOS 5.7 x86_64 の環境で、試していました。
まずは、本命といえる Unbound インストールは簡単です。Unbound の設定は /etc/unbound/unbound.conf ですが、デフォルトの設定だと、DLV が設定されているので DLV が解決できない環境では名前解決が遅くしまうので注意しましよう。
Unboud の特長は、次のとおりです。インストールは、unbound パッケージをインストールするだけです。
- 設定が比較的容易
- DNS ラウンドロビンには対応していない
- cache-min-ttl という設定項目で、最低限 Unbound でキャッシュする最低 TTL を設定することができる
今回の用件では、外部ドメインをキャッシュすることを目的にするため、DNS ラウンドロビンに対応していないというのは痛いです。
次に Dnsmasq です。特長は、次のとおりです。インストールは、dnsmasq パッケージをインストールするだけですが、すでにインストールされていました。
- 設定が比較的容易
- DNS ラウンドロビンに対応している
- DHCP 情報もキャッシュすることが可能
- /etc/hosts や他の特定ファイルを hosts ファイルとして読み込んでキャッシュすることができる
公式ホームページをみると、おもに自宅で NAT 環境を使っている人向けに開発したとありますが、1000 クライアント規模程度から動作するようなので、大規模な環境でない限りは問題はなさそうです。今回は、まったく大規模ではないので、問題なさそうです。また、Dnsmasq はデフォルト設定で、/etc/resolv.conf を読み込んでいるため、/etc/resolv.cnf を nameserver 127.0.0.1 とすると「ignoring nameserver 127.0.0.1 – local interface」というエラーが発生してしまうため、no-resolv を設定していくとよいでしょう(参考)。
次に caching-server ですが、bind 系のものになります。インストールは、caching-nameserver と bind をインストールするだけです。設定は、このページに詳しく書かれていますので割愛します。特長は、次のとおりです。
- bind に慣れている人なら設定は同じ
- DNS ラウンドロビンに対応している
caching-server もよさそうです。ただし、bind なので普段から bind を使っている人は設定が同じなのでまったく問題ないですが、DNS キャッシュ以外の通常の DNS 機能も備えているのでちょっと今回の用件には大げさなのかもしれません。しかも、今回負荷が上がっている DNS は bind なのでなんとなく同じような負荷になってしまう恐れもありました。
DNS ラウンドロビンに対応しているかは、dig コマンドで簡単に確認することができます。
$ dig google.com @localhost
; < <>> DiG 9.3.6-P1-RedHat-9.3.6-16.P1.el5 < <>> google.com @localhost
;; global options: printcmd
;; Got answer:
;; ->>HEADER< ;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 4, ADDITIONAL: 4
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 5 IN A 74.125.31.147
google.com. 5 IN A 74.125.31.99
google.com. 5 IN A 74.125.31.103
…
上のような感じで、ローカルのそれぞれの DNS キャッシュをたてて dig コマンドを繰り返して発行して IP アドレスが入れ替わるかで DNS ラウンドロビンに対応しているかは分かります。Unbound の場合は、IP アドレスがまったく入れ替わりません。
次に本当に DNS キャッシュされているかですが、Unboud だと次のコマンドで確認することができます。
$ sudo unbound-control dump_cache
START_RRSET_CACHE
;rrset 4 1 0 1 2
ns4.google.com. 4 IN A 216.239.38.10
...
END
Dnsmasq と caching-server には専用のコマンドがなさそうな感じだったので、tcpdump で DNS へのアクセスが行われているかみることで確認しました。いずれもちゃんと DNS キャッシュされていました。
最後にそれぞれのパフォーマンスを計測してみました。計測したツールは、google が提供している namebench というツールです。測定方法は、それぞれの DNS キャッシュを起動した状態で、ローカルの DNS に対してパフォーマンスを計測しました。
結果は、次のとおりでした。
$ ./namebench.py --system_only --query_count=100 --num_servers=10
caching-nameserver
Mean response (in milliseconds):
——————————–
SYS-127.0.0.1 ##################################################### 144.51
Dnsmasq
Mean response (in milliseconds):
——————————-
SYS-127.0.0.1 ###################################################### 126.80
unbound
Mean response (in milliseconds):
——————————–
SYS-127.0.0.1 ##################################################### 155.89
いくぶんか Dnsmasq のパフォーマンスがよかったです。DNS ラウンドロビンにも対応していますし、今回の用件にはあっていそうでした。
その他、先日の YAPC::Asia 2011 にて @xaicron さんが「大規模環境におけるマニアックなキャッシュ利用術」というタイトルで Mobage で行われている DNS キャッシュについてトークがありました。ローカルに Memcached をたてて、そこに数秒おきにバッチを実行して DNS キャッシュを作る方法が紹介されていました。なるほどこれも素晴らしいと思ったのですが、規模的にはまったく大規模でないこと、アプリケーション側のコードを変更する必要があること、といった点で今回はこの方法は採用しないことにしました。大規模な場合は、この方法は素晴らしいと思いますので、そのときになったらやってみたいと思っています。
ということで、今回は Dnsmasq をそれぞれのウェブサーバに DNS キャッシュとしてたてることにしました。当然ながら、DNS キャッシュをたてるので、nagios でちゃんと監視するようにしました。
しばらくこれ様子を見てみたいと思います。
Tags: dns






