Solaris カーネルのチューンアップ・リファレンスマニュアル

UFS

bufhwm

説明

入出力バッファのキャッシュに使用するメモリー量の最大値。バッファは、ファイルシステムのメタデータ (スーパーブロック、i ノード、間接ブロック、ディレクトリ) の書き込みに使用されます。バッファは、その量が bufhwm に達するまで必要に応じて割り当てられます。bufhwm に達すると、バッファを再利用して要求を満たします。

歴史的経緯により、このパラメータには必要ありません、ufs: 接頭辞。

データ型

符号付き整数

デフォルト

物理メモリーの 2%

範囲

80K バイトから物理メモリーの 20%

単位

K バイト

動的か

いいえ。この値は、ハッシュバケットサイズの計算に使用された後、データ構造体に格納されます。このデータ構造体は、バッファの割り当てや解放に応じて、そのフィールドの値を調整します。動作しているシステムのロック手順に従わずにこの値を調整すると、正しくない動作を招くおそれがあります。

検査

bufhwm が 80K バイトより小さいか、bufhwm が、物理メモリーの 20% もしくは現在のカーネルヒープ値の 2 倍のうち小さい方より大きい場合、bufhwm は、物理メモリーの 20% か現在のカーネルヒープ値の 2 倍のうち小さい方にリセットされます。その場合は、次のメッセージがシステムコンソールと /var/adm/messages ファイルに出力されます。

binit: bufhwm out of range (value attempted). Using N.

value attempted」は、/etc/system で指定された値か kadb -d の使用による値を表します。「N」は、使用可能なシステムメモリーに基づいてシステムが計算した値です。

どのような場合に変更するか

バッファは必要が生じた時にのみ割り当てられるため、デフォルト設定によるオーバーヘッドは、考えられる最大のバッファ数を処理するために必要になる制御構造体が割り当てられることです。これらの構造体は、32 ビットカーネルでは想定されるバッファ当たり 52 バイト、64 ビットカーネルでは想定されるバッファ当たり 104 バイトを消費します。512M バイトの 64 ビットカーネルでは、この構造体は 104*10144 バイト (約 1M バイト) を消費します。ヘッダーの割り当てでは、バッファサイズは 1K バイトであると想定します。ただし、ほとんどの場合、バッファサイズはこれより大きいのが普通です。

バッファプール内でまだ割り当てられていないメモリー量を知るには、カーネルデバッガを使用して、カーネルの bfreelist 構造体を調べます。この構造体の bufsize フィールドが、残っている可能性があるメモリーのバイト数です。mdb を使用して buf マクロでこのフィールドを表示するには、次のようにします。


# mdb -k
Loading modules: [ unix krtld genunix ip nfs ipc ]
> bfreelist$<buf
bfreelist:
[ 省略 ]
bfreelist + 0x78:	bufsize			[ 省略 ]
				 	      75734016

6G バイトのメモリーを持つこのシステムの bufhwm は 122277 です。要求される実際のバッファサイズは一般に 1K バイトより大きいため、使用されるヘッダー構造体の数を直接知ることはできません。ただし、一部の領域は、このシステムに割り当てられた制御構造体からうまく回収されることがあります。

512M バイトシステム上でこの構造体が、10144K バイトのうち 4K バイトだけがまだ割り当てられていないことを示したとします。また、kstat -n biostatsbiostatskstat を調べると、このシステムでは、buffer_cache_hitsbuffer_cache_lookups の割合も適切であることが分かったとします。これらの情報は、このシステムのデフォルト設定であることを示します。

コミットレベル

変更の可能性あり

ndquot

説明

UFS ファイルシステムに割り当てるべき割り当て (quota) 構造体の数。このパラメータは、1 つまたは複数の UFS ファイルで割り当てが有効になっているときだけ適用されます。歴史的経緯により、ufs: 接頭辞は必要ありません。

データ型

符号付き整数

デフォルト

((maxusers × 40) / 4) + max_nprocs

範囲

0 から MAXINT

単位

割り当て構造体

動的か

いいえ

検査

なし。値が大きすぎると、システムがハングします。

どのような場合に変更するか

デフォルトの割り当て構造体数では十分でない場合。このような状況は、コンソールやメッセージログに出力される次のメッセージから判別できます。


dquot table full
コミットレベル

変更の可能性あり

ufs_ninode

説明

メモリーに保持する i ノードの数。i ノードは、ファイルシステム単位ではなく、全体としてキャッシュされます (UFS の場合)。

この場合のキーとなる変数は ufs_ninode です。このパラメータを使用して、i ノードキャッシュの処理に関係する 2 つのキーとなる境界値が計算されます。高位境界値は ufs_ninode / 2、下位境界値は ufs_ninode / 4 で計算されます。

システムが i ノードの処理を終わると、次のどちらかが起こる可能性があります。

  1. i ノードによって参照されるファイルがもはやシステムにないため、その i ノードが削除される。i ノードが削除されると、その空間は i ノードキャッシュに戻され、別の i ノード (ディスクから読み込まれるか、新規ファイル用に作成されるもの) 用に使用されます。

  2. ファイルは存在するが、実行プロセスに参照されていない。i ノードは遊休キューに入れられます。参照されていたページはメモリーに残ります。

i ノードを遊休化する場合、カーネルはこの遊休化処理を一定の時期まで先送りします。ファイルシステムがロギングファイルシステムの場合も、カーネルは i ノードの削除を先送りします。これを行うのは 2 つのカーネルスレッドです。それぞれのスレッドが一方のキューを処理します。

先送りされていた処理が終わると、システムはその i ノードを削除キューか遊休キューに入れます。それぞれのキューには、そのキューを処理できるスレッドがあります。i ノードがキューに入れられると、キューの占有率が下位境界値と比較され、占有率が下位境界値を超えていると、そのキューに関連するスレッドが起こされます。起こされるとスレッドはキューを調べ、i ノードに結びつけられたページがあればディスクに書き出し、i ノードを解放します。スレッドは、起こされた時にキューにあった i ノードの 50% を削除すると停止します。

遊休スレッドの処理が負荷に追いつかない場合は、2 つめの機構が使用されます。システムは、vnode を見つける必要があると、ufs_vget ルーチンを実行します。vget は「最初に」遊休キューの長さを調べます。長さが高位境界値を超えていると、遊休キューから 2 つの i ノード取り出し、遊休化します (ページをフラッシュし、i ノードを解放する)。vget は、自身が使用する i ノードを取得する「前に」これを行います。

システムは、コア内にページがない i ノードを遊休リストの先頭に置き、ページがある i ノードを遊休リストの終わりに置くことによって最適化を図ります。しかし、リストの順序に関し、それ以外の処理は行いません。i ノードは常に遊休キューの先頭から削除されます。

i ノード全体がキューから削除されるのは、同期 (sync)、アンマウント、または再マウントが行われるときだけです。

歴史的経緯により、このパラメータには必要ありません、ufs: 接頭辞。

データ型

符号付き整数

デフォルト

ncsize

範囲

0 から MAXINT

単位

i ノード

動的か

はい

検査

ufs_ninode が 0 以下の場合、この値は ncsize に設定されます。

どのような場合に変更するか

デフォルトの i ノード数では足りない場合。kstat -n inode_cache で報告される maxsize reached フィールドが kstatmaxsize フィールドより大きい場合は、ufs_ninode の値が小さすぎる可能性があります。ただし、先に述べた i ノードの遊休化が過度に発生するのも問題です。

このような状況を知るには、kstat -n inode_cache を使用して inode_cache kstat を調べます。thread idles はバックグラウンドスレッドが遊休化した i ノード数を、vget idles は i ノードを使用する前の要求プロセスによる遊休数をそれぞれ表しています。

コミットレベル

変更の可能性あり

ufs:ufs_WRITES

説明

ufs_WRITES がゼロ以外の場合、ファイルに書き込むべき未処理のバイト数が調べられます。次に、ufs_HW を参照し、書き込みを行うべきか、未処理のバイト数が ufs_LW になるまで書き込みを延期すべきかが判定されます。未処理のバイト数のトータルはファイルごとに管理されるため、あるファイルの未処理のバイト数が限度を超えても、それが他のファイルに影響を与えることはありません。

データ型

符号付き整数

デフォルト

1 (有効)

範囲

0 (無効)、1 (有効)

単位

切り替え (オン/オフ)

動的か

はい

検査

なし

どのような場合に変更するか

UFS の書き込みスロットル (抑制) を全体的にオフにしたい場合。十分な入出力能力がない場合は、このパラメータを無効にすると、ディスクに対するサービスキューが長くなるおそれがあります。

コミットレベル

変更の可能性あり

ufs:ufs_LWufs:ufs_HW

説明

ufs_HW は 1 つのファイルに対する未処理のバイト数の境界値です。未処理のバイト数がこの値を上回り、ufs_WRITES が設定されていると、書き込みは延期されます。書き込みの延期は、書き込みを行うスレッドを、条件変数で眠らせることで行われます。

ufs_LW は 1 つのファイルに対する未処理のバイト数の境界値です。これを下回ると、他の処理が休眠状態となっている原因の条件変数が切り替えられます。書き込みが終了し、バイト数が ufs_LW を下回ると、条件変数が切り替わり、それによってその変数で待機しているすべてのスレッドが立ち上がり、それぞれの書き込みを行おうとします。

データ型

符号付き整数

デフォルト

256 × 1024 (ufs_LW) と 384 × 1024 (ufs_HW)

範囲

0 から MAXINT

単位

バイト

動的か

はい

検査

なし

暗黙的制約

ufs_LWufs_HW は、ufs_WRITES がゼロでないときだけ意味があります。たとえば ufs_LWufs_HW が近すぎると複数のスレッドが立ち上がってもいずれも書き込みを実行できないことがあったり、あるいは ufs_LWufs_HW が離れすぎていると複数のスレッドが必要以上に待たされることがあるなどの不要な問題を避けるために、ufs_HWufs_LW は共に変更する必要があります。

どのような場合に変更するか

ファイルシステムがストライプ化ボリュームから構成されている場合は、これらの値の変更を検討します。使用可能な合計帯域幅が ufs_HW の現在の値を簡単に超える可能性があります。残念ながら、この値はファイルシステムごとに設定されるものではありません。

ufs_throttles が普通の値ではない場合。現在、ufs_throttles はカーネルデバッガでのみアクセスできます。

コミットレベル

変更の可能性あり