性能改善ガイド

ニフティクラウド SDK for PHP は様々なウェブサービスに、最小限のオーバーヘッドでHTTP要求を送信できます。 この資料は、SDKを利用して、最適な処理性能を達成するためのガイドです。

PHPのアップグレード

PHPの最新版を使えば一般に、PHPアプリケーションの性能も向上します。 PHP 5.4はPHP 5.3に比べて、 20~40%も高速に なっているのです。 PHP 5.4以降にアップグレード すれば、処理性能を改善し、メモリ消費量も削減できます。 PHP 5.4や5.5系列へのアップグレードが難しくても、PHP 5.3.18以降にすれば効果を期待できます。

Amazon Linux AMIにPHP 5.4をインストールするコマンドは次の通りです。

yum install php54

PHP 5.5 の利用またはオペコードキャッシュ (APCなど) の活用

PHP環境全体の性能を改善するため、 PHP 5.5 の利用、APC、XCache、WinCacheなどのオペコードキャッシュを、ぜひ導入するよう推奨します。 通常、PHPの処理系はディスクからファイルを読み込み、PHPのコードをパースしてオペコードに変換した上で、このオペコードを実行します。 APCなどオペコードキャッシュの仕組みを組み込むと、パース済みのオペコードがメモリ中にキャッシュされるので、 ウェブサーバに対する要求の都度、パースする必要がありません。 理想的な状況では、このオペコードをメモリ中から直接取り出して実行できます。

SDKは、オペコードキャッシュを導入した環境でも良好に動作するよう、特に注意を払って開発されています。

Note

PHP 5.5 では、オペコードキャッシュが、デフォルトでインストールされ、有効化されています http://php.net/manual/en/book.opcache.php

もしPHP 5.5 を利用しているのであれば、このセクションはスキップして下さい

APC

もし、 PHP 5.5 を利用できない場合は、 APC をオペコードキャッシュとして利用することをおすすめします。

APCの設定変更

APCの設定は、多くのシステムで、 apc.ini ファイルに記述するようになっています。 詳しくはPHP.netの APCに関する資料 を参照してください。

Amazon Linuxの場合、APC設定ファイルは /etc/php.d/apc.ini にあります。

# You can only modify the file as sudo
sudo vim /etc/php.d/apc.ini

apc.shm_size=128M

apc.shm_size の値は128M以上に設定するよう推奨します。 アプリケーションに応じて値を調整してください。 アプリケーションを構成するファイルの数や、利用している他のフレームワーク、 さらに、データをAPCユーザキャッシュに入れるか、によって適切な値は上下します。

Amazon Linuxでは、次のコマンドでapc.shm_sizeを128Mと設定できます。

sed -i "s/apc.shm_size=.*/apc.shm_size=128M/g" /etc/php.d/apc.ini

apc.stat=0

SDKはPSR-0規約に準拠しており、クラスのオートロード機能に強く依存しています。 apc.stat=1 という設定の場合、APCはキャッシュ済みエントリごとにstatを実行して、 キャッシュ後に元のファイルが更新されていないか調べます。 したがって、PHPスクリプトがクラスをオートロードする都度、システムコールが 発生します (これはアプリケーションに対して strace を実行すれば確認可能)。

キャッシュ済みファイルごとのstat実行が不要であれば、apc.iniファイルに apc.stat=0 と設定してください。 これによりAPC全体の性能が向上しますが、キャッシュした元のファイルを更新したときには、明示的にクリアしなければなりません。 これはApacheの場合、再起動 (restartまたはgraceful) により行います。 再起動の手順を、アプリケーションの配備プロセスに組み込んでおいてもよいでしょう。

Amazon Linuxでは、次のコマンドでapc.statを0と設定できます。

sed -i "s/apc.stat=1/apc.stat=0/g" /etc/php.d/apc.ini

PHPの資料 から

デフォルト値は「オン」なので、APCは要求の都度statを実行して、スクリプトファイルが変更されていないかどうか調べます。 変更されていれば、再コンパイルし、改めてこれをキャッシュに入れます。 「オフ」であればAPCはこの確認をしません。強制的に再確認させるためには、 ウェブサーバを再起動するか、手作業でキャッシュをクリアする必要があります。 なお、FastCGIを組み込んだウェブサーバの場合、再起動してもキャッシュはクリアされないので注意してください。 スクリプトの変更がほとんどない実稼働サーバでは、statを省略することにより、大幅に性能を向上できます。

include/requireの対象ファイルにもこの設定は適用されますが、相対パス (Unixであれば先頭が「/」以外のパス) で 指定されている場合、該当するファイルを特定するため、いずれにしてもstatを実行しなければなりません。 絶対パスであればこの文字列だけでファイルを特定できるので、statを省略できます。

Xdebugのアンインストール

Xdebug は、性能改善を妨げている箇所を特定するうえで大きな効果があります。 しかし性能が最優先のアプリケーションであれば、実稼働環境にXdebug拡張をインストールしないでください。 この拡張機能をロードするだけで、SDKの処理性能が大きく低下します。

Amazon Linuxの場合、次のコマンドでXdebugを削除できます。

# PHP 5.4
yum remove php54-pecl-xdebug

# PHP 5.3
yum remove php-pecl-xdebug

PECL uri_templateのインストール

SDKは各オペレーションを実行するためにURIテンプレートを使います。 さまざまなPHP環境で動作するよう、デフォルトのURIテンプレート展開処理はPHPで記述されています。 PECL URI_Template は、Cで記述されたPHP用のURIテンプレート拡張です。 この実装は、デフォルトの実装に比べて3倍高速です。 PECL uri_template拡張をインストールすれば、アプリケーションは自動的にこれを使うようになります。

pecl install uri_template-alpha

パラメータ検査の省略

SDKはサービス記述を参照して、クライアントに対し、HTTP要求をシリアライズする方法、 HTTP応答をパースしてModelオブジェクトに変換する方法を伝えます。 クライアント側では、シリアライズに関する情報とともにサービス記述を参照して、 要求を送信する前に、オペレーション入力の妥当性を検査します。 このパラメータ検査を省略すれば、処理速度を若干改善できます。 但し通常、実稼働システムでのみ、クライアント側ファクトリメソッドの validation オプションを``false``にしてパラメータ検査を省略します。

$client = Aws\DynamoDb\DynamoDbClient::factory(array(
    'region'     => 'us-west-2',
    'validation' => false
));

インスタンスプロファイル証明書のキャッシュ

SDKに証明書を渡さず、環境変数にもその定義がなければ、SDKはIAMインスタンスプロファイル証明書を取得するため、 Amazon EC2インスタンスメタデータサービス (IMDS) への接続を試みます。 IMDSに接続し証明書を取得するためには、HTTP要求が必要です。

取得したインスタンスプロファイル証明書を、無効になるまでの間メモリ中にキャッシュすることにより、 必要の都度IMDSにHTTP要求を送信する、というコストをなくすことができます。 credentials.cache オプションを true と設定すれば、 Doctrine Cache というPHPライブラリを使って、APCに証明書をキャッシュするようになります。

$client = Aws\DynamoDb\DynamoDbClient::factory(array(
    'region'            => 'us-west-2',
    'credentials.cache' => true
));

Note

credentials.cachetrue の時、SDKに証明書をキャッシュさせるためには、 Doctrine Cacheをインストールしておかなければなりません。 doctrine/cacheをcomposer.jsonの依存関係に追加するため、 プロジェクトの required セクションに次の記述を加えてください:

{
    "required": {
        "aws/sdk": "2.*",
        "doctrine/cache": "1.*"
    }
}

通信路の閉塞状況の確認

通信が途絶えていないか (再試行が発生していないか) の確認は、 ロガーのべき乗打ち切り待機法 に 関するオプションを有効にすることにより行います。 開発時には client.backoff.logger オプションを debug にしても構いませんが、 実稼働版では Guzzle\Log\LogAdapterInterface オブジェクトを用意するとよいでしょう。

$client = Aws\DynamoDb\DynamoDbClient::factory(array(
    'region'                => 'us-west-2',
    'client.backoff.logger' => 'debug'
));

Amazon DynamoDBを使っている場合、閉塞状況の表は Amazon CloudWatch で監視できます。

頻繁にインクルードされるファイルの事前ロード

ニフティクラウド SDK for PHP はPSR-0規約に準拠しており、クラスのオートロード機能を積極的に活用します。 各クラスはそれぞれ独立したファイルで、必要が生じた時点でインクルードされます。 APCなどのオペコードキャッシュを有効にし、 apc.stat=0 と設定し、 最適化されたComposerオートローダを利用すれば、SDKを使うために必要な、 クラスのオートロードに伴う負荷を緩和できます。 同じクラスを繰り返しロードするウェブページをホストするような状況では、 オートロードされるクラスをすべてコンパイルして単一のファイルにまとめ、 オートロード処理のコストを完全になくすことにより、処理時間を少し削減できます。 この方法により、ある種のユースケース (Amazon DynamoDBセッションハンドラを使うなど) においては、 SDK側の処理ばかりでなく、アプリケーションの他の部分も高速化が可能です。 apc.stat=0 という設定であっても、使われることが事前に分かっているクラスを あらかじめロードしておけば、オートロード機能を用いるよりも若干高速になります。

コンパイル済みのオートローダファイルは、 ClassPreloader プロジェクトを 使って容易に生成できます。ニフティクラウド SDK for PHPで用いる「プリローダー」の生成方法については、 プロジェクトのREADMEを参照してください。

コードのプロファイリングによる性能改善を妨げている箇所の検出

性能改善を妨げている箇所を見出すためには、アプリケーションのプロファイルを 取得するとよいでしょう。 これは、 XdebugXHProfstrace など、 各種のツールで実施できます。 アプリケーションの性能改善に役立つ情報が、インターネット上に多数見つかります。 その一例を挙げておきましょう。