2026年6月12日
2026年6月12日
PowerDNS のパフォーマンスチューニング|Authoritative Server のスレッド・キャッシュ・バックエンドDBを調整する
PowerDNS Authoritative Server(pdns_server)の応答が遅い、負荷が高いといった問題の多くは、パケットキャッシュの効き具合と、バックエンドのデータベースへの問い合わせで決まります。チューニングは pdns_control で統計を見て詰まっている箇所を特定し、スレッド数・キャッシュの有効時間・データベースの順に調整するのが効率的です。この記事では、計測の方法、主な設定の意味と調整の考え方、反映と効果の確認を説明します。
PowerDNS には権威DNSの Authoritative Server と、キャッシュDNSの Recursor という別の製品があり、設定項目も異なります。この記事は Authoritative Server を対象とします。設定項目の名前や既定値は版によって変わることがあるため(2026年10月現在)、手元の版の公式ドキュメント(Authoritative Server の Settings のページ)で確認してから使ってください。
まず統計で現状を測る
pdns_control で統計を読む
稼働中の pdns_server の統計は pdns_control で読めます。
# 統計の一覧
sudo pdns_control list | tr ',' '\n'
# 個別の値
sudo pdns_control show latency
sudo pdns_control show packetcache-hit
sudo pdns_control show packetcache-miss
組み込みのウェブサーバー(webserver=yes)を有効にしている場合は、Prometheus 形式の /metrics などから同じ統計を集められます。ウェブサーバーと API は、webserver-address と webserver-allow-from で管理用のネットワークからだけ読めるようにします。API も有効にする場合は推測されにくい API キーを設定し、pdns.conf の読み取り権限を PowerDNS の実行ユーザーと管理者に限定します。
見るべき統計
- latency:問い合わせに答えるまでの平均時間(マイクロ秒)です。全体の傾向を見る指標で、ここが悪化したら以下の項目で原因を探します。
- packetcache-hit と packetcache-miss:応答をまるごと覚えておくパケットキャッシュで答えられた数と、答えられなかった数です。ヒット率が低いと、ほぼすべての問い合わせがバックエンドに届きます。
- query-cache-hit と query-cache-miss:バックエンドへの問い合わせ結果を覚えておくクエリキャッシュの状況です。
- qsize-q:バックエンドの処理を待っている問い合わせの数です。常に増えているなら、バックエンドかスレッド数が追いついていません。
- udp-recvbuf-errors:OS の UDP 受信バッファがあふれて捨てられたパケットの数です。
- servfail-packets と timedout-packets:失敗やタイムアウトになった応答の数です。バックエンドの不調で増えます。
負荷をかけて測る
設定変更の効果は、検証環境で同じゾーンを載せたサーバーに DNS-OARC の dnsperf などで負荷をかけ、前後を比べると判断しやすくなります。負荷試験は自分が管理するサーバーにだけ行います。
スレッド数を調整する
pdns_server の処理は、パケットを受け取る receiver スレッド と、バックエンドに問い合わせる distributor スレッド に分かれています。
receiver-threads:パケットを受け取るスレッドの数です。CPU のコア数を目安に増やします。複数にするときはreuseport=yesを合わせて設定すると、OS が受信を各スレッドに振り分けます。distributor-threads:receiver スレッド1つあたりの、バックエンドに問い合わせるスレッドの数です。
# /etc/powerdns/pdns.conf(4コアのサーバーの例)
receiver-threads=4
reuseport=yes
distributor-threads=3
注意したいのは、データベースのバックエンドでは、distributor スレッドごとにデータベースへの接続を持つことです。この例では 4 × 3 = 12 本の接続を、バックエンドの種類ごとに使います。MySQL の max_connections や PostgreSQL の max_connections に余裕があるか、複数台の PowerDNS から同じデータベースを使っている場合は合計で足りるかを確認します。distributor スレッドを増やしすぎると、データベース側が詰まって逆に遅くなります。
キャッシュの有効時間を調整する
pdns_server には主に2つのキャッシュがあり、有効時間(秒)を設定できます。
cache-ttl:パケットキャッシュの有効時間です。query-cache-ttl:クエリキャッシュで、存在するレコードの結果を覚えておく時間です。negquery-cache-ttl:クエリキャッシュで、存在しない名前の結果を覚えておく時間です。
多くの版では、これらの既定値は数十秒程度です。有効時間を延ばすとバックエンドへの問い合わせが減り、ヒット率が上がります。その代わり、データベースでレコードを変更してから応答に反映されるまでの時間が延びます。
# 変更の反映が最大 60 秒遅れてもよい場合の例
cache-ttl=60
query-cache-ttl=60
negquery-cache-ttl=60
レコードを変更した直後に反映させたいときは、該当する名前のキャッシュを消します。末尾の $ は、そのドメイン以下をまとめて消す指定です。
sudo pdns_control purge www.example.com
sudo pdns_control purge example.com$
API や管理ツールからレコードを更新する運用では、更新の処理にキャッシュの消去を組み込んでおくと、有効時間を長めにしても困りにくくなります。
存在しない名前への大量の問い合わせ(ランダムなサブドメインを使った攻撃など)は、パケットキャッシュが効きにくく、バックエンドに直接負荷がかかります。negquery-cache-ttl だけで防ぐのは難しいため、前段に dnsdist を置いて問い合わせの頻度を制限する方法も検討します。
バックエンドのデータベースを見直す
キャッシュに載らない問い合わせは、最終的にバックエンドの速さで決まります。gmysql や gpgsql を使っている場合は、次の点を確認します。
- 公式のスキーマとインデックスを使っているか:PowerDNS の版に付属するスキーマには、records テーブルの名前や種別で検索するためのインデックスが含まれています。古い版から更新してきたデータベースでは、更新手順で追加されたインデックスが入っていないことがあります。データベースのスロークエリログで、PowerDNS からの問い合わせが遅くなっていないかを見ます。
- データベースとの距離:別のサーバーにデータベースを置いている場合、ネットワークの往復時間がそのまま応答時間に加わります。
- バックエンドの種類:ゾーンの数が多くなく、更新の頻度も低いなら、LMDB バックエンドや bind バックエンドのように、外部のデータベースを使わない方式のほうが速いことがあります。移行は検証環境で十分に試してから行います。
データベースの設定を変える前には、PowerDNS のデータベースのバックアップを取ります。インデックスの追加は大きなテーブルではロックや負荷を伴うため、利用の少ない時間帯に、まず検証環境で所要時間を測ってから本番で行います。
DNSSEC と OS の設定
DNSSEC を有効にしたゾーンでは、署名の処理に CPU を使います。署名済みの応答もパケットキャッシュに載るため、キャッシュのヒット率を上げることが署名の負荷を減らすことにもつながります。鍵の情報を覚えておく時間(dnssec-key-cache-ttl)など、DNSSEC 関連のキャッシュ設定も公式ドキュメントで確認します。
udp-recvbuf-errors が増え続けている場合は、OS の受信バッファの上限を上げます。
# /etc/sysctl.d/90-pdns.conf に書き、sudo sysctl --system で反映する
net.core.rmem_max = 8388608
net.core.rmem_default = 8388608
反映と効果の確認
設定ファイルを変えたら、pdns_server を再起動して反映します。権威DNSを複数台で運用しているなら、1台ずつ反映し、応答を確認してから次の台に進みます。
sudo systemctl restart pdns
systemctl status pdns --no-pager
dig @192.0.2.53 example.com SOA +norec
sudo pdns_control show latency
再起動の直後はキャッシュが空なので、latency やヒット率は一時的に悪くなります。比較は、キャッシュが温まるまで待ってから、最初に測ったときと同じくらいの時間帯で行います。改善しない場合や悪化した場合は、変更を1つずつ戻して影響を確かめます。複数の設定を同時に変えると、どれが効いたのか分からなくなるため、変更内容と統計の値を記録しながら進めます。
まとめ
- 対象は PowerDNS Authoritative Server です。Recursor は別製品で設定項目が異なります。
pdns_controlの latency・パケットキャッシュとクエリキャッシュのヒット率・qsize-q・udp-recvbuf-errors で、詰まっている箇所を特定してから調整します。receiver-threadsはコア数を目安にreuseportと組み合わせ、distributor-threadsはデータベースの接続数の上限と合わせて決めます。- キャッシュの有効時間を延ばすと負荷は下がりますが、変更の反映が遅れます。更新時に
pdns_control purgeで消す運用と組み合わせます。 - キャッシュに載らない問い合わせはバックエンドの速さで決まるため、公式スキーマのインデックスとデータベースまでの距離を確認し、変更前にはバックアップを取ります。