※このエントリーは、developerWorks : AIX and UNIXの「Advanced performance tuning concepts」を翻訳したエントリーのPart 2です。

【訳注】 「パフォーマンスチューニングの応用概念 Part 1」の続きのエントリーです。

ディスク

ディスクはメモリーと比べると遅いため、過剰なディスクアクセスはアプリケーションのレスポンス低下を招きます。ディスクアクセスの原因は上述したスワッピングかもしれませんし、アプリケーションやOSからの要求によるものかもしれません。過剰なログ書き出しもディスクアクセスの渋滞を招きます。

ディスクのボトルネックを探し出すのに最適なツールはiostatです。このツールを使えば、ある一時点でどのくらいの読み書きが発生しているかが分かり、どれくらいディスクコントローラが混雑しているかが把握出来ます。複数のディスクが搭載されているならば、負荷をディスク分散するのは非常に有効な方法です。なぜなら、ディスクの待ち時間のうち最も大きなものがシークタイムだからです。ログファイルやデータベース・ジャーナルなどのように継続的にファイルが肥大化するものは、アプリケーションやデータベースのディスクとは別のディスクに配置すべきです。

vmstatとiostatのどちらでも、システムがiowaitに費やしている時間のパーセンテージが表示されます。iowaitとは、CPUはアイドル状態ですが、システムとしてはIOのリターンが来るのを待っている状態を指します。高いiowaitの値は、ディスクが遅い、または過負荷になっていることを示唆しています。

ディスクの密接に関係している部分では、オープンすることが出来るファイル・ディスクリプターの数が挙げられます。ファイル・ディスクリプターが枯渇すると、ファイルを開こうとしても失敗します。一般的には、ulimitコマンドでファイル・ディスクリプターの数を増やす事が出来ますが、OSにカーネルの制限があった場合、ulimitコマンドがうまく動作しないかもしれません。

ネットワーク

ネットワークは大部分のアプリケーションで大きな比重を占めるものです。それはデータが、サーバーとクライアント間を移動するものだからです。低速なネットワークでは、アプリケーションのレスポンスが悪いように見えます。最初になすべきことは、すべてのサーバーとのスイッチのポートが正しく設定され、可能な限り最高速度かつ全二重通信に固定されていることを確認することです。サーバーとスイッチ間の速度と二重通信設定の設定間違いは、しばしばネットワークの問題の原因となります。

OSはネットワークリソース向けのバッファを複数割り当てています。例えば、OSはTCP接続ごとにTCP送信キューを保持しています。このキューは、アプリケーションが送信したが、相手先からAckが返ってこない場合にデータを保持します(Ackされていないパケット数によってはネットワークに送信されていないかもしれません)。このキューがいっぱいになると、未処理のデータが捌けるまではアプリケーションはこれ以上のデータを送信出来なくなります。

バッファの混雑の予兆は、netstat -aコマンドで確認することが出来ます。このコマンドでは、ネットワークカウンターのリストが表示されます。「queue」や「overflow」という言葉はTCPキューと関連があり、監視対象とすべきものです。これらのカウンターは、一般的にはブート時にのみリセットされます。そのため、徐々に増加しているようならば、注意をすべきです。

netstat -anで待ち状態(CLOSE_WAITやFIN_WAIT_1)になっているコネクションが多数表示されるようならば、それらの新鮮でないコネクションのためにシステムリソースが使用状態になっているため、新しい接続の確立に問題が発生する恐れがあります。このケースでは、タイムアウト値を減らすことにより、OSが保持するコネクションの時間をコントロールすることが出来ます。Solarisではnddコマンド、AIXではnoコマンドで変更可能です。

Javaメモリー

これまでのセクションでは、システムでチューニングが必要な広範囲の領域について述べてきました。その一つがメモリーです。Javaアプリケーション環境では、サーバーはJavaプロセスにメモリーを割り当て、アプリーケーションコードはその上で実行されます。JavaプロセスとはJVMであり、それ自身でアプリケーションにメモリーを割り当てています。

OSのレイヤーから見ると、Javaプロセスに対してギガバイトのメモリーを割り当てているように見えるかもしれません。そのプロセスの内部では、JVMはヒープを管理しています。ヒープは、新しく入ってくるオブジェクトのためのメモリー領域のことです。オブジェクトが作成されると、ヒープに配置されます。そして、そのオブジェクトが破棄されても、それらはヒープに残ります。JVMによって実行されるガーベジ・コレクションというプロセスは、認知されているオブジェクトをマークし、ヒープの残りの部分を次回の割り当てに使うために掃除してしまいます。ガーベジ・コレクションで十分な空きが確保出来なかった場合、次のメモリー割り当ての際にヒープが広がってしまいます。また、JVMがヒープが大き過ぎると判断する水準まで達した場合には、圧縮されてしまいます。

ガーベジ・コレクションの最も単純な定義からは、ガーベジ・コレクションが実行されている間はどんなアプリケーションも実行出来なくなると考えられます。JVMは、ガーベジ・コレクション実行中は効果的に静止します。それゆえに、Javaのチューニングというのは、最適なヒープのメモリーサイズを決定することと、ガーベジ・コレクション・プロセスのチューニングが大部分を占めます。

ガーベジ・コレクションのチューニングに関する大まかな考えとしては、どのくらいの頻度で実行し、どんな状態になれば実行される必要があるかを判断した上で、ガーベジ・コレクションの影響を最小限にするためにJVMの設定変更をすることです。

【訳注】 「パフォーマンスチューニングの応用概念 Part 3」に続きます。