今回は /etc/hosts と dnsmasq でどの程度速度が変わるのかをベンチマークしました。
テスト環境は
- OS: CentOS 6.4 64bit, Linux 3.10.2
- CPU: Intel Core i7-2600 @ 3.4GHz
テストにはひたすら getaddrinfo(3) し続けるプログラムを作成し、名前を解決しました。 /etc/hosts には
10.234.130.1 host1301 10.234.130.2 host1302 10.234.130.3 host1303
のように適当なアドレスとホスト名を並べたものを作り、利用しました。なお端数の2件はIPv4とv6のlocalhostです。
比較対象に dnsmasq をローカルに立てて同じ内容の hosts ファイルを読ませたものを使いました。
結果は次のとおりです。単位は秒で、10万クエリあたりの所要時間です。
#hosts | hosts | dnsmasq |
---|---|---|
2 | 1.516 | 4.8068 |
102 | 2.6598 | 4.9224 |
252 | 4.4474 | 4.9286 |
1002 | 13.2376 | 4.831 |
結果は一目瞭然で、ホストのエントリ数が増加するに従って、hosts を引く時間はほぼ線形に増加しています。今回の構成では損益分岐点はおよそ250エントリ程度となりました。なお hosts に見つからなかった場合は hosts の検索時間に加えて DNS を引く時間がかかります。
こうなる理由は、hosts の中身はライブラリ(libc)によって処理されていて、毎回 fopen(3) して線形に検索しているからです。dnsmasqをはじめとする多くのネームサーバーはファイルから読み込んだあと、ハッシュなどを使って高速に検索を行います。
実際には1リクエストあたりの時間に換算すると0.05マイクロ秒程度で、hostsに1000エントリ書いた場合でも0.14マイクロ秒なので大した時間ではありません。ですが、場合によってはhostsを引くよりきちんとDNSを使ったほうが早くなる場合があるということは覚えておいて損はありません。
測定に用いたプログラムは下記のとおりです。
2013/08/23 追記:
タイトルが「急激に遅くなる」というのは煽っていると指摘を受けたので変更しました。
測定ポイント数が少ないのは単なる手抜きです...
「そんな多数のホストがある状態で /etc/hosts にすべて書くのはありえない」的な意見も見受けられましたが、実際にあるんですよ... そういう状態に対してきちんとエビデンスを示す目的で書かれました。 DNSで実際に速度や冗長性を担保するには別の工夫が必要になりますが、それはまた別の記事で。
あと nscd 使えばっていう話があったので参考までに1002エントリhostsで走らせたところ
こんくらいの速度だったので、何も考えずに200倍早くなります。
「そんな多数のホストがある状態で /etc/hosts にすべて書くのはありえない」的な意見も見受けられましたが、実際にあるんですよ... そういう状態に対してきちんとエビデンスを示す目的で書かれました。 DNSで実際に速度や冗長性を担保するには別の工夫が必要になりますが、それはまた別の記事で。
あと nscd 使えばっていう話があったので参考までに1002エントリhostsで走らせたところ
$ ./a.out 100000 host127183 Resolved 100000 times. Elapsed time = 0.740 seconds, 0.007 us per host.
こんくらいの速度だったので、何も考えずに200倍早くなります。