スポンサーリンク

TUNING(7) FreeBSD 多方面の情報マニュアル TUNING(7)

名称

tuning − FreeBSD における性能チューニング

システム設定 - disklabel, newfs, tunefs, スワップ

bsdlabel(8) または sysinstall(8) を使ってハードディスク上にファイルシステ ムをレイアウトする場合、ディスクの内周トラックよりも外周トラックのほうが ずっと速くデータを転送できることを意識することが重要です。この利点を生か すには、小さいファイルシステムやスワップを外周トラックに近いほうから詰め ていくべきです。より大きいファイルシステムは内周へ近いほうへ詰めていき、 最も大きいファイルシステムを最後にします。後でマシンを増強した時にシステ ム標準のファイルシステムの大きさを変更しなくて済むような大きさに決めるこ とが重要です。私は大抵、順番にルートパーティションに 128M、スワップに 1G、 /var に 128M、 /var/tmp に 128M、 /usr に 3G、そして残りを /home に 割り当てます。

典型的にはメインメモリの約 2 倍のスワップスペースを用意すべきです。 RAM がそれほど多くない場合は、一般にもっとスワップが必要でしょう。 256M より 小さいスワップを設定するのは奨められません。スワップパーティションの大き さを決めるときは将来のメモリ増設のことを考えておくべきです。カーネルの VM ページングアルゴリズムは、スワップの大きさがメインメモリの少なくとも 2 倍 ある場合に最高の性能が出るようにチューンされています。スワップを小さくし すぎると、 VM ページ走査コードが効率的に動かなくなります。メモリをさらに 追加した時も同様です。最後に、複数の SCSI ディスク (あるいは異なるコント ローラ上にある複数の IDE ディスク) を備えた大規模なシステムにおいては、そ れぞれのドライブにスワップを置くことを強く推奨します。各ドライブ上のス ワップパーティションがほぼ同じ大きさになるようにしてください。カーネルは 任意の大きさを扱うことができますが、内部のデータ構造は最大のスワップパー ティションのものの 4 倍の大きさになってしまいます。スワップパーティション をだいたい同じ大きさにすることで、カーネルは最適な方法でスワップ空間を N 台のディスクに対しストライピングします。少々のやりすぎを気にする必要はあ りません。スワップ空間は UNIX が優雅に動作するためのものです。普段それほ どスワップを使っていなくても、プログラムの暴走で強制的にリブートしてしま う前に、回復作業をするための時間稼ぎになります。

/var パーティションをどれだけの大きさにするかは、そのマシンを何に使うかと いうことに大きく依存します。このパーティションは主にメールボックスやプリ ントスプール、ログファイルの保存場所に使われます。 /var/log を別のパー ティションにする人もいます (しかし、パーティション ID を消費しないほうが 良い極端な場合は例外です)。メールサーバやプリントサーバ、あるいは訪問数が 非常に多い Web サーバとしてマシンが動作するなら、極めて大きいパーティショ ン – おそらく 1 ギガバイト以上 – を作成することを考えるべきでしょう。ログ ファイルの保存に必要な大きさは、小さく見積もられがちです。

/var/tmp の大きさは、テンポラリファイルの類がどれだけ使われる必要があるか で決まります。最低でも 128M にすることを推奨します。また sysinstall は /tmp ディレクトリも作成します。テンポラリファイル領域専用に 1 つのパー ティションを割り当てることは重要で、2 つの理由があります: クラッシュ時の ファイルシステムの破壊の可能性を減らすのと、 [

                                                     /var]/tmp を一杯にしてしまうような暴走プロセスが、さらに重要なサブシステム (メールやログ等) に影響を与える可能性を減らすためです。 [                                           /var]/tmp が一杯になってしまうのはよくある問題です。
かつては /tmp/var/tmp の間には違いがありましたが、 /var (と /var/tmp)の導入によってプログラマは大変混乱し、今日では両方がでたらめに使われています。つまりこの 2 つは実際には区別することができません。したがって、1 つのテンポラリディレクトリだけにして、他の tmp ディレクトリからここへソフトリンクを張ることは意味があります。どのように /tmp を扱ったとしても、それがルートパーティションにあるのは好ましくないでしょう。一杯になったり、クラッシュやリブートにより破壊される可能性があるからです。
/usr パーティションはシステムをサポートするために必要なファイルの大部分を持っており、そのサブディレクトリ /usr/localports(7) 階層からインストールされるファイルの大部分が置かれます。 ports をあまり使わず、システムのソース (/usr/src) を保持するつもりがなければ /usr は 1 ギガバイトで十分でしょう。しかし、大量の ports (特にウィンドウマネージャや Linux エミュレーションされるバイナリ) をインストールする場合は、少なくとも 2 ギガバイトの /usr を推奨します。さらに、システムのソースを保持するつもりであれば、3 ギガバイトの /usr を推奨します。このパーティションに対して必要な領域の大きさを過小評価しないでください。これは緩やかに成長し、驚かされることになります !
/home パーティションはユーザ固有のデータを保持するのに使われます。私は大抵ディスクの残りを使います。
何故 パーティションを切るのでしょう ?  1 つの大きな / パーティションを作るだけで良いのではないでしょうか ?  そうすれば小さすぎないかどうか気にする必要はないのに !  はい、その考えが良くないのは、いくつか理由があります。 1 つめは、それぞれのパーティションは運用上の性格が異なるのですが、それらを分離することでファイルシステムに対しその性格に適したチューンをすることが可能になるからです。例えばルートパーティションや /usr パーティションはほとんど読み込みであり、ほとんど書き込みがありません。一方で /var/var/tmp に対しては大量の読み込みや書き込みがあるでしょう。システムをうまく分割することで、書き込みが多いパーティションの破壊による被害が、ほとんど読み込みのみのパーティションに及ばないようします。加えて、書き込みが多いパーティションをディスクの端 (すなわちパーティションテーブルにおいて、本当に大きなパーティションの後ろではなく、前の方) の方に置くことで、そのパーティションについて性能が向上します。より大きなパーティションについても入出力性能が必要なのも確かですが、 /var をディスクの端に置くと大きな改善が可能であるのに対し、巨大なパーティションをディスクの端に置いてもそれほど性能の改善にはつながりません。最後は安全性に関わることです。小さく、簡潔な、本質的に読み込みのみのルートパーティションとすることで、クラッシュを生き延びるチャンスを大きくすることができます。
システムを正しく分割することで、 newfs(8)tunefs(8) に与えるパラメータをチューンすることも可能になります。 newfs(8) のチューニングにはさらに経験が必要ですが、かなりの性能改善につながります。比較的安全にチューンできる 3 つのパラメータがあります: blocksize, bytes/inode, cylinders/group です。
FreeBSD は 8K または 16K のファイルシステムブロックサイズを使用した時に最高の性能が得られます。デフォルトは 16K であり、ほとんどのアプリケーションで良い結果となりますが、大きなファイルにランダムアクセスするアプリケーション (データベースサーバソフトウェア等) は例外です。このようなアプリケーションでは、小さなブロックサイズで良い結果となる傾向がありますが、最近のディスクの特性においては、小さなブロックサイズの使用は考慮に値しないでしょう。 16K より大きなブロックサイズを使用するとバッファキャッシュの断片化を招き、性能が低下します。
デフォルトは、多大な inode を必要とするファイルシステムや、多大な小ファイルを保持することを意図したファイルシステムには向かないかもしれません。このようなファイルシステムは、 8K または 4K のブロックサイズで作成されるべきです。これはまた、小さなフラグメントサイズを指定する必要があります。常にブロックサイズの 1/8 のフラグメントサイズにすることを推奨します (他のフラグメントサイズの割合ではあまりテストされていません)。この場合のnewfs(8) オプションは ‘‘newfs -f 1024 -b 8192 ...’’ となるでしょう。
大きなパーティションに、データベースファイルのような少数の大きなファイルを置くのであれば、 bytes/i-node の比率を増やすことができます。これは、そのパーティションの inode の数 (ファイルやディレクトリの最大の数) を減らします。 inode の数を減らすことで、クラッシュ後の fsck(8) による修復時間を大幅に減らすことができます。本当にこのパーティションに大きなファイルを置くのでない限り、このオプションを使わないでください。空き領域が大量にあるのにファイルを収容できなくなるかもしれません。 bytes/inode は、32768 か65536 か 262144 とすることが推奨されます。もっと大きな値にすることができますが、 fsck(8) による修復時間を増やすだけでしょう。例えば、 ‘‘newfs -i32768 ...’’ のようにして値を与えます。
tunefs(8) はファイルシステムをさらにチューンするのに使えます。このコマンドは、シングルユーザモードで実行することができ、ファイルシステムの再フォーマットは不要です。しかし、おそらく最も誤って使用されているプログラムでしょう。多くの人はファイルシステムの利用可能な空き領域を増やそうとして、 min-free 比率を 0 に設定します。これはファイルシステムの猛烈な断片化につながるので、推奨されません。ここで、唯一本当に価値がある tunefs(8) のオプションは、 ‘‘tunefs -n enable /filesystem’’ として softupdates を有効にすることです (注意: FreeBSD 4.5 以降では newfs(8)−U オプションを与えることで softupdates を有効にすることができます。そして sysinstall(8)は、ルート以外のファイルシステムの softupdates を標準で自動的に有効にします)。 softupdates はメタデータの性能、主にファイルの作成と削除の性能を劇的に改善します。大部分のファイルシステムで softupdates を有効にすることを推奨します。しかしながら、ファイルシステムで softupdates を使うかどうか判断する際に気をつけるべき 2 つの制限があります。 1 つめは、softupdates はクラッシュ時におけるファイルシステムの一貫性は保証しますが、未反映の物理ディスク書き込みより何秒か (1 分になることもあります!)  おそらく遅れていることです。クラッシュした場合、より多くの成果が消えてしまうかもしれません。 2 つめは、softupdates はファイルシステムブロックを解放するのを遅らせるということです。あるファイルシステム (例えばルートファイルシステム) が満杯近くの時にそれに対する大規模な更新、たとえば ‘‘make installworld’’ をすると、空き領域を使い果たして更新が失敗してしまうことがあります。そのため標準的なインストールではルートファイルシステムの softupdates を有効にしません。ルートファイルシステムは滅多に書き込まれませんので、性能上の損失はありません。
mount(8) 実行時のいくつかのオプションはファイルシステムをチューンするのに役立ちます。最も明らかで、しかも最も危険なのは async です。これは決して使わないでください。大変危険です。比較的危険度が低く、より役に立つ mount(8)のオプションは noatime です。通常 UNIX ファイルシステムは、ファイルやディレクトリにアクセスがあった場合は常に、その最終アクセス時刻を更新します。FreeBSD では、この動作は遅延書き込みで行なわれ、通常は大した負荷にはなりません。しかし、大量のファイルが連続してアクセスされた場合、バッファキャッシュがアクセス時刻の更新で汚染され大きな負荷となります。例えば、高負荷の web サイトや大量の読者を抱えるニューズサーバでは、この mount(8) のオプションで大きなパーティションにおけるアクセス時刻の更新を停止することが考えられます。根拠もなく、すべての場所でアクセス時刻の更新を停止しないでください。例えば、 /var ファイルシステムは、慣習的にメールボックスを保持し、新規メールのメールボックス中の有無判定に atime (および mtime) が使用されます。読み込み専用パーティション、 //usr では、atime をオンにしておいた方が良いでしょう。システムユーティリティには、atime フィールドを使用するものがあるので、 / では特に有用です。

ディスクのストライピング

大きなシステムでは、いくつかのドライブのパーティションを互いにストライピ ングして、全体として巨大なパーティションを作ることもあります。ストライピ ングは、入出力操作を複数のディスクに振り分けることでファイルシステムの性 能を向上させることができます。 vinum(8) および ccdconfig(8) ユーティリ ティは、シンプルなストライピングされたファイルシステムを作るのに使われま す。一般に、ルートや /var/tmp のような小さなパーティション、あるいは /usr のような本質的に読み込みのみのパーティションをストライピングしても時間の 無駄にしかなりません。本当に入出力性能を必要とするパーティションのみをス トライピングするべきです。典型的には /var, /home あるいはデータベースや Web ページを保持するカスタムパーティションです。適切なストライプサイズを 選ぶことも重要です。ファイルシステムはメタデータを 2 の累乗の境界で格納す る傾向にあり、大抵はシークを増やすのではなく減らしたいでしょう。これ は、1152 セクタといったような、シーケンシャルな I/O が両方のディスクを シークしないように、かつメタデータが単一のディスクに集中するのではなく両 方に分散するような、中心を外れた (off-centered) 大きなストライプサイズに したい、ということを意味します。本当に性能が必要なら、 FreeBSD がサポート する本物のハードウェア RAID コントローラを使うことを勧めます。

sysctl によるチューニング

sysctl(8) 変数は、実行時に、システムの動作のモニタおよび制御を可能としま す。 sysctl には、単にシステムの動作を報告するものもありますが、システム の動作を変更するものもあります。ブート時に rc.conf(5) を使用して設定可能 なものもありますが、大部分は sysctl.conf(5) で設定可能です。システムには 数百の sysctl(8) 変数が存在します。そのなかには、チューニングの候補のよう に見えますが本当はそうでないものも多く含まれます。この文書ではシステムに 最も大きな影響を与えるものだけを扱います。

kern.ipc.shm_use_phys sysctl は、デフォルトが 0 (オフ) であり、 0 (オフ) または 1 (オン) にセットすることができます。このパラメータを 1 にセットす ると、全ての System V 共有メモリセグメントがページング不可の物理メモリに マップされます。これは、(A) 大量 (数百) のプロセス間で少量の共有メモリを マッピングしているか、(B) 任意個のプロセス間で大量の共有メモリをマッピン グしている、のいずれかの場合に効果があります。この機能は、共有メモリをス ワップ不可にすることで、共有メモリをコアに結び付ける時に生じる、カーネル における内部のメモリ管理によるページ追跡オーバヘッドをかなり減らします。

vfs.vmiodirenable sysctl は、デフォルトは 1 (オン) です。このパラメータ は、ディレクトリがシステムによってどのようにキャッシュされるかを制御しま す。ほとんどのディレクトリは小さく、ファイルシステムにおいては単一フラグ メント (典型的には 1K) であり、バッファキャッシュではさらに小さくなってい ます (典型的には 512 バイト)。しかし、デフォルトモードで動作している時 は、大量のメモリを搭載していてもバッファキャッシュは固定数のディレクトリ しかキャッシュしません。この sysctl をオンにすると、バッファキャッシュが VM ページキャッシュを、ディレクトリをキャッシュするために使うことを可能に します。これによる利点は、全てのメモリがディレクトリをキャッシュするのに 使えるようになるということです。欠点は、キャッシュに使われる最小のメモリ の大きさが 512 バイトではなく物理ページサイズ (大抵は 4K) になることで す。メモリに制約があるシステムでは、このオプションをオフにすることを推奨 します。一方、オンにすると、多数のファイルを操作するサービスの性能が向上 します。そのようなサービスには、web キャッシュや、大規模なメールシステ ム、ニューズシステムなどが含まれます。このオプションは一般にメモリを消費 しますが、性能を削減することはありません。ただし実験して調べてみるべきで しょう。

vfs.write_behind sysctl は、デフォルトで 1 (オン) です。これによって、 ファイルシステムからメディアへの書き込みが、クラスタ分が集まった時に発行 されるようになります。そのような状況は、典型的には、大きなシーケンシャル ファイルへ書き込んでいる時に起こります。これは、I/O パフォーマンスに寄与 しないであろう場合に、ダーティなバッファでバッファキャッシュが飽和するの を避けるというアイデアです。しかしながら、これによってプロセスが止まるか もしれないので、状況によっては この機能を切りたいと望むかもしれません。

vfs.hirunningspace sysctl は、任意の時点においてシステム全体で、ディスク コントローラのキューに入れて未完了状態にして良い、書き込み I/O の量を決定 します。通常、デフォルト値で十分ですが、ディスクをたくさん持つマシンでは 4、5メガバイトに増やしたくなるかもしれません。値を大きくしすぎる (バッ ファキャッシュの書き込みの閾値を超えて) と、クラスタリングの効果が極端に 悪くなる可能性があるので注意してください。この値を思いつきで大きくしては いけません! また書き込みのキュー値を大きくすると、同時に発生した読みだし が待たされるかもしれません。

他にもバッファキャッシュと VM ページキャッシュに関連した、様々な sysctl が存在します。これらを変更することは推奨されません。 FreeBSD 4.3 について 言えば、VM システムは自分自身のチューニングに関して大変良い仕事をしていま す。

net.inet.tcp.sendspace sysctl と net.inet.tcp.recvspace sysctl は、ネット ワークに関連するアプリケーションを稼動している場合は特に重要です。これ は、TCP コネクションの送信および受信バッファ領域の大きさを調節します。デ フォルトでは、送信バッファは 32K で、受信バッファは 64K です。このデフォ ルトを増やすことで各コネクションについてカーネルメモリがさらに消費されま すが、帯域幅の利用率が改善することがあります。同時に数百とか数千のコネク ションを扱っている場合、このデフォルトを増やすことは推奨されません。失速 してしまったコネクションが蓄積することで、システムがメモリをすぐに使い果 たしてしまうからです。しかし、少ない数のコネクションについて広い帯域幅が 必要ならば、特にギガビットイーサネットの場合、このデフォルトを大幅に増や すことができます。入力データと出力データのバッファを個別に調整することが できます。たとえば、主に web サービスをしているマシンならば recvspace を 減らすことで、それほど大量にカーネルメモリを消費せずに sendspace を増やす ことができます。経路表 (route(8) を参照 ) に対しては、経路に特化した送受 信バッファを導入することができるということに注意してください。

付加的な管理ツールとして、ファイアウォールルールにおいてパイプ (pipe) を 使うことで (ipfw(8) を参照)、特定の IP ブロックやポートへ行く、あるいはそ こから来る帯域幅を制限することができます。例えば T1 回線を持っている場 合、 web トラフィックは回線の 70% に制限し、残りをメールとインタラクティ ブな用途に使いたいと思うでしょう。通常高い負荷の web サーバは、ネットワー ク回線が使い切られていても、他のサービスに大きな遅延を与えることはありま せんが、制限をかけることは物事を円滑にし長期的な安定につながります。ま た、多くの人が、帯域超過による課金をされないように意図的な帯域制限をかけ ています。

net.inet.tcp.rfc1323 sysctl で制御可能な TCP プロトコルのウィンドウスケー リング拡張を両方のホストがサポートしない限り、 TCP の送信あるいは受信バッ ファサイズを 65535 を超えて指定してもほとんど性能の改善はありません。ある 種のネットワークリンクから良い性能を引き出すために、これらの拡張を有効に し、 TCP バッファサイズを 65536 より大きく設定すべきです。特に、ギガビッ ト WAN リンクや、高レイテンシの衛星リンクが対象となります。 RFC1323 サ ポートは、デフォルトでオンになっています。

net.inet.tcp.always_keepalive sysctl は、TCP 実装が、コネクション上に断続 的に ‘‘keepalives’’ を配送することで死んでしまった TCP コネクションの検出 を試みるかどうかを決定します。デフォルトで、これはすべてのアプリケーショ ンについて許可されています。この sysctl を 0 に設定すると、特に keepalives を要求したアプリケーションだけが検出機能を利用できます。大抵の 環境において、死んでしまった TCP コネクションを失効にすることで、 TCP keepalives はシステム状態の管理を改善します。特にダイヤルアップのユーザに サービスを提供しているシステムでは効果があります。なぜならユーザがネット ワークとのコネクションを切る前にいつも個々の TCP コネクションを終了すると は限らないからです。しかしながら、ある種の環境では、一時的なネットワーク の停止が誤ってセッションの死と判断されるかもしれません。結果として予期し ない TCP コネクションの終了となります。その様な環境では、sysctl を 0 に設 定することで、 TCP のセッション切断の発生を減らせるかもしれません。

net.inet.tcp.delayed_ack TCP 機能は大きく誤解されています。歴史的には、こ の機能は、転送されたデータに対する確認応答を、応答と共に返せるようにする ためにデザインされました。例えば、リモートシェル上でキー入力していると き、あなたが送信した文字への確認応答は、文字のエコーを表すデータと共に返 されます。遅延確認応答をオフにすると、リモートサービスが丁度受け取った データをエコーする機会を得る前に、確認応答がそれだけを含むパケットで送ら れてしまうかもしれません。この同じ考え方がすべての対話的プロトコル (例 SMTP, WWW, POP3) にあてはまり、ネットワークの片一方を流れている小パケット を減らせるのです。 FreeBSD の遅延確認応答の実装も、TCP プロトコルの規則に 従っています。すなわち、標準の 100ms のタイムアウトが経過しなくても、 2 パケットに 1 回は確認応答を行います。通常、遅延確認応答が行う最悪のこと は、コネクションの破壊を少々遅らせること、スロースタート TCP コネクション の立ち上がりを少々遅らせることです。確かなことは分かりませんが、 SAMBA や SQUID といった package に関連する FAQ が遅延確認応答をオフにするように勧 めているのは、スロースタートの問題に言及しているのでしょう。 FreeBSD で は、スロースタートフライトサイズを net.inet.tcp.slowstart_flightsize sysctl で増やすことの方が、遅延確認応答をオフにするより、利益があるでしょ う。

net.inet.tcp.inflight.enable sysctl は、すべての TCP コネクションに対し、 バンド幅と遅延の積による制限を適用します。システムは、各コネクションに対 してバンド幅と遅延の積を計算し、ネットワークにキューされるデータ量を、最 適なスループットを確保するのに必要な量に限定しようとします。この機能が有 用なのは、モデムやギガビットイーサや高速 WAN リンク (といったバンド幅と遅 延の積が大きなネットワーク) 経由でデータを提供している場合であり、特に有 用なのは、ウィンドウスケーリングを併用している場合や大きな送信ウィンドウ を設定した場合です。本オプションを有効にする場合、 net.inet.tcp.inflight.debug を 0 (デバッグ無効) に設定することを忘れず に。実運用では、 net.inet.tcp.inflight.min を少なくとも 6144 に設定すると 有用でしょう。しかしながら、最低値を大きく設定すると、リンクによってはバ ンド幅制限を無効にする結果となり得ることに注意してください。本限定機能 は、中間ルータやスイッチのパケットキューに蓄積されるデータ量を減らし、 ローカルホストのインタフェースキューに蓄積されるデータ量をも減らします。 キューされるパケット数が少ないと、対話的コネクション、特に低速モデム経由 のものは、短い往復時間での動作が可能になります。しかしながら、この機能は データ送信 (アップロード / サービス側) にのみ影響することに注意してくださ い。データ受信 (ダウンロード) には影響しません。

net.inet.tcp.inflight.stab の調整はお勧めしません。このパラメータのデフォ ルトは 20 であり、バンド幅と遅延の積のウィンドウ計算に対して 2 個の極大パ ケットが追加されることを示します。アルゴリズムの安定化のために、追加の ウィンドウが必要となり、状態の変化に対する応答性を高めます。しかしなが ら、遅いリンク越しでは、ping の遅延を大きくしてしまいます (それで も、inflight アルゴリズム無しと比べれば、低いものです)。このような場合、 このパラメータを 15, 10, 5 に減らし、 net.inet.tcp.inflight.min も (例え ば 3500 へ) 減らすことで、望む効果が得られるかもしれません。これらのパラ メータを減らすのは、最終手段としてください。

net.inet.ip.portrange.* sysctls は、自動的に TCP や UDP ソケットに結合さ れるポート番号の範囲を制御します。 3 種類の範囲があります。すなわち、下位 の範囲、デフォルトの範囲、高位の範囲であり、 IP_PORTRANGE setsockopt(2) 呼び出しで選択可能です。ほとんどのネットワークプログラムが使用するのはデ フォルトの範囲であり、 net.inet.ip.portrange.firstnet.inet.ip.portrange.last で制御されます。それぞれ 1024 と 5000 がデフォ ルトです。範囲を限定されたポート範囲は外向きコネクションに使用され、ある 条件下ではシステムがポートを使い尽してしまう場合があります。これは、高負 荷のウェブプロキシを実行している場合に、よく発生します。通常のウェブサー バ等の主に内向きコネクションを扱うサーバや、メールリレー等の外向きコネク ションが限られているサーバを実行している場合、これは問題とはなりません。 ポートを使い果たしてしまう場合、適度に net.inet.ip.portrange.last を増や してみてください。 10000, 20000, 30000 といった値は大丈夫でしょう。ポート の範囲を変えるときには、ファイアウォールの影響も考慮に入れるべきです。 ファイアウォールによっては、広い範囲のポート (通常は下位のポート) を遮蔽 し、システムが高位のポートを外向きコネクションに使用することを期待しま す。このため、 net.inet.ip.portrange.first を低下させることはお勧めできま せん。

kern.ipc.somaxconn sysctl は、新しい TCP コネクションを受け付けるための listen キューのサイズを制限します。高負荷の web サーバ環境では、デフォル ト値の 128 は新しいコネクションを余裕をもって扱うには低すぎます。そのよう な環境では、この値を 1024 以上に増やすことが推奨されます。サービスデーモ ン (例えば sendmail(8) や apache) は自分自身の listen キューのサイズを制 限しているかもしれませんが、設定ファイルでキューのサイズを増やすディレク ティブを持つようになるでしょう。 listen キューを大きくすることは、サービ ス拒否攻撃を防ぐのにも役立ちます。

kern.maxfiles sysctl は、システムがどれだけの数のファイルをオープンできる かを決めます。デフォルトは典型的には数千ですが、データベースや記述子を大 量に使うデーモンを稼働している場合は 10000 や 20000 に引き上げる必要があ るかもしれません。読み込み専用の kern.openfiles sysctl を検査することで、 システム上で開かれているファイル数を判定可能です。

vm.swap_idle_enabled sysctl は、多数のユーザがシステムに出入りして大量の アイドルプロセスがある大きなマルチユーザシステムで便利です。そのようなシ ステムでは、フリーメモリの予約に対し、継続して重大な負担をかける傾向にあ ります。これをオンにして vm.swap_idle_threshold1 sysctl と vm.swap_idle_threshold2 sysctl でスワップアウトヒステリシス (アイドルの秒 数) を調整することでアイドルプロセスに与えられているページの優先度を通常 のページアウトアルゴリズムよりも速やかに下げることができます。これはペー ジアウトデーモンを手助けします。必要がないかぎり、このオプションはオンに しないでください。これによって起こるトレードオフは、本質的に、スワップと ディスク帯域幅をより多く消費してメモリのプリページングをより早いうちに行 うことだからです。小さなシステムではこのオプションは有害となるでしょう が、すでにある程度ページングが発生している大きなシステムでは、このオプ ションによって、全体のプロセスがより容易にメモリへ入ったり出たりするよう にできるでしょう。

ローダのチューナブル

システムの動作の一部は、そのためのメモリ割り当てをブート処理の初期に行う 必要があるために、実行時には調整不可能です。ローダのチューナブルを変更す るには、これらの値を loader.conf(5) に設定し、システムをリブートする必要 があります。

kern.maxusers は、静的なシステムテーブルの大きさを制御します。これには、 オープンファイルの最大数、ネットワークメモリ資源の大きさ等が含まれます。 FreeBSD 4.5 の時点では、 kern.maxusers は、ブート時に、システムで利用可能 なメモリ量に応じて、大きさが自動的に決定されます。また、実行時に、読み取 り専用の kern.maxusers sysctl 値を見て決定することも可能です。サイトに よっては、 kern.maxusers を大きくしたり小さくしたりする必要があり、これは ローダチューナブルで設定可能です。 64, 128, 256 は、変な値ではありませ ん。膨大なファイル記述子が必要なのでない限り、 256 より大きくすることは勧 められません。 kern.maxusers によってデフォルト値が決定される多くのチュー ナブル値は、本文書の別の場所に記述した方法で、個々にブート時または実行時 に上書き可能です。 FreeBSD 4.4 より古いシステムでは、カーネルの config(8) オプションの maxusers を設定する必要があります。

kern.ipc.nmbclusters を調整することで、システムが割り当てようとしている ネットワーク mbuf の数を増やすことができます。それぞれのクラスタは約 2K のメモリに相当するので、 1024 は 2M のカーネルメモリをネットワークバッ ファに予約することを示します。簡単な計算でどれだけ必要なのかがわかりま す。 web サーバが同時に最大 1000 本のコネクションを扱い、各コネクションが 16K の受信バッファと 16K の送信バッファを消費する場合、約 32MB に相当する ネットワークバッファを扱う必要があります。経験から得た方法によると、2 倍 すると良いとされています。つまり 32MBx2 = 64MB/2K = 32768 です。したがっ て、この場合は kern.ipc.nmbclusters を 32768 に設定します。中くらいの量の メモリが搭載されたマシンでは 1024 から 4096、さらに大量のメモリが搭載され ているなら 4096 から 32768 の値を推奨します。決して大きい値を指定すべきで はありません。ブート時にクラッシュを引き起こす可能性があります。 netstat(1)−m オプションを与えることで、ネットワーククラスタの使用状況 が分かります。古い FreeBSD ではこのチューナブルを持ちませんので、代りに カーネルの config(8) オプションの NMBCLUSTERS を設定する必要があります。

ますます多くのプログラムが sendfile(2) システムコールを使ってネットワーク を通じてファイルを転送しています。 kern.ipc.nsfbufs sysctl は sendfile(2) の実行時にファイルシステムバッファをどれだけの数だけ使えるかを制御しま す。通常このパラメータは kern.maxusers に比例しているので、極端な場合を除 いてはこのパラメータに手を出す必要はありません。詳細は、 sendfile(2) マ ニュアルページの チューニング節を参照してください。

カーネル構成におけるチューニング

大規模なシステムでは、いくつかのカーネルオプションを操作しなければならな いかもしれません。これらのオプションを変更する場合、あなたはソースから新 しいカーネルをコンパイルできなければなりません。 config(8) マニュアルペー ジやハンドブックが良い入門となるでしょう。あなただけのカスタムカーネルを 作るときに一般に最初にすることは、使用しないドライバやサービスをすべて削 ることです。 INET6 や使わないドライバを削除することで、カーネルのサイズを 時に 1 メガバイト以上減らすことができ、アプリケーションにさらにメモリを与 えることができます。

SCSI_DELAY は、システムの起動時間を減らすために使うことができます。このデ フォルト値はかなり大きく、ブート処理の中で 5 秒以上を占めるでしょう。 SCSI_DELAY を 5 秒未満に減らしてもうまく動くかもしれません (特に最近のド ライブでは)。 IDE_DELAY (PC98 でのみ利用可能) を減らしてもうまくいきます が、少々慎重になる必要があります。

*_CPU オプションの多くはコメントアウトできます。そのカーネルを Pentium ク ラスの CPU だけで動かすなら、 I386_CPU と I486_CPU は削除することができま す。ただし、 I586_CPU は、CPU が Pentium II 以上として認識されることを確 認してから削除してください。 Pentium や 486 としてさえ認識されるクローン が存在し、その場合はこれらのオプションがないと起動することができません。 もし動いたらすごいことです ! オペレーティングシステムは、MMU やタスク切 り替え、タイムベース、デバイス操作に至る、より高度な機能をより利用するこ とができるようになります。加えてより高度な CPU は、カーネルがカーネル自身 をメモリにマップする 4MB の MMU ページをサポートします。これは高いシステ ムコール負荷の下での効率を上げます。

IDE ライトキャッシュ

FreeBSD 4.3 では IDE のライトキャッシュがオフになりました。これは IDE ディスクへの書き込み帯域幅を減らしてしまうことになりますが、ハードドライ ブベンダに起因するデータの一貫性に関する重大な問題のために、必要なことだ と考えられました。基本的には、書き込み完了時期について IDE ドライブが嘘を つくという問題です。 IDE ライトキャッシュがオンであると、 IDE ハードドラ イブはデータを順番に書きこまないばかりか、ディスクの負荷が高い時にはいく つかのブロックの書き込みを無期限に延期してしまいます。クラッシュや電源故 障の場合、ファイルシステムの重大な破壊をもたらします。したがって私たちは デフォルトを安全側に変更しました。残念ながら、これは大変な性能の低下をも たらし、私たちはあきらめてこのリリース後にオンに戻しました。 hw.ata.wc sysctl 変数を見て、デフォルトをチェックしてみるべきです。もし IDE ライト キャッシュがオフになっていたら、 hw.ata.wc ローダチューナブルを 1 に設定 することでオンに戻すことができます。 ATA ドライバシステムのチューニングに 関する更なる情報は、 ata(4) を参照してください。性能が必要なら SCSI を使 いましょう。

CPU、メモリ、ディスク、ネットワーク

負荷が上がるとシステムのどの部分がボトルネックになりはじめているかによっ て、チューニングの種類が違ってきます。 CPU を使い果たしている (アイドル時 間が常に 0%) ならば、CPU をアップグレードしたり SMP マザーボード (CPU を 複数にする) に移行したり、あるいは負荷の原因となっているプログラムを見直 して最適化することを考える必要があるでしょう。スワップに対して大量のペー ジングがあるならメモリをもっと増やす必要があるでしょう。ディスク性能が飽 和している場合、CPU アイドル時間は高く、全般的にディスクが飽和状態になっ ています。 systat(1) でこれらをモニタすることができます。ディスク性能の飽 和を解決するにはいろいろな方法があります: キャッシュのためのメモリを増や す、ディスクをミラーリングする、複数のマシンに操作を分散させる等です。 ディスク性能が問題で、IDE ドライブを使っている場合、 SCSI に切り替えるこ とでずいぶんよくなります。生のシーケンシャルな帯域幅については、最近の IDE ドライブは SCSI のものに匹敵していますが、調べると大抵 SCSI ドライブ が勝っています。

最後に、ネットワーク性能を使い果たしているかもしれません。ネットワーク性 能を改善するために最初に確認すべきことは、ハブではなくスイッチを使ってい るか、ということです。特に最近はスイッチは安くなっています。ハブが高負荷 になると、コリジョンバックオフのために深刻な問題が発生します。また、1 台 のホストに問題があると、LAN 全体の性能を大幅に低下させます。次に、できる だけネットワーク経路を最適化することです。例えば firewall(7) で説明した内 部ホストを守るファイアウォールでは、外部から見えるホストはファイアウォー ルを通さないトポロジです。必要に応じて 10BaseT ではなく 100Base-T を、あ るいは 100BaseT ではなく 1000BaseT を使いましょう。最大のボトルネックは WAN 回線です (モデム、T1、DSL 等)。回線を増強できないのであれば、 dummynet(4) 機能を使ってピーク削減やその他のトラフィックシェイピングを行 い過負荷のサービス (web サービス等) が他のサービス (電子メール等) に影響 を与えるのを防いでください。逆もまた同様です。これは、家庭環境において、 外部に公開しているサービス (web サービスや電子メール) よりもインタラク ティブなトラフィック (ブラウザや ssh(1) ログイン) を優先するために使うこ とができるでしょう。

関連項目

netstat(1), systat(1), ata(4), dummynet(4), login.conf(5), rc.conf(5), sysctl.conf(5), firewall(7), hier(7), ports(7), boot(8), bsdlabel(8), ccdconfig(8), config(8), fsck(8), ifconfig(8), ipfw(8), loader(8), mount(8), newfs(8), route(8), sysctl(8), sysinstall(8), tunefs(8), vinum(8)

歴史

tuning マニュアルページは、もともと Matthew Dillon によって書かれ、 2001 年 5 月に、 FreeBSD 4.3 ではじめて登場しました。

FreeBSD 10.0 June 25, 2002 FreeBSD 10.0

スポンサーリンク