DNSキャッシュサーバ チューニングの勘所

19,947 views

Published on

BIND9部分を公開しました。いくつか加筆修正しVer1.1になりました。

Published in: Technology
0 Comments
49 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
19,947
On SlideShare
0
From Embeds
0
Number of Embeds
760
Actions
Shares
0
Downloads
166
Comments
0
Likes
49
Embeds 0
No embeds

No notes for slide

DNSキャッシュサーバ チューニングの勘所

  1. 1. DNSキャッシュサーバ チューニングの勘所 Daisuke HIGASHI Version 1.2 2014/3 1
  2. 2. この文書について • キャッシュサーバ(フルリゾルバ)として動作させた Unbound・BIND9両方について、大規模環境に適した チューニングとしてボトルネックになりやすい部分を紹介 • 対象verは Unbound 1.4.22/BIND 9.9.5 を基準として いるが、それ以前でも同様の設定が可能な場合がある • DNS権威サーバは対象外 • OSやネットワーク環境のチューニング項目、性能チュー ニング以外のおすすめ設定も合わせて紹介 2
  3. 3. チューニングの必要性 • Unbound/BIND9やOSのデフォルト設定は、ハードウェアの性能を最大に発 揮する設定になっていない • 適切なチューニングをしないと、CPU使用率が少ないのに性能が頭打ち/CPU ばかり食って性能が上がらない、という状況に陥る • 「設定」とはハードウェア資源の配分方法 設定は、ほとんどの場合リミッターとして働いてい る。DNSキャッシュサーバのチューニングの多くは、 高い性能を出すために、リミッターの上限を適切に引 き上げる作業となる。 3
  4. 4. ワーカー スレッド ワーカー スレッド DNSキャッシュサーバ 内部構造 キャッシュメモリ リクエスト処理状態 管理メモリ ソケットバッファ udp/53 インターネット (権威サーバ) ワーカー スレッド ワーカー スレッド DNS リクエスト ユーザ キャッシュサーバ プロセス 説明しやすいように簡略化して いる。また、DNSサーバの実装 によって細かい差がある 4
  5. 5. DNSリクエスト処理(1) ワーカー スレッド ワーカー スレッド キャッシュメモリ リクエスト処理状態 管理メモリ ソケットバッファ udp/53 ワーカー スレッド ワーカー スレッド ユーザ ①ユーザからのDNSリ クエスト受信、ソケッ トバッファにキューイ ング インターネット (権威サーバ) キャッシュサーバ プロセス 5
  6. 6. リクエスト処理状態 管理メモリ DNSリクエスト処理(2) ワーカー スレッド ワーカー スレッド キャッシュメモリ ソケットバッファ udp/53 ワーカー スレッド ワーカー スレッド ユーザ ②ワーカースレッドが、ソ ケットからリクエスト取り 出し、リクエスト管理メモ リに格納 インターネット (権威サーバ) キャッシュサーバ プロセス 6
  7. 7. DNSリクエスト処理(3) ワーカー スレッド ワーカー スレッド キャッシュメモリ リクエスト処理状態 管理メモリ ソケットバッファ udp/53 ワーカー スレッド ワーカー スレッド ユーザ ③ワーカースレッドは、キャッ シュメモリを参照したり、イン ターネットの権威サーバに問合 せたりしながら、リクエストの 答えを検索 インターネット (権威サーバ) ソケット キャッシュサーバ プロセス 7
  8. 8. DNSリクエスト処理(4) ワーカー スレッド ワーカー スレッド キャッシュメモリ リクエスト処理状態 管理メモリ ソケットバッファ udp/53 ワーカー スレッド ワーカー スレッド ユーザ ④得られたDNSの答えを、 ユーザに送り返す インターネット (権威サーバ) キャッシュサーバ プロセス 8
  9. 9. 高負荷なDNSキャッシュ の状態 ワーカー スレッド ワーカー スレッド キャッシュメモリ リクエスト処理状態 管理メモリ ソケットバッファ udp/53 ワーカー スレッド ワーカー スレッド ユーザ ユーザから送られてくる多数の リクエストについて、処理①∼ ④が同時並行に行われている インターネット (権威サーバ) ソケット ソケット ソケット ソケット キャッシュサーバ プロセス 9
  10. 10. チューニングすべき箇所 ワーカー スレッド ワーカー スレッド キャッシュメモリ リクエスト処理状態 管理メモリ ソケットバッファ udp/53 ワーカー スレッド ワーカー スレッド ユーザ インターネット (権威サーバ) ソケット ソケット ソケット ソケット キャッシュサーバ プロセス ①ワーカースレッドの数 ②ユーザ通信用ソケットバッファ サイズ ③リクエスト処理状態 管理メモリサイズ ⑤キャッシュメモリ サイズ ④権威サーバ通信用ソ ケット最大数 10
  11. 11. ビルド時に 設定すべきオプション • Unbound • 多数のソケットを同時に扱えるようにlibeventとリンク してビルド • configure ̶with-libevent • BIND9 • マルチスレッドで動作するようにビルド • configure ̶enable-threads 11
  12. 12. 各項目のチューニング 12
  13. 13. ①ワーカースレッド数のチュー ニング ワーカー スレッド ワーカー スレッド キャッシュメモリ リクエスト処理状態 管理メモリ ソケットバッファ udp/53 ワーカー スレッド ワーカー スレッド ユーザ インターネット (権威サーバ) ソケット ソケット ソケット ソケット キャッシュサーバ プロセス ①ワーカースレッドの数 13
  14. 14. ワーカースレッド数の設定 • CPUを100%使い切るためには、ワーカースレッド 数を適切な値に増やす • 通常、CPUコアと同じ数だけワーカースレッドを起 動するのが良い • スレッド数は、小さすぎるとCPUを使い切れず、大 きすぎると無駄なコンテキストスイッチが多発して 性能低下の原因となる。ベンチマークを行いながら 適切な値を探る。 14
  15. 15. ワーカースレッド数 キャッシュサーバにおける設定方法 • Unbound • num-threads: <スレッド数> (デフォルト:1) • BIND9 • named起動時にCPU数を検出して自動設定す るが、named起動時の引数でも指定可能 • named -n <スレッド数> 15
  16. 16. ワーカースレッド数 設定値の決め方 • CPUコア数の合計を指定するのが良い • 4コアのCPU2個搭載マシンでは、4 2=8 • HyperThreadingなCPUでは、それを考慮した 数を指定すると性能向上の可能性も • 4(cores) 2(threads) 2(CPUs) = 16 16
  17. 17. ワーカースレッド数に伴う その他設定 • Unbound • msg-cache-slabs / infra-cache-slabs / key-cache-slabs / infra- cache-slabs • スレッド数に近い「2のN乗」の値を設定するとよい • スレッド数1∼2では2、スレッド数3∼4では4、5∼8では8を指 定 • キャッシュを構成するハッシュデータ構造のスラブ数を指定している。ワーカースレッドは、このデー タ構造アクセス時に、スラブ毎にロックを獲得するため、スラブ数とワーカースレッド数と一致させ るとロックコンテンションが減らせる。 • BIND9は、Unboundの上記設定に相当する項目無し 17
  18. 18. ワーカースレッド数に伴う その他設定 • BIND9 • UDPリスナタスク数(ワーカースレッドとは 別)の設定 • デフォルトではCPU数を自動検出してその数 を設定するがコマンドラインでも指定可能 • named -U <リスナタスク数> 18
  19. 19. ②ユーザ通信用ソケット バッファサイズ ワーカー スレッド ワーカー スレッド キャッシュメモリ リクエスト処理状態 管理メモリ ソケットバッファ udp/53 ワーカー スレッド ワーカー スレッド ユーザ インターネット (権威サーバ) ソケット ソケット ソケット ソケット キャッシュサーバ プロセス ユーザからのDNSリクエストメッセージの到着間隔は一定ではなく、一時的 に大量のバーストリクエストを受信することがある(例:昼12:00、1月1日 午前0:00) リクエストメッセージが、ソケット受信バッファからドロップされることを 防ぐため、バッファサイズを大きくしておくとよい。 ②ユーザ通信用ソケットバッファ サイズ 19
  20. 20. ユーザ通信用ソケットバッファ サイズの設定 • Unbound • so-rcvbuf: <バイト数> / so-sndbuf: <バイト数> (デフォルトはOSデ フォルト値) • OS側でソケットの最大バッファサイズが制限されていることがあるので、それも引き上 げる • (Linux sysctl) net.core.rmem_max / net.core.wmem_max • BIND9 • named.conf等では指定不可。 • ただし、OSの設定でデフォルトのソケットバッファサイズを指定可能なことがある • (Linux sysctl) net.core.rmem_default / net.core.wmem_default 20
  21. 21. ユーザ通信用ソケットバッファ サイズの決定 • いくつならよい、と言い切るのは難しいが・・・ • Unboundでは、大規模環境では 4m or 8m(バイト) という値が例示されている • 1リクエスト128バイトとすると、それぞれ3万 or 6万リクエスト分に相当 • 最繁時間帯に netstat -su で RcvbufErrors / SndbufErrors が増えているようなら、値を引き上げ る等の対応をしてもよい 21
  22. 22. リクエスト処理状態 管理メモリサイズの設定の必要性 ワーカー スレッド ワーカー スレッド キャッシュメモリ リクエスト処理状態 管理メモリ ソケットバッファ udp/53 ワーカー スレッド ワーカー スレッド ユーザ インターネット (権威サーバ) ソケット ソケット ソケット ソケット キャッシュサーバ プロセス ③リクエスト処理状態 管理メモリサイズ 処理中のユーザリクエストに つき1個生成(解決すると消滅) 多数のリクエストを同時に処 理していると、大きな領域が 必要。 (領域が不足すると、古いも のからドロップされてしまう) 22
  23. 23. リクエスト処理状態 管理メモリサイズの設定 • 未解決のリクエストを保存する最大個数を指定 • Unbound • num-queries-per-thread: <スレッドあたりの最大同時リクエスト数> • デフォルト値: 512 or 1024 (コンパイルオプションによって異な る) • BIND9 • recursive-clients <named全体の最大同時リクエスト数>; • デフォルト値: 1000 23
  24. 24. リクエスト処理状態 管理メモリサイズの決定 • いくつなら良いと言い切るのは難しいが、理論的には以下の値となる • 単位時間あたりのリクエスト受信数 1リクエストの処理にかかる平均時間 マー ジン • 1万リクエスト受信/秒、平均リクエスト処理時間0.1秒、マージン4倍ならば、 1万 0.1 4= 同時管理リクエスト数 4000 • Unbound設定: num-queries-per-thread: 2000 (2threadsの場合) • BIND9設定: recursive-clients 4000; • BIND9 ARMによると、recursive-clients 1個あたり約20kB消費す る。上記に関わらず、メモリが許す限りの大きい値に引き上げてもよ い。 24
  25. 25. リクエスト処理状態 管理メモリサイズのモニタ • Unbound • unbound-control statsでスレッド毎・プロセス全体のリクエストリ スト数(未解決の処理中リクエスト数)をモニタ可能。 • current.userが設定値に近づいていたり、exceededやoverwrittenが カウントアップしているようなら、num-query-per-threadを引き上 げる。 thread0.requestlist.avg=0 thread0.requestlist.max=0 thread0.requestlist.overwritten=0 thread0.requestlist.exceeded=0 thread0.requestlist.current.all=0 thread0.requestlist.current.user=0 thread1.requestlist.avg=0 thread1.requestlist.max=0 thread1.requestlist.overwritten=0 thread1.requestlist.exceeded=0 thread1.requestlist.current.all=0 thread1.requestlist.current.user=0 total.requestlist.avg=0 total.requestlist.max=0 total.requestlist.overwritten=0 total.requestlist.exceeded=0 total.requestlist.current.all=0 total.requestlist.current.user=0 25
  26. 26. リクエスト処理状態 管理メモリサイズのモニタ • BIND9 • rndc statusでrecursive clients数をモニタ可能。 > rndc status CPUs found: 1 worker threads: 1 number of zones: 16 debug level: 0 xfers running: 0 xfers deferred: 0 soa queries in progress: 0 query logging is OFF recursive clients: 123/2900/3000 tcp clients: 0/100 server is up and running warning: client xxx.xxx.xxx.xxx#xxxx: no more recursive clients: quota reached (最大制限値超過時:新着リクエストは捨てられる) ! • recursive clientが最大数を超えると以下の警告がsyslogに出る 現在値/ソフトリミット/最大制限値 recursive-clients soft limit exceeded, aborting oldest query (ソフトリミット超過時:古いリクエストが捨てられる) ソフトリミットは、 最大制限値が1000以下なら設定なし(0)、 それ以上の値なら「最大制限値-100」に設定さ れる 26
  27. 27. ④権威サーバ通信用ソケット 最大数の設定 ワーカー スレッド ワーカー スレッド キャッシュメモリ リクエスト処理状態 管理メモリ ソケットバッファ udp/53 ワーカー スレッド ワーカー スレッド ユーザ インターネット (権威サーバ) ソケット ソケット ソケット ソケット キャッシュサーバ プロセス ④権威サーバ通信用ソ ケット最大数 ワーカースレッドが権威サーバ とクエリ送受信するためのソケッ トの最大同時数。 port randomiseのため、権威 サーバにリクエスト送信するた びにソケットが生成される ソケット ソケット ソケット 27
  28. 28. 権威サーバ通信用ソケット最 大数の設定 • Unbound • outgoing-range: <スレッドあたりのソケット数> • デフォルト値: コンパイルオプションによって異なる • BIND9 • (named起動時オプション) named -S <namedプロセス全体のソケット数> • デフォルト値: 4096 • OS側のハード・ソフトリミットの引き上げ • Unbound/BIND9ともに、root権限で起動するとulimitを自動的に引き上げ てくれる。手動で引き上げたい時は、unbound/namedを起動するスクリプ ト中でulimitコマンドを実行 ulimit -HSn 100000 28
  29. 29. 権威サーバ通信用ソケット最 大数の決定 • Unboundでは、num-queries-per-threadの2倍の値が推奨されて いる • num-q-per-thr: 2500なら、outgoing-range: 5000 • BIND9でも理屈は同じはず? • recursive-clientsの2倍? • BIND9でソケット数の最大値に達した場合、以下のエラーが出る socket: file descriptor exceeds limit (4096/4096) 29
  30. 30. ⑤キャッシュメモリサイズの 設定 ワーカー スレッド ワーカー スレッド キャッシュメモリ リクエスト処理状態 管理メモリ ソケットバッファ udp/53 ワーカー スレッド ワーカー スレッド ユーザ インターネット (権威サーバ) ソケット ソケット ソケット ソケット キャッシュサーバ プロセス ⑤キャッシュメモリ サイズ キャッシュメモリサイズの設定。少 なければキャッシュヒット率が低下 し性能(スループット・応答遅延) が悪化し、大きすぎると物理メモリ を食い尽くしてしまう 30
  31. 31. キャッシュメモリサイズの 設定 • Unbound • rrset-cache-size: <RRsetキャッシュサイズ> (デフォルト 4m) • msg-cache-size: <メッセージキャッシュサイズ> (デフォルト 4m) • BIND9 • max-cache-size: <キャッシュサイズ> (デフォルト 制限無し) • OS側のハード・ソフトリミットの引き上げ(必要に応じ) • OS側でもプロセスあたりの使用メモリ量のリミットが設定されている場合が あるので、unbound/named起動スクリプトでulimitで引き上げる(制限無し にする)必要があるかもしれない ulimit -HSd unlimited ulimit -HSm unlimited ulimit -HSv unlimited 31
  32. 32. キャッシュメモリサイズの 決定 • Unbound • rrset-cache-sizeは、msg-cache-sizeの2倍が推奨されている • 例:rrset-cache-size: 1g / msg-cache-size: 512m • BIND9 • デフォルトは「制限無し」なので、プロセスがメモリを食い尽 くさないよう max-cache-size値を設定 • Unboundのようにrrsetとmsgで分かれているわけではなく、 max-cache-sizeでキャッシュサイズの最大値を指定 32
  33. 33. キャッシュメモリサイズ 指定上の注意 • DNSキャッシュサーバは、小さなメモリオブジェクトを大量に作成する ため、メモリ管理領域オーバヘッドが大きい • プロセスの実メモリ使用量(RSS)は、指定した合計キャッシュサイズの 2.5倍程度まで拡大することを想定するのが良い • 例:プロセスの実メモリ使用量(RSS)を 5GBまでに抑えたい場合 は、キャッシュメモリサイズは合計2GB使用する指定となる • Unbound: • rrset-cache-size: 1330m / msg-cache-size: 660m • BIND9: max-cache-size 2g; 33
  34. 34. キャッシュメモリサイズ の考え方 • 一般にキャッシュメモリが大きいほど、キャッシュヒット 率が上昇し、性能(スループット・応答時間)は向上する • キャッシュヒットしないリクエストは、ヒットしたリクエストの10倍以 上の処理コストがかかる • つまり、メモリは与えられるだけ与えるのがよい • ただし、メモリサイズがある一定以上を超えるとヒット率 はほとんど向上しなくなるので程々に 34
  35. 35. その他考慮すべき事項 35
  36. 36. ファイアウォール セッション数についての注意 ワーカー スレッド ワーカー スレッド キャッシュメモリ リクエスト処理状態 管理メモリ ソケットバッファ udp/53 ワーカー スレッド ワーカー スレッド ユーザ インターネット (権威サーバ) ソケット ソケット ソケット ソケット キャッシュサーバ プロセス ⑤キャッシュメモリ サイズ 外付けのファイアウォール装置や、 iptables等のOS付属のステートフルな ファイアウォールを適用している場合は、 最大セッション数に注意 36
  37. 37. ファイアウォールセッション 数の注意 • ステートフルなファイアウォールを適用している場合、DNS リクエストが送受信される度にFWセッションが作成される • 秒間10万リクエスト/秒・セッション維持時間30秒なら ば、同時セッション数300万 • FWセッション数には上限が設定されているため、この上限 に達しないように注意 • 上限に達してしまうと、新しいセッションが作れない= クエリを送受信できない 37
  38. 38. FWセッション数チューニングの 例 (Linux Netfilter) 最大コネクション数 net.netfilter.nf_conntrack_max 現在のコネクション数 net.netfilter.nf_conntrack_count UDPコネクションの維持時間 net.netfilter.nf_conntrack_udp_timeout NetfilterステートフルFW (iptables -m state)に関係するsysctl項目 コネクションが上限に達すると、以下のカーネルメッセージが出力さ れるので注意 ip_conntrack: maximum limit of xxxxxx entries exceeded ip_conntrack: table full, dropping packet Netfilterの最大コネクション数は、nf_conntrakモジュールロード時 の設定オプションで指定するとよい (RHEL6の設定例) options nf_conntrack hashsize=32768 /etc/modprobe.d/nf_conntrack.conf hashsize 8の値が最大コネクション数 (nf_conntrack_max)として設定される 例では32768 8 = 262144コネクション 38
  39. 39. FWだけでなくロードバランサ も注意 • 複数のキャッシュサーバに対し、ロードバラン サで負荷分散している場合は、そのセッション 数も注意 • 数十万セッション/秒を捌けるロードバランサな んて高いですよね(意味深) 39
  40. 40. 同時TCPリクエスト数 • ほとんどのDNSメッセージはUDPだが、まれにTCPが使われる • BIND9・Unoundともに、ユーザからの同時TCPリクエスト数 /権威サーバへの同時TCPリクエストの最大数に制限あり • 大規模用途や、今後Response Rate LimitやANY-to-TCP動作 をする権威サーバが増えてくると不足するかもしれない • RRLは、特定のIPから同じリクエストを短時間に多数した場合、TCビットが立っ た応答を返しTCPリクエストを強制する • ANY-to-TCPは、ANYリクエストに対してはTCビットが立った応答を返してTCP リクエストを強制する機能 40
  41. 41. 同時TCPリクエスト数の設定 Unbound • スレッド毎のユーザ同時TCPリクエスト最大数 • incoming-num-tcp (デフォルト10) • 大規模用途では10では足りないかも… • スレッド毎の権威サーバへの同時TCPリクエス ト最大数 • outgoing-num-tcp (デフォルト10) 41
  42. 42. 同時TCPリクエスト数の設定 BIND9 • namedプロセス全体の同時TCPソケット数 (TCPの他に、標準入出力等の数も含む) • reserved-sockets (デフォルト: 512) • ただし、ユーザ同時TCPリクエスト最大数は 別の制限設定あり • tcp-clients (デフォルト:100) 42
  43. 43. その他 おすすめ設定 43
  44. 44. minimal-responses • DNS応答のauthority section/additional section を(DNSプロトコル上許される範囲で)省略する機能 $ dig www.kernel.org ! ;; QUESTION SECTION: ;www.kernel.org. IN A ! ;; ANSWER SECTION: www.kernel.org. 600 IN CNAME pub.all.kernel.org. pub.all.kernel.org. 600 IN A 198.145.20.140 pub.all.kernel.org. 600 IN A 149.20.4.69 pub.all.kernel.org. 600 IN A 199.204.44.194 ! ;; AUTHORITY SECTION: kernel.org. 86400 IN NS ns0.kernel.org. kernel.org. 86400 IN NS ns1.kernel.org. kernel.org. 86400 IN NS ns2.kernel.org. ! ;; ADDITIONAL SECTION: ns0.kernel.org. 86400 IN A 198.145.19.196 ns1.kernel.org. 86400 IN A 149.20.20.144 ns1.kernel.org. 86400 IN AAAA 2001:4f8:8:10::1:1 ns2.kernel.org. 86400 IN A 149.20.4.80 ns2.kernel.org. 86400 IN AAAA 2001:4f8:1:10::1:1 ! ;; MSG SIZE rcvd: 260 $ dig www.kernel.org ! ;; QUESTION SECTION: ;www.kernel.org. IN A ! ;; ANSWER SECTION: www.kernel.org. 600 IN CNAME pub.all.kernel.org. pub.all.kernel.org. 600 IN A 199.204.44.194 pub.all.kernel.org. 600 IN A 198.145.20.140 pub.all.kernel.org. 600 IN A 149.20.4.69 ! ;; MSG SIZE rcvd: 102 min-res: no min-res: yes 44
  45. 45. minimal-responsesの効能 • DNS応答が小さくなるため、TCPフォールバックが必要と なる可能性が減る • TCP-DNSクエリを実装しないクライアントがまだ相当数 存在するため、TCPフォールバックは避けたほうが良い • BIND9では応答性能が向上することがある (最大1.5倍程度) 設定方法 (デフォルトではno) BIND9: minimal-responses yes; Unbound: minimal-response: yes 45
  46. 46. DNSラウンドロビン • UnboundはデフォルトではDNSラウンドロビン がオフ (BIND9はオン)のため、オンにするのが 望ましい • Unbound設定方法: rrset-roundrobin: yes 46
  47. 47. キャッシュサーバは、IPv4/IPv6 デュアルスタックとすべきか? • ユーザからのクエリがIPv4のみでも、可能なら権威サーバとの通 信はデュアルスタック化したほうがよい、というのが私の考え • 権威サーバへのクエリのエントロピーが増えるため、Kaminsky Attack型のキャッシュポイズニングの可能性が若干減る • 経路障害や不適切なフィルタが原因で、特定の権威サーバとの IPv4がNGになるケースがいまだにある→IPv6で救えることも • BIND9のリゾルバは、もはやデュアルスタック前提で開発され てるフシがある・・・[1] [1]「DNS運用、その時どうする?」永井さん@JANOG33 http://www.janog.gr.jp/meeting/janog33/program/dns.html 47
  48. 48. 参考文献 • Unbound: Howto Optimise • http://unbound.nlnetlabs.nl/documentation/ howto_optimise.html • BIND 9.9 Administrator Reference Manual • https://kb.isc.org/article/AA-00845/0/BIND-9.9-Administrator- Reference-Manual-ARM.html • Linux ip-sysctl.txt • linux-src/Documentation/networking/ip-sysctl.txt 48
  49. 49. 更新履歴 • 2013/3/7 ver1.0 • 初版 • 2013/3/14 ver1.1 • キャッシュメモリ指定に関する注意を修正。TCPリクエ スト数に関する注意、おすすめ設定を追加 • 2013/3/19 ver 1.2 • BIND9 UDPリスナタスクに関して追記 49
  50. 50. END 50

×