PHPは5.5以降、APCからZend OPcache+APCuに変わりました。
APCはインストールしてiniファイルを編集したりするだけでopecode cacheとdata cacheを勝手に上手い具合にやってくれましたが、APCuは自分で使うようなスクリプトを書かなければなりません。
APCがAPCuとZend OPcacheに取って代わられたワケ – Qiita
インストールしたり、iniの設定項目について解説している記事は多くありますが、実際にAPCuを利用する方法についてはあまり無いようです。
APCuはPHPスクリプト上でユーザーキャッシュを利用する関数で、PHPサイトにもリファレンスがあります。
要はPHPからメモリ領域でデータの読み書きをするための方法みたいです。
処理に時間のかかるようなデータや、DBから取得するようなデータをキャッシュしておき、2回目以降のアクセスではそれを読むといったようにして、PHPやDBの負荷を下げることが出来るようになります。
例えば、DBに接続して任意のクエリでデータを取得するスクリプトでは、取得結果をAPCuのユーザーキャッシュに保存し、次回以降のアクセスで同じクエリが来たらキャッシュを返す、とすると、DB接続のコスト削減になるわけです。
インストールについて
PHP7をyumで入れていれば、おそらく同じリポジトリでAPCuもあるはずですので、yum installできます。
yum --enablerepo=remi-php70 install php-pecl-apcu
これでインストールできます。
iniファイルはこんな感じのところにできているはずです。
vim /etc/php.d/40-apcu.ini
設定関連については省略します。yumでインストールしていれば、とりあえず使えるようにはなっているはずです。
APCuの使い方
基本的に、apc_addまたはapc_storeでデータを記録し、apc_fetchでデータを取り出すだけです。
1
2
3
4
5
6
|
//データを記録 apc_add( 'hoge' , "aaa" ); //データを取り出す $v = apc_fetch( 'hoge' ); // $v === "aaa" |
addとstoreの違いは、addは新規登録のみなのに対して、storeは既存のキーを指定しても上書きするようです。
先程の例で、DB(MySQL)からデータを取得する部分をキャッシュするとしたら、このようになると思います。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
//検索したいテーブルのIDをGETで取得し、データを返すスクリプト。 //テーブルの中身はid,v,dateとします。 $qval = intval ( $_GET [ "id" ] ); //DBクエリの変数(ここではテーブルのIDとします) $key = "query_key_" . $qval ; //このクエリのAPCu用キー //APCuにキャッシュがあるか確認 if ( apc_exists( $key ) ) { //キャッシュがあるので、それを変数に list( $id , $v , $date ) = apc_fetch( $key ); } else { //キャッシュが無いのでDBに接続 ( mysqliの変数定義部分は省略してます ) $con = new mysqli(HOST, USERNAME, PASS, DBNAME); $stmt = $con ->prepare( "select `id`,`v`,`date` from DBNAME.TABLE_NAME where `id` = ?" ); $stmt ->bind_param( "i" , $qval ); $stmt ->execute(); $stmt ->bind_result( $id , $v , $date ); $stmt ->fetch(); $stmt ->close(); //データがDBから取得できていたらAPCにキャッシュする if ( ! empty ( $id ) ) { add_apc( $key , array ( $id , $v , $date ) ); } } //出力 echo "id:" . $id . "\n" ; echo "v:" . $v . "\n" ; echo "date:" . $date . "\n" ; |
MySQLからの取得結果を配列にして任意のキーに格納しています。
最初にアクセスしたユーザーがAPCuにクエリ結果をキャッシュするので、次からアクセスしたユーザーはキャッシュのデータを取得するようになり、DBには接続しなくなります。
なお、DBのデータが更新・削除などされた場合は、キャッシュに反映させなくてはならなくなります。
先程のようなクエリでも、データ内容が変わるようなことがある場合は、そのタイミングでAPCuのデータを消すなどする必要があるのです。
1
2
3
4
|
$qval = 1; //編集されたデータのID $key = "query_key_" . $qval ; //APCu用キー //指定のキーのデータを消す apc_delete( $key ); |
とりあえず削除すれば、また先程のスクリプトのアクセスユーザーがキャッシュを作るので、内容は更新され、その次のユーザーからまたキャッシュを参照するようになります。
こんな感じで、DB接続のキャッシュとしてAPCuを利用するようにできました。
クエリの内容によっては、だいぶ負荷を下げられると思いますので、誰がアクセスしても同じ結果になる、更新性のあまり無いページのデータなどは積極的にAPCuにキャッシュするといいですね。
コメント
>基本的に、acp_addまたはapc_storeでデータを記録し、
acp_add -> apc_add
修正しました!