午前2時。携帯電話のアラートが鳴り止みません。プライマリクラスターのDNSレイテンシが、安定していた10msから500msという驚愕の数値に跳ね上がりました。バックボーン回線はほとんど空いているにもかかわらず、ユーザーからは「インターネットが繋がらない」という報告が相次いでいます。
原因は何だったのでしょうか?DNSリカーサが通常の10倍のトラフィック急増に耐えきれず、パンクしていたのです。このような局面で必要なのは、単に「遅い」と告げるだけのツールではありません。正確な限界点を特定できるツールです。長年、私はこうした難題を解決するために、dnsperfとresperfを頼りにしてきました。
クイックスタート:最初のテストを実行する
障害対応の真っ只中に、50ページもあるマニュアルを読んでいる暇はありません。今すぐ知りたいのは、サーバーが現在のクエリ秒数(QPS)に耐えられるかどうかです。もともとNominum社によって開発され、現在はDNS-OARCによってメンテナンスされているdnsperfとresperfは、DNSベンチマークの業界標準となっています。
1. インストール
最新のLinuxディストリビューションへのインストールは、1分もかかりません。UbuntuやDebianユーザーの場合は、以下を実行します。
sudo apt update
sudo apt install dnsperf
RHELやCentOSを使用している場合は、まずEPELリポジトリを有効にします。
sudo yum install epel-release
sudo yum install dnsperf
2. クエリファイルの作成
どちらのツールも、ランダムなクエリを生成するわけではありません。テストしたいドメインとレコードタイプをリストした「データファイル」という単純なテキストファイルが必要です。queries.txtという名前でファイルを作成します。
google.com A
facebook.com A
itfromzero.com AAAA
cloudflare.com MX
linux.org A
有意義なテストにするために、5行だけで済ませないでください。私は通常、実際のquerylogから5万〜10万件のユニークなクエリを抽出し、実際のユーザーの挙動を模倣して、単純なキャッシュヒットを回避するようにしています。
3. 最初のベンチマーク
ローカルのDNSサーバーに対して、100 QPSの一定レートで30秒間テストしてみましょう。
dnsperf -s 127.0.0.1 -p 53 -d queries.txt -l 30 -Q 100
レポートには、送信されたクエリ数、失われた(ロストした)クエリ数、および平均レイテンシが表示されます。「Lost queries」がゼロで、レイテンシが20ms未満に保たれていれば、サーバーは余裕を持って動作しています。もしQPSが低いままでレイテンシが上昇する場合は、設定にボトルネックがあります。
ツールの選択:dnsperf vs. resperf
これらは同じパッケージに含まれていますが、役割が異なります。用途を間違えると、誤ったデータを得ることになります。
dnsperf:スループット測定のスペシャリスト
私は主に権威DNS(Authoritative DNS)サーバーにdnsperfを使用します。これは固定レートでクエリを送信します。「このサーバーは静的なレコードに対して50,000 QPSを処理できるか?」という問いに答えるのに最適です。一定の負荷を維持し、時間の経過に伴う安定性を測定します。
resperf:キャパシティ測定のスペシャリスト
resperf(Resolution Performance)は、キャッシュDNS(再帰的DNS)サーバー向けに設計されています。兄弟分であるdnsperfとは異なり、resperfは低いクエリレートから開始し、サーバーが限界に達するまで負荷を上げていきます。これにより、システムの「天井(限界)」が明らかになります。
新しいハードウェアロードバランサーに移行する際、私はresperfを実行して応答曲線の飽和点を探ります。最近の移行では、resperfによって新しいVMが12,000 QPSまでは処理できるものの、13,000 QPSでレイテンシが3倍になることが判明しました。これにより、本番稼働前に正確なレート制限を設定することができました。
高度なストレステスト
本番環境は複雑です。信頼できるデータを得るには、ツールをより強力に活用する必要があります。
最大キャパシティの特定
サーバーが処理できる絶対的な最大QPSを見つけるには、ランプアップ(負荷増大)機能を使用します。
resperf -s 192.168.1.10 -d queries.txt -m 10000
-mフラグは目標とする最大QPSを設定します。resperfは1秒ごとにデータブロックを出力します。「Target QPS」が上昇しているのに「Actual QPS」の伸びが止まったポイントを探してください。そこが限界点です。
マルチスレッドの活用
32コアのBINDやUnboundのような高性能サーバーでは、ベンチマークツール自体がボトルネックになることがあります。-Tフラグを使用して、テストマシンの複数のCPUコアに負荷を分散させます。
dnsperf -s 10.0.0.5 -d queries.txt -T 4 -l 60 -Q 20000
分散クライアントのシミュレーション
ファイアウォールは、送信元IPに基づいたレート制限を行うことがよくあります。単一のマシンから大規模なテストを実行すると、ファイアウォールによってパケットが破棄され、結果が歪む可能性があります。これを回避するには、複数のコンテナからツールを実行するか、-xフラグを使用して異なる送信元ポートをシミュレートします。
芳しくないベンチマーク結果を改善する方法
ベンチマーク結果でレイテンシが高かったりパケットロスが発生したりしても、慌てる必要はありません。パフォーマンスの低いDNSノードをチューニングするためのチェックリストを以下に示します。
1. ファイルディスクリプタの上限
DNSサーバーは数千の同時接続を処理します。OSの制限が低すぎると、クエリは単に消失します。ulimit -nで現在の制限を確認してください。本番ノードでは、/etc/security/limits.confで少なくとも65,535に設定するのが通例です。
2. メモリとキャッシュサイズ
resperfで、再帰クエリのレイテンシは高いが、繰り返しのクエリには高速に反応する場合、キャッシュサイズが小さすぎます。BINDの場合はmax-cache-sizeを、Unboundの場合はrrset-cache-sizeを確認してください。これらの値を増やすことで、サーバーは上位のルートサーバーを待つことなく、RAMから回答を返すようになります。
3. マルチスレッドとCPUアフィニティ
dnsperfの実行中にCPU使用率を監視してください。他のコアがアイドル状態なのに1つのコアだけが100%に張り付いている場合、ソフトウェアのマルチスレッド設定が正しくありません。Unboundでは、コア数に合わせてnum-threadsを明示的に設定する必要があります。BINDでは、ワーカーレッド数に-nフラグを使用しているか確認してください。
4. UDPスタックのチューニング
多くの場合、ボトルネックはLinuxカーネルにあります。トラフィックの急増時にパケットドロップを防ぐため、私は頻繁にUDP受信バッファを増やします。
# 最大UDPバッファを16MBに設定
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
まとめ
ベンチマークとは、単に大きな数字を追い求めることではありません。「予測可能性」を確保するためのものです。dnsperfでベースラインを測定し、resperfで限界点を把握することで、インフラがどれだけのトラフィックに耐えられるかを正確に把握でき、安心して眠りにつくことができます。私は、CI/CDパイプラインの必須ゲートキーパーとしてこれらのテストを組み込んでいます。午前2時の障害でサーバーの限界が5,000 QPSだったと気づく前に、今日テストしましょう。

