Unbound - 最適化の方法
これはunboundを最適化するためのガイドです。ほとんどのユーザはこれを行う必要はありません。しかし、大規模なリゾルバでは役に立つでしょう。下記の文書はunboundユーザからのフィードバックの結果です。異なる経験や推奨があれば、私に知らせてください。
設定
num-threads
をシステムのCPUのコア数に等しくなるように設定します。例えば、2コアのCPUが4個あれば、8を使います。
*-slabsをnum-threads
の値に近くなる2の累乗に設定します。msg-cache-slabs
とrrset-cache-slabs
とinfra-cache-slabs
とkey-cache-slabs
に対してこれを行います。これはロックの競合を減らします。
キャッシュのメモリサイズを増やします。msgキャッシュメモリの約2倍のrrsetキャッシュメモリを使ってください。例えば、rrset-cache-size: 100m
とmsg-cache-size: 50m
です。mallocのオーバーヘッドにより、総メモリ使用量は設定ファイルに記入した総キャッシュメモリの2倍(あるいは2.5倍)まで増える可能性があります。
outgoing-range
を可能な限り値を大きくするように設定します。全体で1024の制限を乗り越える方法については後述するセクションを見てください。これにより一度に多くのクライアントにサービスを提供します。1コアでは、950。2コアでは、450。4コアでは、200。num-queries-per-thread
はoutgoing-range
の半分の数に設定するのが最もよいです。しかし、クエリーの数が突出したときにそれを吸収できるだけたくさん欲しいでしょう。outgoing-range
の制限のためにnum-queries-per-thread
も制限されます。outgoing-range
の1024の制限をなくせるように、(下記のセクションに示す)libeventを使うようにコンパイルするのがよいでしょう。
負荷の高いサーバではso-rcvbuf
をより大きな値(4mか8m)に設定します。これは負荷が突出したときにメッセージが失われないようにカーネルバッファを大きく設定します。応答信頼性(reply-reliability)のパーセンテージにさらに9sを加えます。OSは最大値で上限をかけます。Linux上ではunboundはその制限を回避するためにroot権限を必要とします。あるいは管理者はsysctl net.core.rmem_max
を使うことができます。BSDでは、/etc/sysct.conf
でkern.ipc.maxsockbuf
を変えます。OpenBSDではヘッダを変え、カーネルを再コンパイルします。Solarisではndd -set /dev/udp udp_max_buf 8388608
を行います。
最適化した設定の短い概要をここに示します。
# some optimisation options. server: # use all CPUs num-threads: <number of cores> |
デフォルトの設定はうまく働きます。しかし、多くのユーザにサービスを提供する必要があるときにはシステムの制限に達してしまいます。大部分はファイル記述子の数です。デフォルトで1024の制限があります。1024個より多くのファイル記述子を使うためには、libeventかフォーク運用を使います。これらについては下のセクションで記述します。
Libeventの使い方
libeventはプラットホーム特有のイベント通知システムコールのBSDライセンスのクロスプラットフォーム ラッパーです。
Unboundは1024個より多くのファイル記述子を効率よく使うためにlibeventを使うことができます。お好みのパッケージ マネージャでlibeventを(もしあればlibevent-develも)インストールします。unboundをコンパイルする前に、./configure --with-libevent
を実行します。
そうすれば、outgoing-range
にお好みのどんな数でも設定することができます。同様にnum-queries-per-thread
の値も増やせます。
# with libevent
outgoing-range: 8192
num-queries-per-thread: 4096
|
libevent-1.4.8-stableでうまく動いているとのユーザからの報告があります。LinuxとFreeBSDで4096や8192を値として設定してうまく動いていることをユーザが確認しています。num-queries-per-thread
を2倍にしてoutgoing-range
として使います。
安定版の(古い)ディストリビューションではlibevent-1.1のような古いバージョンのパッケージが含まれています。このようなパッケージではクラッシュの報告があります。そのため、libeventをアップグレードする必要があります。unbound 1.2.0では、libeventコールの競合条件が修正されました。
unboundはlibeventやlibevのビルド ディレクトリを指定してコンパイルできます; configure --with-libevent=/home/user/libevent-1.4.8-stable
やconfigure --with-libevent=/home/user/libev-3.52
のように指定します。
備考 いずれせよクラッシュを経験したら、以下のことを試すことができます。libeventを更新します。問題が存続するのであれば、libeventは環境変数をセットすることにより異なるシステムコール バックエンドを使うことができあます。unboundはverbosityをレベル4にするときに使用中のバックエンドを報告します。unboundを開始する前に、EVENT_NOKQUEUE
やEVENT_NODEVPOLL
や EVENT_NOPOLL
やEVENT_NOSELECT
やEVENT_NOEPOLL
や EVENT_NOEVPORT
をシェルでyesに設定することで、それらのバックエンドが除外できます。poll(2)バックエンドは信頼できますが、遅いです。
フォーク動作
unboundはスレッディングなしに動作する独特なモードを持っています。これは、libeventがプラットフォームで失敗するとき、更なる性能のため、毒が他に入らないようにコア間で壁を作るときなどに役に立ちます。
フォーク動作を使うようにコンパイルするためには、コンパイル前にスレッドを無効にして、フォーク動作を有効にするために./configure --without-pthreads --without-solaris-threads
を実行します。ロッキングが行われないため、そのコードは10%から20%くらい速度が向上します。
設定ファイルには、(スレッドではなくプロセスを使うとしても)num-threads
に使いたいコア数を指定します。そして、outgoing-range
とキャッシュメモリの値はすべてスレッド毎にあります。これはコア毎にコア自身のキャッシュを使うため、もっと多くのメモリが使われることを意味します。コア毎に自身のキャッシュを持つため、キャッシュに毒入れされたときでも他のコアには影響はありません。
# with forked operation server: # use all CPUs num-threads: <number of cores> |
プロセス毎に多くても1024個のファイル記述子を使っているため、有効な最大値はコア数×1024です。上述した設定ではプロセス毎に950個を使います。4つのプロセッサでは3800個のソケットを与えます。クエリー毎にソケットを取得することを保証し、いくつかのソケットをqueries-for-nameserversに割かせるために、スレッド毎のクエリー数はソケットの数の半分です。
libeventといっしょにフォーク動作を使うことも可能です。スレッドの代わりに異なるプロセスにファイル記述子をOSに提供させるのに役に立ちます。基底にあるネットワーク スタックがプロセス毎の(遅い)検索構造を使っていれば、これは(急進的な)異なる性能を持つでしょう。
この文章はUnbound: Howto Optimise (www.unbound.net)の翻訳です。[翻訳: 滝澤 隆史]