DNSキャッシュサーバ チューニングの勘所
-
Upload
hdais -
Category
Technology
-
view
11.720 -
download
9
description
Transcript of DNSキャッシュサーバ チューニングの勘所
DNSキャッシュサーバ チューニングの勘所
Daisuke HIGASHI Version 1.2 2014/3
1
この文書について• キャッシュサーバ(フルリゾルバ)として動作させたUnbound・BIND9両方について、大規模環境に適したチューニングとしてボトルネックになりやすい部分を紹介
• 対象verは Unbound 1.4.22/BIND 9.9.5 を基準としているが、それ以前でも同様の設定が可能な場合がある
• DNS権威サーバは対象外
• OSやネットワーク環境のチューニング項目、性能チューニング以外のおすすめ設定も合わせて紹介
2
チューニングの必要性• Unbound/BIND9やOSのデフォルト設定は、ハードウェアの性能を最大に発揮する設定になっていない
• 適切なチューニングをしないと、CPU使用率が少ないのに性能が頭打ち/CPUばかり食って性能が上がらない、という状況に陥る
• 「設定」とはハードウェア資源の配分方法
設定は、ほとんどの場合リミッターとして働いている。DNSキャッシュサーバのチューニングの多くは、高い性能を出すために、リミッターの上限を適切に引き上げる作業となる。
3
ワーカー スレッド
ワーカー スレッド
DNSキャッシュサーバ 内部構造
キャッシュメモリリクエスト処理状態 管理メモリ
ソケットバッファ
udp/53
インターネット(権威サーバ)
ワーカー スレッド
ワーカー スレッド
DNS リクエスト
ユーザ
キャッシュサーバ プロセス
説明しやすいように簡略化している。また、DNSサーバの実装
によって細かい差がある
4
DNSリクエスト処理(1)ワーカー スレッド
ワーカー スレッド
キャッシュメモリリクエスト処理状態 管理メモリ
ソケットバッファ
udp/53ワーカー スレッド
ワーカー スレッド
ユーザ
①ユーザからのDNSリクエスト受信、ソケットバッファにキューイ
ング
インターネット(権威サーバ)
キャッシュサーバ プロセス
5
リクエスト処理状態 管理メモリ
DNSリクエスト処理(2)ワーカー スレッド
ワーカー スレッド
キャッシュメモリ
ソケットバッファ
udp/53ワーカー スレッド
ワーカー スレッド
ユーザ
②ワーカースレッドが、ソケットからリクエスト取り出し、リクエスト管理メモ
リに格納
インターネット(権威サーバ)
キャッシュサーバ プロセス
6
DNSリクエスト処理(3)ワーカー スレッド
ワーカー スレッド
キャッシュメモリリクエスト処理状態 管理メモリ
ソケットバッファ
udp/53ワーカー スレッド
ワーカー スレッド
ユーザ
③ワーカースレッドは、キャッシュメモリを参照したり、インターネットの権威サーバに問合せたりしながら、リクエストの
答えを検索
インターネット(権威サーバ)
ソケット
キャッシュサーバ プロセス
7
DNSリクエスト処理(4)ワーカー スレッド
ワーカー スレッド
キャッシュメモリリクエスト処理状態 管理メモリ
ソケットバッファ
udp/53ワーカー スレッド
ワーカー スレッド
ユーザ
④得られたDNSの答えを、ユーザに送り返す
インターネット(権威サーバ)
キャッシュサーバ プロセス
8
高負荷なDNSキャッシュ の状態
ワーカー スレッド
ワーカー スレッド
キャッシュメモリリクエスト処理状態 管理メモリ
ソケットバッファ
udp/53
ワーカー スレッド
ワーカー スレッド
ユーザ
ユーザから送られてくる多数のリクエストについて、処理①~④が同時並行に行われている
インターネット(権威サーバ)
ソケット
ソケット
ソケット
ソケット
キャッシュサーバ プロセス
9
チューニングすべき箇所ワーカー スレッド
ワーカー スレッド
キャッシュメモリリクエスト処理状態 管理メモリ
ソケットバッファ
udp/53
ワーカー スレッド
ワーカー スレッド
ユーザ
インターネット(権威サーバ)
ソケット
ソケット
ソケット
ソケット
キャッシュサーバ プロセス
①ワーカースレッドの数
②ユーザ通信用ソケットバッファサイズ
③リクエスト処理状態 管理メモリサイズ
⑤キャッシュメモリ サイズ
④権威サーバ通信用ソケット最大数
10
ビルド時に 設定すべきオプション
• Unbound
• 多数のソケットを同時に扱えるようにlibeventとリンクしてビルド
• configure ̶with-libevent
• BIND9
• マルチスレッドで動作するようにビルド
• configure ̶enable-threads11
各項目のチューニング
12
①ワーカースレッド数のチューニング
ワーカー スレッド
ワーカー スレッド
キャッシュメモリリクエスト処理状態 管理メモリ
ソケットバッファ
udp/53
ワーカー スレッド
ワーカー スレッド
ユーザ
インターネット(権威サーバ)
ソケット
ソケット
ソケット
ソケット
キャッシュサーバ プロセス
①ワーカースレッドの数
13
ワーカースレッド数の設定• CPUを100%使い切るためには、ワーカースレッド数を適切な値に増やす
• 通常、CPUコアと同じ数だけワーカースレッドを起動するのが良い
• スレッド数は、小さすぎるとCPUを使い切れず、大きすぎると無駄なコンテキストスイッチが多発して性能低下の原因となる。ベンチマークを行いながら適切な値を探る。
14
ワーカースレッド数 キャッシュサーバにおける設定方法• Unbound
• num-threads: <スレッド数> (デフォルト:1)
• BIND9
• named起動時にCPU数を検出して自動設定するが、named起動時の引数でも指定可能
• named -n <スレッド数>15
ワーカースレッド数 設定値の決め方
• CPUコア数の合計を指定するのが良い
• 4コアのCPU2個搭載マシンでは、4×2=8
• HyperThreadingなCPUでは、それを考慮した数を指定すると性能向上の可能性も
• 4(cores)×2(threads)×2(CPUs) = 16
16
ワーカースレッド数に伴う その他設定
• 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
ワーカースレッド数に伴う その他設定
• BIND9
• UDPリスナタスク数(ワーカースレッドとは別)の設定
• デフォルトではCPU数を自動検出してその数を設定するがコマンドラインでも指定可能
• named -U <リスナタスク数>
18
②ユーザ通信用ソケット バッファサイズ
ワーカー スレッド
ワーカー スレッド
キャッシュメモリリクエスト処理状態 管理メモリ
ソケットバッファ
udp/53
ワーカー スレッド
ワーカー スレッド
ユーザ
インターネット(権威サーバ)
ソケット
ソケット
ソケット
ソケット
キャッシュサーバ プロセス
ユーザからのDNSリクエストメッセージの到着間隔は一定ではなく、一時的に大量のバーストリクエストを受信することがある(例:昼12:00、1月1日 午前0:00) リクエストメッセージが、ソケット受信バッファからドロップされることを防ぐため、バッファサイズを大きくしておくとよい。
②ユーザ通信用ソケットバッファサイズ
19
ユーザ通信用ソケットバッファサイズの設定
• 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
ユーザ通信用ソケットバッファサイズの決定
• いくつならよい、と言い切るのは難しいが・・・
• Unboundでは、大規模環境では 4m or 8m(バイト)という値が例示されている
• 1リクエスト128バイトとすると、それぞれ3万 or 6万リクエスト分に相当
• 最繁時間帯に netstat -su で RcvbufErrors / SndbufErrors が増えているようなら、値を引き上げる等の対応をしてもよい
21
リクエスト処理状態 管理メモリサイズの設定の必要性
ワーカー スレッド
ワーカー スレッド
キャッシュメモリリクエスト処理状態 管理メモリ
ソケットバッファ
udp/53
ワーカー スレッド
ワーカー スレッド
ユーザ
インターネット(権威サーバ)
ソケット
ソケット
ソケット
ソケット
キャッシュサーバ プロセス
③リクエスト処理状態 管理メモリサイズ
処理中のユーザリクエストにつき1個生成(解決すると消滅)多数のリクエストを同時に処理していると、大きな領域が必要。 (領域が不足すると、古いものからドロップされてしまう) 22
リクエスト処理状態 管理メモリサイズの設定
• 未解決のリクエストを保存する最大個数を指定
• Unbound
• num-queries-per-thread: <スレッドあたりの最大同時リクエスト数>
• デフォルト値: 512 or 1024 (コンパイルオプションによって異なる)
• BIND9
• recursive-clients <named全体の最大同時リクエスト数>;
• デフォルト値: 1000
23
リクエスト処理状態 管理メモリサイズの決定
• いくつなら良いと言い切るのは難しいが、理論的には以下の値となる
• 単位時間あたりのリクエスト受信数×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
リクエスト処理状態 管理メモリサイズのモニタ
• 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
リクエスト処理状態 管理メモリサイズのモニタ
• 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
④権威サーバ通信用ソケット最大数の設定
ワーカー スレッド
ワーカー スレッド
キャッシュメモリリクエスト処理状態 管理メモリ
ソケットバッファ
udp/53
ワーカー スレッド
ワーカー スレッド
ユーザ
インターネット(権威サーバ)
ソケット
ソケットソケット
ソケット
キャッシュサーバ プロセス
④権威サーバ通信用ソケット最大数
ワーカースレッドが権威サーバとクエリ送受信するためのソケットの最大同時数。 port randomiseのため、権威サーバにリクエスト送信するたびにソケットが生成される
ソケット
ソケット
ソケット
27
権威サーバ通信用ソケット最大数の設定
• Unbound
• outgoing-range: <スレッドあたりのソケット数>
• デフォルト値: コンパイルオプションによって異なる
• BIND9
• (named起動時オプション) named -S <namedプロセス全体のソケット数>
• デフォルト値: 4096
• OS側のハード・ソフトリミットの引き上げ
• Unbound/BIND9ともに、root権限で起動するとulimitを自動的に引き上げてくれる。手動で引き上げたい時は、unbound/namedを起動するスクリプト中でulimitコマンドを実行 ulimit -HSn 100000
28
権威サーバ通信用ソケット最大数の決定
• 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
⑤キャッシュメモリサイズの 設定
ワーカー スレッド
ワーカー スレッド
キャッシュメモリリクエスト処理状態 管理メモリ
ソケットバッファ
udp/53
ワーカー スレッド
ワーカー スレッド
ユーザ
インターネット(権威サーバ)
ソケット
ソケット
ソケット
ソケット
キャッシュサーバ プロセス
⑤キャッシュメモリ サイズ
キャッシュメモリサイズの設定。少なければキャッシュヒット率が低下し性能(スループット・応答遅延)が悪化し、大きすぎると物理メモリを食い尽くしてしまう
30
キャッシュメモリサイズの 設定
• 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
キャッシュメモリサイズの 決定
• 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
キャッシュメモリサイズ 指定上の注意
• DNSキャッシュサーバは、小さなメモリオブジェクトを大量に作成するため、メモリ管理領域オーバヘッドが大きい
• プロセスの実メモリ使用量(RSS)は、指定した合計キャッシュサイズの2.5倍程度まで拡大することを想定するのが良い
• 例:プロセスの実メモリ使用量(RSS)を 5GBまでに抑えたい場合は、キャッシュメモリサイズは合計2GB使用する指定となる
• Unbound:
• rrset-cache-size: 1330m / msg-cache-size: 660m
• BIND9: max-cache-size 2g;33
キャッシュメモリサイズ の考え方
• 一般にキャッシュメモリが大きいほど、キャッシュヒット率が上昇し、性能(スループット・応答時間)は向上する
• キャッシュヒットしないリクエストは、ヒットしたリクエストの10倍以上の処理コストがかかる
• つまり、メモリは与えられるだけ与えるのがよい
• ただし、メモリサイズがある一定以上を超えるとヒット率はほとんど向上しなくなるので程々に
34
その他考慮すべき事項
35
ファイアウォール セッション数についての注意
ワーカー スレッド
ワーカー スレッド
キャッシュメモリリクエスト処理状態 管理メモリ
ソケットバッファ
udp/53
ワーカー スレッド
ワーカー スレッド
ユーザ
インターネット(権威サーバ)
ソケット
ソケット
ソケット
ソケット
キャッシュサーバ プロセス
⑤キャッシュメモリ サイズ
外付けのファイアウォール装置や、iptables等のOS付属のステートフルなファイアウォールを適用している場合は、最大セッション数に注意
36
ファイアウォールセッション数の注意
• ステートフルなファイアウォールを適用している場合、DNSリクエストが送受信される度にFWセッションが作成される
• 秒間10万リクエスト/秒・セッション維持時間30秒ならば、同時セッション数300万
• FWセッション数には上限が設定されているため、この上限に達しないように注意
• 上限に達してしまうと、新しいセッションが作れない=クエリを送受信できない
37
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
FWだけでなくロードバランサも注意
• 複数のキャッシュサーバに対し、ロードバランサで負荷分散している場合は、そのセッション数も注意
• 数十万セッション/秒を捌けるロードバランサなんて高いですよね(意味深)
39
同時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
同時TCPリクエスト数の設定 Unbound
• スレッド毎のユーザ同時TCPリクエスト最大数
• incoming-num-tcp (デフォルト10)
• 大規模用途では10では足りないかも…
• スレッド毎の権威サーバへの同時TCPリクエスト最大数
• outgoing-num-tcp (デフォルト10)41
同時TCPリクエスト数の設定 BIND9
• namedプロセス全体の同時TCPソケット数(TCPの他に、標準入出力等の数も含む)
• reserved-sockets (デフォルト: 512)
• ただし、ユーザ同時TCPリクエスト最大数は別の制限設定あり
• tcp-clients (デフォルト:100)
42
その他 おすすめ設定
43
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
minimal-responsesの効能
• DNS応答が小さくなるため、TCPフォールバックが必要となる可能性が減る
• TCP-DNSクエリを実装しないクライアントがまだ相当数存在するため、TCPフォールバックは避けたほうが良い
• BIND9では応答性能が向上することがある (最大1.5倍程度)
設定方法 (デフォルトではno) BIND9: minimal-responses yes; Unbound: minimal-response: yes
45
DNSラウンドロビン
• UnboundはデフォルトではDNSラウンドロビンがオフ (BIND9はオン)のため、オンにするのが望ましい
• Unbound設定方法: rrset-roundrobin: yes
46
キャッシュサーバは、IPv4/IPv6デュアルスタックとすべきか?• ユーザからのクエリがIPv4のみでも、可能なら権威サーバとの通信はデュアルスタック化したほうがよい、というのが私の考え
• 権威サーバへのクエリのエントロピーが増えるため、Kaminsky Attack型のキャッシュポイズニングの可能性が若干減る
• 経路障害や不適切なフィルタが原因で、特定の権威サーバとのIPv4がNGになるケースがいまだにある→IPv6で救えることも
• BIND9のリゾルバは、もはやデュアルスタック前提で開発されてるフシがある・・・[1]
[1]「DNS運用、その時どうする?」永井さん@JANOG33 http://www.janog.gr.jp/meeting/janog33/program/dns.html
47
参考文献• 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
更新履歴• 2013/3/7 ver1.0
• 初版
• 2013/3/14 ver1.1
• キャッシュメモリ指定に関する注意を修正。TCPリクエスト数に関する注意、おすすめ設定を追加
• 2013/3/19 ver 1.2
• BIND9 UDPリスナタスクに関して追記49
END
50