[ホーム] -> [Aache + PHP + PostgreSQL 実験室]

PHP の実行速度を上げる

持続的接続

PHP からデータベースに接続するには、普通 pg_connect 関数を使いますが、この関数は、呼ばれるたびにデータベースに接続します。普通、データベースへの接続の確立という作業は、サーバに大きく負担をかける処理の一つです。

そこで、サーバ製品の中には、一度接続したら接続を保持し、再度接続要求があったときには、保持している接続を使わせるという機能があります。コネクションプーリングとか、持続的接続とか呼ばれる機能で、PHP にもその機能があります。

やりかたは至って簡単で、pg_pconnect 関数を使って接続をするだけです。今まで、pg_connect と書いていた部分に対して、この関数を使うように変換するだけです。これで持続的接続されるようになります。

Apache で PHP を動かす場合は注意点があり、データベースコネクションが使い回されるのはプロセス単位だと言うことです。Apache が起動すると、サーバ上には複数の Apache のプロセスが起動されます。ps acux | grep httpd とかすれば確認できるかと思います。クライアントからのアクセスに対して、そのプロセスのどれか一つに処理を割り当て、そのプロセスで処理が行われますが、データベースコネクションを使い回せるのは、このプロセス単位です。あるプロセスで作成したデータベースコネクションは、他のプロセスでは利用できません。

つまり、場合によって、プロセスの数分だけデータベースコネクションが作成されることになります(プロセスオーナが root のプロセスは、処理を行わないので対象外)。

この持続的接続を制御するために、php.ini に設定項目があります。

; 持続的接続を許可するかどうか
pgsql.allow_persistent  =   On
; プロセス毎の持続的接続の最大数(-1 は無制限)
pgsql.max_persistent    =   -1
; プロセス毎の持続的接続と普通の接続を合計した最大数(-1 は無制限)
pgsql.max_links         =   -1

Apache の場合は、最初の設定以外はあまり関係ないかもしれません(一つのプロセスで一度に複数処理することはないから)。IIS や、iPlanet などの様な SAPI を使って、マルチスレッドで動くサーバに効果のある項目だと思います(確認してませんが)。

この持続的接続は、アクセスの多いサイトではとても有用だと思います。特に、Web サーバとデータベースサーバが別のマシンで動いている場合などは、比較的接続の負担は大きいので(でも、Oracle ほどじゃないと思う)、試してみてはどうでしょうか。接続がいつまでも残る不安があるかもしれませんが、経験的に言えば、増え続けていかない限り問題はないと思います。

コンパイルキャッシュ

もう一つ PHP の動作をあげるのに、PHP コンパイラの性能を上げるというのがあります。PHP のようなスクリプト言語の場合、必ず実行時にコンパイルが行われますが、その時間を短縮しようというものです。

実際この方法は二つあり、一つは Zend 社の Zend Optimizer というやつです。これは、PHP のコンパイラを置き換え、コンパイルを最適化し、実行速度を上げるというものです。バイナリ形式で配布されているので、ダウンロードし、ファイルの置き換えをすると、この機能が使われるようになります。この説明は省略させてください。

もう一つは、APC(Alternative PHP Cache)というやつで、こちらはソースコードで配布されているため、コンパイルが必要です。

APC は、PHP のソースをコンパイルしたものをキャッシュしておき、2回目以降のアクセスがあるとそのコンパイルしたキャッシュ(マシン語ではなく、中間コード)を使うというものです。これにより、実行時にコンパイルを行う作業が無くなり、動作速度が上がるという仕組みです。

ちなみに、APC 1.1.0pl1 のバージョンでは、PHP 4.2.x に対して組み込むことは出来ません。現時点では、「Current CVS version」を使う必要があります。

APC は動作モードが2種類有り、一つは mmap モードで、これはコンパイルしたものをファイルに保存しておく(メモリーマップドファイル)方法で、ディスクにファイルを書き込めるようにしておく必要があります(Apache の実行ユーザ権限で書き込む)。もう一つは、shm で、コンパイルしたものをメモり内に保存しておく方法(SystemV 共有メモリ)です。インストールした直後の状態では、この APC の機能が無効になっているので注意してください。

APC の設定に必要な項目は次の通りです。

;; APC の動作モード
;apc.mode                   = none  ; none, shm, mmap
;; キャッシュの仕組みを制御するが、safe が無難
;apc.cache_rt               = safe
;; mmap 時の保存するディレクトリの指定
;; Apache の実行ユーザ(User ディレクティブ)で書き込みできる必要がある
;apc.cachedir               = /var/lib/php/apc
;; キャッシュ対象のファイルの合計数以上がよい(最低でも 1/3 以上)
;; 1 につき、264 バイト消費する
;apc.hash_buckets           = 1024
;; キャッシュしないファイルを POSIX 正規表現で指定
;apc.regex                  =
;; shm で利用される共有メモリセグメントの数
;apc.shm_segments           = 10
;; shm で利用される一つの共有メモリセグメントあたりのサイズ
;apc.shm_segment_size       = 33554431
;; キャッシュの有効時間を設定できるかどうかを指定する(shm のみ)
;; 0:指定できない、1:指定できる
;apc.ttl                    = 0
;; コンパイルした後にソースが変更された場合、再コンパイルするかどうか
;; 0:しない、1:する
;apc.check_mtime            = 0
;; include() などのパスを解決する。1 が無難
;apc.relative_includes      = 1
;; コンパイルしたものが、ソースと同じものかどうかをチェックする
;; 0;チェックしない、1:チェックする
;apc.check_compiled_source  = 0

設定以外でも、apc_ で始まる PHP 関数も利用できるようになります。キャッシュの情報を取得したり、キャッシュの有効時間を設定したり、キャッシュ情報を削除したり出来ます。INSTALL ファイルに書かれていますので読んでください。

ちなみに、APC の動作モードは、好きな方を選択して構わないと思います。FAQ によれば、shm は、ttl の指定が出来るし、どんな Web サーバでも利用できる代わりに、SystemV 共有メモリの解放失敗(クラッシュしたときなど)の可能性がある。mmap は、どんな大きなフィルでもキャッシュ出来る、事前にコンパイルしておくことが利用できる(ファイルに保存されるから、shm はメモリ内)代わりに、ファイルの I/O が派生する、キャッシュ単位がプロセス単位、キャッシュ管理が面倒。だそうです。

ホームへ