はじめまして。リスペクトの山内です。
昨年度プログラマとして新卒で入社し、ようやくプログラマ歴二年目に突入したところです。
さて、今回ブログを初めて書くにあたり、キャッシュについて取り上げてみようと思います。
データベースに無駄なリクエストを送らないようにしたりして処理を高速化する便利機能ですが、プログラミング初心者だと、なかなか処理速度にまで目が行かず、キャッシュにじっくり触る機会も少ないのではないでしょうか。
かくいう自分もそんなプログラミング初心者の一人なので、初心者脱却を目指してキャッシュについて調べてみました。
以下、概要です。
本記事は
- CakePHPでのCacheクラスの使い方
- CakePHPで使用できるキャッシュシステムの導入方法
について取り上げます。
今回の環境
- CentOS 6.7
- Apache 2.2.15
- PHP 5.5.28
- CakePHP 2.8.3
CakePHPのCacheクラスについて
キャッシュは主に、データベースなど外部のリソースから何度も同じデータを読み込みたいときに利用されます。
キャッシュの種類によってしくみは様々ですが、何度も利用することがわかっているデータをあらかじめキャッシュしておくことで、二度目以降のデータの呼び出しを高速化します。
CakePHPにはCacheクラスがあります。
このCacheクラスのなにがいいかというと、設定さえちゃんとしておけば、様々なキャッシュシステムを一貫した作法で使うことができるという点です。Cacheクラスを使えば、異なるキャッシュエンジンを使用したいときも容易に交換できます。
Cacheクラスの使い方
Cacheクラスは実際に使用する前に設定を行います。
Cache::config(‘test’, array( ‘engine’ => ‘File’, ‘duration’ => ‘+1 hours’, ‘prefix’ => ‘test_cake_’, ));
config()メソッドでこのようにすると、test
という名前の設定が作られます。主な設定項目の内容は以下のとおりです。ここでは全キャッシュエンジン共通の設定項目を紹介します。
設定項目 | 概要 | デフォルト |
---|---|---|
engine | 使用するキャッシュエンジン | |
duration | キャッシュの有効期限 | 3600 |
probability | キャッシュクリアの確率 | 100 |
prefix | キーのプレフィックス | ‘cake_’ |
group | キャッシュのグループ | array() |
その他設定項目はキャッシュエンジンによって様々なので、それぞれの項を参照してください。
また、Cacheクラスの主なメソッドは以下のようになっています。
Cache::write(‘key’, ‘value’, ‘test’);
test
という名前の設定を使い、key
というキーでvalue
という値をキャッシュします。
Cache::read(‘key’, ‘test’);
test
という名前の設定を使い、key
というキーにキャッシュされた値を取得します。
Cache::delete(‘key’, ‘test’);
test
という名前の設定から、key
というキーのキャッシュを削除します。
この他にもCacheクラスには様々なメソッドがあります。詳しくは公式のAPIを参照してください。
キャッシュエンジン
CakePHPはv.2.8.3現在、7つの組み込みのキャッシュエンジンを用意しています。
- FileCache
- ApcCache
- Wincache
- XcacheEngine
- MemcacheEngine
- MemcachedEngine
- RedisEngine
(ちなみに最新のv3.*系ではMemcacheEngineがなくなり、すべてfalseを返すNullEngineが新たに追加されているようです。)
それぞれのキャッシュエンジンについて、導入方法から見ていきましょう。
キャッシュエンジンについて
FileCache
FileCacheは、ローカルファイルを使用するシンプルなキャッシュです。
CakePHP2.3以降はデフォルトのキャッシュエンジンになっており、CakePHPのコア内部でもFileCacheは使用されています。
なのでキャッシュが機能していれば、app/tmp/cacheなどにもキャッシュファイルが格納されています。
FileCacheのいいところは、何よりもそのシンプルさにあります。
ローカルファイルを作成してそこにデータを保存するだけなので、それほど高速なキャッシュではありませんが、それでもいちいち無駄にデータベースを叩くよりよっぽど高速ですし、他のキャッシュエンジンと違いPHP拡張などを導入する手間がありません。
求める処理速度にそこまで切羽詰まったものがなければ、まずはお手軽にFileCacheを導入してみてはいかがでしょうか。
Cache::config()で設定する、FileCacheの主な設定項目とデフォルト値は以下のとおりです。
設定項目 | 概要 | デフォルト |
---|---|---|
engine | ‘File’ | |
path | キャッシュファイルを保存するパスを指定します。 | CACHE |
lock | flock()でファイルへの書き込みをロックします。 | true |
serialize | シリアライズされたデータをキャッシュします。 | true |
mask | 生成したキャッシュファイルのパーミッション | 0664 |
ApcCache
PHPのAPC(Alternative PHP Cache)拡張を利用したキャッシュです。CakePHP2.0から2.2までは、APC拡張が利用可能であればこちらがデフォルトのキャッシュとして利用されていました。
APCはもともとPHPの中間コードをキャッシュするPHPアクセラレータです。
PHPはプログラムが呼ばれる度に中間コードにコンパイルされてから実行されますが、その中間コードをキャッシュしておくことで高速化をはかります(オペコードキャッシュ)。
CakePHPのApcEngineではAPCのオペコードキャッシュ機能ではなく、ユーザーキャッシュ機能を使用するためのapc_store()
とapc_fetch()
というAPC関数を利用して変数をキャッシュするしくみを提供しているようです。
しかしこのAPC拡張、実はPHP5.5以降では使用することができません。
APCはオペコードキャッシュ機能、ユーザーキャッシュ機能を提供するPHPアクセラレータとして使われていましたが、PHP5.5への対応版が出ないままメンテナンスが止まってしまい、使われなくなりました。
現在ではAPCのユーザーキャッシュ機能のみを提供するAPCuと、オペコードキャッシュ機能を提供するZend OPcacheで同様の機能を使用することができます。
(参考:https://www.devside.net/wamp-server/installing-apc-for-php-5-5)
ということで、PHP5.5以降の方々はあきらめて次の項に進みましょう。
APCが利用できる方はひとまずインストールです。
yumから簡単にインストールできます。
yum install php-pecl-apc
インストールが完了したらApacheを再起動するとapcが使えるようになります。
また、/etc/php.d/apc.ini
あたりでメモリ容量などの設定ができます。APCの実行時設定を確認してみてください。
あとはCacheクラスで設定をしてしまえば、他のキャッシュエンジンと同様に使うことができます。簡単ですね。
設定項目は以下のとおりです。
設定項目 | 概要 | デフォルト |
---|---|---|
engine | ‘Apc’ |
余談ですが、前述のとおりAPC拡張はオペコードキャッシュ機能も持っているので、APC拡張を導入すればCacheクラスを利用せずとも多少PHPが高速化するようです。これは儲けものですね。
WinCache
こちらはPHPのWinCache拡張を利用したキャッシュです。
WinCacheはAPC同様、PHPの中間コードをキャッシュすることで高速化を図るしくみで、WindowsおよびWindowsサーバ上でのPHPアプリケーションの動作速度を向上させます。
Windows向けのキャッシュエンジンのようなので、ここでは割愛します。
XcacheEngine
PHPのXcacheを利用したキャッシュエンジンです。
XcacheはAPCと同じくPHPの中間コードをキャッシュしてPHP全体を高速化するPHPアクセラレータです。
PHP5.5以上をremiリポジトリで入れていた場合は、remi-php55リポジトリとかにあるようなのでyumでインストールできます。
yum --enablerepo=remi,remi-php55 install php-xcache xcache-admin
これで導入完了です。
それ以外の場合でもXCache公式からtar.gz形式でダウンロードし、手動でインストールすることも可能です。
wget https://xcache.lighttpd.net/pub/Releases/3.1.0/xcache-3.1.0.tar.gz tar xvfz xcache-3.1.0.tar.gz cd xcache-3.1.0 phpize ./configure --enable-xcache make make install
php -v
でPHPのバージョンを確認すると、一緒に
Zend Engine v2.5.0, Copyright (c) 1998-2015 Zend Technologies with XCache v3.1.1, Copyright (c) 2005-2014, by mOo with Xdebug v2.3.3, Copyright (c) 2002-2015, by Derick Rethans with XCache Optimizer v3.1.1, Copyright (c) 2005-2014, by mOo
こんなのが表示されているはずです。最後にApacheの再起動を忘れずに!
主な設定項目は以下のようになっています。
設定項目 | 概要 | デフォルト |
---|---|---|
engine | ‘Xcache’ | |
PHP_AUTH_USER | xcache.admin.userで設定したユーザー名 | ‘user’ |
PHP_AUTH_PW | xcache.admin.passで設定したパスワード | ‘password’ |
MemcacheEngine / MemcachedEngine
PHPのMemcache及びMemcached拡張を利用したキャッシュエンジンです。名前はほぼ同じなのですが、これらは別物なので注意しましょう。
MemcachedEngineはv2.5から追加され、それに伴ってMemcacheEngineが非推奨になっているので、使うのであればMemcachedEngineの方を使用してください。ここでもMemcachedEngineについてのみ解説します。
Memcachedは分散型メモリオブジェクトキャッシュシステムと呼ばれており、PHPでもMemcachedクラスとして実装されています。APCなどのキャッシュシステムと違って、memcachedサーバを別に立て、そのサーバのメモリにキャッシュして負荷を減らすということもできます。
それでは実際にMemcachedを導入してみましょう。複雑なので、
- memcachedの導入
- libmemcachedの導入
- php-pecl-memcachedの導入
の3ステップに分けて説明します。
memcachedの導入
まずは大元、memcachedの導入です。
memcachedはyumからインストールできます。
また、memcachedはlibeventというパッケージを使用するので、こちらもあらかじめyumでインストールしておきましょう。
yum install libevent libevent-devel memcached
インストールが終わったらmemcachedを起動してみましょう。
ちなみに、root権限で実行しようとすると以下の様なエラーが出ます。
can't run as root without the -u switch
言われたとおり、あらかじめ適当なユーザーにしておくか、-uオプションでユーザー名を指定して実行してください。
memcached -d -m 64 -p 11211
なにも問題がなければこれでmemcachedが起動されます。
ちなみに、memcachedの起動オプションは
-p
: memcachedが利用するTCPのポート。デフォルトは11211-d
: デーモンとしてバックグラウンドで起動。-m
: 最大のメモリサイズ。デフォルトは64MB
みたいな感じです。起動オプションについてはこちらが詳しいので目を通してみてください。
libmemcachedの導入
memcachedを導入しただけでは、PHPからmemcachedを使用することはできません。
そのために、libmemcachedとphp-pecl-memcachedをインストールしましょう。
まずlibmemcachedですが、これはmemcachedのクライアントライブラリです。
libmemcacheというライブラリもあるので間違えないようにしてください。
wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz tar xvf libmemcached-1.0.18.tar.gz cd libmemcached-1.0.18 ./configure make make install
libmemcached公式(英語)にあるのでよさげなものを選んできてください。基本的には最新のもので良いかと思います。
また、configureが途中で失敗する場合は、Cコンパイラがインストールされていない可能性があります。あらかじめ
yum install gcc gcc-c++
などしてコンパイラをインストールしておくようにしてください。
php-pecl-memcachedの導入
最後にphp-pecl-memcachedの導入です。
php-pecl-memcachedはPHPでMemcachedクラスを利用できるようにするためのPECL拡張です。CakePHPのMemcachedEngineでは、内部的にこのMemcachedクラスを使用しています。
yum --enablerepo=remi,remi-php55 install php-pecl-memcached
PHPをremiリポジトリ経由でyumインストールした場合はこれでインストールができます。
/etc/php.d/の中に設定ファイルz-memcached.iniが作成されているのを確認してください。
設定項目 | 概要 | デフォルト |
---|---|---|
engine | ‘Memcached’ | |
servers | memcachedサーバのアドレス、もしくはその配列 | 127.0.0.1 |
compress | キャッシュの中身を圧縮するかどうか | false |
persistent | 持続的接続にしたい場合はtrueを指定する | false |
login | null | |
password | null | |
serialize | シリアライズエンジンを指定する。php/json/igbinary | php |
options | memcachedクライアントのその他オプション | array() |
設定項目はこんな感じです。’servers’でサーバを複数設定できるのがポイントですね。
ちなみに、memcachedはデフォルトでは1MB以上の大きさのキャッシュを保存することができません。ですが、memcachedの起動時に-l
オプションをつけて起動すると最大キャッシュサイズを変更することができます。なぜかキャッシュができていないことがあったら確認してみてください。
RedisEngine
Redisとは、メモリ上にキーとデータを保存するデータベースです。保存したい値と対応した任意のキーをペアで保存する、Key-Valueストア(KVS)を構築します。
Redisには、
- 保存する値に文字列以外のデータ型を使用できる
- メモリ上で動作するのと同時に、データをディスクに書き込んで永続化させる
- 他のコンピュータに複製を作る「レプリケーション」という負荷分散の方法
など、Memcachedよりも豊富な機能が提供されています。
Redisについてより詳しいところは、redisドキュメント日本語訳などを参考にしてみてください。
RedisもまたMemcachedと同様に、PECL拡張を利用してPHPから使用できるようにしなければなりません。
redisはyumコマンドからインストールすることができますが、デフォルトのリポジトリにはないので、epelリポジトリからインストールしましょう。
yum --enablerepo=epel install redis
インストールができたらredis-serverコマンドでRedisを起動することができます。
redis-server /etc/redis.conf
ここで注意です。
上記コマンドは、設定ファイル/etc/redis.conf
の設定でRedisを起動するコマンドなのですが、
/etc/redis.conf
のデフォルトの設定ではローカルホストからしか接続できないようになっています(bind 127.0.0.1
のところ)。
別サーバからRedisを使用したい場合はコメントアウトするなどして対応しましょう。
CakePHPのRedisEngineでは、PHPからRedisを扱うためのphpredis拡張を使用しています。こちらもepelリポジトリにあるはずなので、あわせてインストールしましょう。
yum --enablerepo=epel install php-pecl-redis
インストールまで終わったら/etc/php.d/の中にredis.iniという設定ファイルが作成されているのが確認できるかと思います。
ちなみに主な設定項目はこんな感じ。
設定項目 | 概要 | デフォルト |
---|---|---|
engine | ‘Redis’ | |
server | サーバーを指定します。 | 127.0.0.1 |
database | 使用するデータベースの番号 | 0 |
port | 使用するポート番号 | 6379 |
password | false | |
timeout | タイムアウトの秒数。0は無制限 | 0 |
persistent | 持続的接続にしたい場合はtrueを指定する | true |
unix_socket | UNIXソケットファイルのパス | false |
まとめ
それではまとめです。
ひとくちにキャッシュと言っても奥が深く、CakePHPからも多くのキャッシュエンジンを利用できます。
キャッシュエンジンの選び方はアプリケーションの規模などにより最適なものは異なり、サービスの規模が大きくなれば求められるキャッシュも変わってきます。
そんなときに、CakePHPのCacheクラスを利用しておけば簡単にキャッシュエンジンを付け替えることができるのです。
今までキャッシュを使ったことがないという人も、これを機にキャッシュデビューしてみてはいかがでしょうか。
以上、リスペクトの山内からでした。